diff options
author | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2011-12-12 11:19:20 -0500 |
---|---|---|
committer | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2011-12-12 11:19:20 -0500 |
commit | 68556ca1e03d6a35be3b315eba58df2f8176e3a0 (patch) | |
tree | 36a390d29a0d03a59a90c0f223b0d98a80f0f6c3 /drivers/gpu/drm | |
parent | 0604ca48f1689ad06144b81f5c08f297b6edd831 (diff) | |
parent | 8ab30691826fc05efa47c4ffba19b80496bb3a2c (diff) |
Merge branch 'mfd/wm8994' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/misc into for-3.3
Diffstat (limited to 'drivers/gpu/drm')
52 files changed, 1021 insertions, 666 deletions
diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig index 785127cb281b..1368826ef284 100644 --- a/drivers/gpu/drm/Kconfig +++ b/drivers/gpu/drm/Kconfig | |||
@@ -9,7 +9,6 @@ menuconfig DRM | |||
9 | depends on (AGP || AGP=n) && !EMULATED_CMPXCHG && MMU | 9 | depends on (AGP || AGP=n) && !EMULATED_CMPXCHG && MMU |
10 | select I2C | 10 | select I2C |
11 | select I2C_ALGOBIT | 11 | select I2C_ALGOBIT |
12 | select SLOW_WORK | ||
13 | help | 12 | help |
14 | Kernel-level support for the Direct Rendering Infrastructure (DRI) | 13 | Kernel-level support for the Direct Rendering Infrastructure (DRI) |
15 | introduced in XFree86 4.0. If you say Y here, you need to select | 14 | introduced in XFree86 4.0. If you say Y here, you need to select |
@@ -96,6 +95,7 @@ config DRM_I915 | |||
96 | select FB_CFB_IMAGEBLIT | 95 | select FB_CFB_IMAGEBLIT |
97 | # i915 depends on ACPI_VIDEO when ACPI is enabled | 96 | # i915 depends on ACPI_VIDEO when ACPI is enabled |
98 | # but for select to work, need to select ACPI_VIDEO's dependencies, ick | 97 | # but for select to work, need to select ACPI_VIDEO's dependencies, ick |
98 | select BACKLIGHT_LCD_SUPPORT if ACPI | ||
99 | select BACKLIGHT_CLASS_DEVICE if ACPI | 99 | select BACKLIGHT_CLASS_DEVICE if ACPI |
100 | select VIDEO_OUTPUT_CONTROL if ACPI | 100 | select VIDEO_OUTPUT_CONTROL if ACPI |
101 | select INPUT if ACPI | 101 | select INPUT if ACPI |
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index 9a2e2a14b3bb..8323fc389840 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c | |||
@@ -1873,6 +1873,10 @@ int drm_mode_dirtyfb_ioctl(struct drm_device *dev, | |||
1873 | } | 1873 | } |
1874 | 1874 | ||
1875 | if (num_clips && clips_ptr) { | 1875 | if (num_clips && clips_ptr) { |
1876 | if (num_clips < 0 || num_clips > DRM_MODE_FB_DIRTY_MAX_CLIPS) { | ||
1877 | ret = -EINVAL; | ||
1878 | goto out_err1; | ||
1879 | } | ||
1876 | clips = kzalloc(num_clips * sizeof(*clips), GFP_KERNEL); | 1880 | clips = kzalloc(num_clips * sizeof(*clips), GFP_KERNEL); |
1877 | if (!clips) { | 1881 | if (!clips) { |
1878 | ret = -ENOMEM; | 1882 | ret = -ENOMEM; |
@@ -2118,8 +2122,10 @@ struct drm_property *drm_property_create(struct drm_device *dev, int flags, | |||
2118 | property->num_values = num_values; | 2122 | property->num_values = num_values; |
2119 | INIT_LIST_HEAD(&property->enum_blob_list); | 2123 | INIT_LIST_HEAD(&property->enum_blob_list); |
2120 | 2124 | ||
2121 | if (name) | 2125 | if (name) { |
2122 | strncpy(property->name, name, DRM_PROP_NAME_LEN); | 2126 | strncpy(property->name, name, DRM_PROP_NAME_LEN); |
2127 | property->name[DRM_PROP_NAME_LEN-1] = '\0'; | ||
2128 | } | ||
2123 | 2129 | ||
2124 | list_add_tail(&property->head, &dev->mode_config.property_list); | 2130 | list_add_tail(&property->head, &dev->mode_config.property_list); |
2125 | return property; | 2131 | return property; |
diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c index 2957636161e8..3969f7553fe7 100644 --- a/drivers/gpu/drm/drm_crtc_helper.c +++ b/drivers/gpu/drm/drm_crtc_helper.c | |||
@@ -484,6 +484,7 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set) | |||
484 | struct drm_connector *save_connectors, *connector; | 484 | struct drm_connector *save_connectors, *connector; |
485 | int count = 0, ro, fail = 0; | 485 | int count = 0, ro, fail = 0; |
486 | struct drm_crtc_helper_funcs *crtc_funcs; | 486 | struct drm_crtc_helper_funcs *crtc_funcs; |
487 | struct drm_mode_set save_set; | ||
487 | int ret = 0; | 488 | int ret = 0; |
488 | int i; | 489 | int i; |
489 | 490 | ||
@@ -556,6 +557,12 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set) | |||
556 | save_connectors[count++] = *connector; | 557 | save_connectors[count++] = *connector; |
557 | } | 558 | } |
558 | 559 | ||
560 | save_set.crtc = set->crtc; | ||
561 | save_set.mode = &set->crtc->mode; | ||
562 | save_set.x = set->crtc->x; | ||
563 | save_set.y = set->crtc->y; | ||
564 | save_set.fb = set->crtc->fb; | ||
565 | |||
559 | /* We should be able to check here if the fb has the same properties | 566 | /* We should be able to check here if the fb has the same properties |
560 | * and then just flip_or_move it */ | 567 | * and then just flip_or_move it */ |
561 | if (set->crtc->fb != set->fb) { | 568 | if (set->crtc->fb != set->fb) { |
@@ -721,6 +728,12 @@ fail: | |||
721 | *connector = save_connectors[count++]; | 728 | *connector = save_connectors[count++]; |
722 | } | 729 | } |
723 | 730 | ||
731 | /* Try to restore the config */ | ||
732 | if (mode_changed && | ||
733 | !drm_crtc_helper_set_mode(save_set.crtc, save_set.mode, save_set.x, | ||
734 | save_set.y, save_set.fb)) | ||
735 | DRM_ERROR("failed to restore config after modeset failure\n"); | ||
736 | |||
724 | kfree(save_connectors); | 737 | kfree(save_connectors); |
725 | kfree(save_encoders); | 738 | kfree(save_encoders); |
726 | kfree(save_crtcs); | 739 | kfree(save_crtcs); |
diff --git a/drivers/gpu/drm/drm_debugfs.c b/drivers/gpu/drm/drm_debugfs.c index d067c12ba940..1c7a1c0d3edd 100644 --- a/drivers/gpu/drm/drm_debugfs.c +++ b/drivers/gpu/drm/drm_debugfs.c | |||
@@ -118,7 +118,10 @@ int drm_debugfs_create_files(struct drm_info_list *files, int count, | |||
118 | tmp->minor = minor; | 118 | tmp->minor = minor; |
119 | tmp->dent = ent; | 119 | tmp->dent = ent; |
120 | tmp->info_ent = &files[i]; | 120 | tmp->info_ent = &files[i]; |
121 | list_add(&(tmp->list), &(minor->debugfs_nodes.list)); | 121 | |
122 | mutex_lock(&minor->debugfs_lock); | ||
123 | list_add(&tmp->list, &minor->debugfs_list); | ||
124 | mutex_unlock(&minor->debugfs_lock); | ||
122 | } | 125 | } |
123 | return 0; | 126 | return 0; |
124 | 127 | ||
@@ -146,7 +149,8 @@ int drm_debugfs_init(struct drm_minor *minor, int minor_id, | |||
146 | char name[64]; | 149 | char name[64]; |
147 | int ret; | 150 | int ret; |
148 | 151 | ||
149 | INIT_LIST_HEAD(&minor->debugfs_nodes.list); | 152 | INIT_LIST_HEAD(&minor->debugfs_list); |
153 | mutex_init(&minor->debugfs_lock); | ||
150 | sprintf(name, "%d", minor_id); | 154 | sprintf(name, "%d", minor_id); |
151 | minor->debugfs_root = debugfs_create_dir(name, root); | 155 | minor->debugfs_root = debugfs_create_dir(name, root); |
152 | if (!minor->debugfs_root) { | 156 | if (!minor->debugfs_root) { |
@@ -192,8 +196,9 @@ int drm_debugfs_remove_files(struct drm_info_list *files, int count, | |||
192 | struct drm_info_node *tmp; | 196 | struct drm_info_node *tmp; |
193 | int i; | 197 | int i; |
194 | 198 | ||
199 | mutex_lock(&minor->debugfs_lock); | ||
195 | for (i = 0; i < count; i++) { | 200 | for (i = 0; i < count; i++) { |
196 | list_for_each_safe(pos, q, &minor->debugfs_nodes.list) { | 201 | list_for_each_safe(pos, q, &minor->debugfs_list) { |
197 | tmp = list_entry(pos, struct drm_info_node, list); | 202 | tmp = list_entry(pos, struct drm_info_node, list); |
198 | if (tmp->info_ent == &files[i]) { | 203 | if (tmp->info_ent == &files[i]) { |
199 | debugfs_remove(tmp->dent); | 204 | debugfs_remove(tmp->dent); |
@@ -202,6 +207,7 @@ int drm_debugfs_remove_files(struct drm_info_list *files, int count, | |||
202 | } | 207 | } |
203 | } | 208 | } |
204 | } | 209 | } |
210 | mutex_unlock(&minor->debugfs_lock); | ||
205 | return 0; | 211 | return 0; |
206 | } | 212 | } |
207 | EXPORT_SYMBOL(drm_debugfs_remove_files); | 213 | EXPORT_SYMBOL(drm_debugfs_remove_files); |
diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c index fc81af9dbf42..40c187c60f44 100644 --- a/drivers/gpu/drm/drm_drv.c +++ b/drivers/gpu/drm/drm_drv.c | |||
@@ -125,7 +125,7 @@ static struct drm_ioctl_desc drm_ioctls[] = { | |||
125 | DRM_IOCTL_DEF(DRM_IOCTL_SG_ALLOC, drm_sg_alloc_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | 125 | DRM_IOCTL_DEF(DRM_IOCTL_SG_ALLOC, drm_sg_alloc_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), |
126 | DRM_IOCTL_DEF(DRM_IOCTL_SG_FREE, drm_sg_free, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | 126 | DRM_IOCTL_DEF(DRM_IOCTL_SG_FREE, drm_sg_free, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), |
127 | 127 | ||
128 | DRM_IOCTL_DEF(DRM_IOCTL_WAIT_VBLANK, drm_wait_vblank, 0), | 128 | DRM_IOCTL_DEF(DRM_IOCTL_WAIT_VBLANK, drm_wait_vblank, DRM_UNLOCKED), |
129 | 129 | ||
130 | DRM_IOCTL_DEF(DRM_IOCTL_MODESET_CTL, drm_modeset_ctl, 0), | 130 | DRM_IOCTL_DEF(DRM_IOCTL_MODESET_CTL, drm_modeset_ctl, 0), |
131 | 131 | ||
diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c index cb3794a00f98..44a5d0ad8b7c 100644 --- a/drivers/gpu/drm/drm_irq.c +++ b/drivers/gpu/drm/drm_irq.c | |||
@@ -110,10 +110,7 @@ static void vblank_disable_and_save(struct drm_device *dev, int crtc) | |||
110 | /* Prevent vblank irq processing while disabling vblank irqs, | 110 | /* Prevent vblank irq processing while disabling vblank irqs, |
111 | * so no updates of timestamps or count can happen after we've | 111 | * so no updates of timestamps or count can happen after we've |
112 | * disabled. Needed to prevent races in case of delayed irq's. | 112 | * disabled. Needed to prevent races in case of delayed irq's. |
113 | * Disable preemption, so vblank_time_lock is held as short as | ||
114 | * possible, even under a kernel with PREEMPT_RT patches. | ||
115 | */ | 113 | */ |
116 | preempt_disable(); | ||
117 | spin_lock_irqsave(&dev->vblank_time_lock, irqflags); | 114 | spin_lock_irqsave(&dev->vblank_time_lock, irqflags); |
118 | 115 | ||
119 | dev->driver->disable_vblank(dev, crtc); | 116 | dev->driver->disable_vblank(dev, crtc); |
@@ -164,7 +161,6 @@ static void vblank_disable_and_save(struct drm_device *dev, int crtc) | |||
164 | clear_vblank_timestamps(dev, crtc); | 161 | clear_vblank_timestamps(dev, crtc); |
165 | 162 | ||
166 | spin_unlock_irqrestore(&dev->vblank_time_lock, irqflags); | 163 | spin_unlock_irqrestore(&dev->vblank_time_lock, irqflags); |
167 | preempt_enable(); | ||
168 | } | 164 | } |
169 | 165 | ||
170 | static void vblank_disable_fn(unsigned long arg) | 166 | static void vblank_disable_fn(unsigned long arg) |
@@ -407,13 +403,16 @@ int drm_irq_uninstall(struct drm_device *dev) | |||
407 | /* | 403 | /* |
408 | * Wake up any waiters so they don't hang. | 404 | * Wake up any waiters so they don't hang. |
409 | */ | 405 | */ |
410 | spin_lock_irqsave(&dev->vbl_lock, irqflags); | 406 | if (dev->num_crtcs) { |
411 | for (i = 0; i < dev->num_crtcs; i++) { | 407 | spin_lock_irqsave(&dev->vbl_lock, irqflags); |
412 | DRM_WAKEUP(&dev->vbl_queue[i]); | 408 | for (i = 0; i < dev->num_crtcs; i++) { |
413 | dev->vblank_enabled[i] = 0; | 409 | DRM_WAKEUP(&dev->vbl_queue[i]); |
414 | dev->last_vblank[i] = dev->driver->get_vblank_counter(dev, i); | 410 | dev->vblank_enabled[i] = 0; |
411 | dev->last_vblank[i] = | ||
412 | dev->driver->get_vblank_counter(dev, i); | ||
413 | } | ||
414 | spin_unlock_irqrestore(&dev->vbl_lock, irqflags); | ||
415 | } | 415 | } |
416 | spin_unlock_irqrestore(&dev->vbl_lock, irqflags); | ||
417 | 416 | ||
418 | if (!irq_enabled) | 417 | if (!irq_enabled) |
419 | return -EINVAL; | 418 | return -EINVAL; |
@@ -886,10 +885,6 @@ int drm_vblank_get(struct drm_device *dev, int crtc) | |||
886 | spin_lock_irqsave(&dev->vbl_lock, irqflags); | 885 | spin_lock_irqsave(&dev->vbl_lock, irqflags); |
887 | /* Going from 0->1 means we have to enable interrupts again */ | 886 | /* Going from 0->1 means we have to enable interrupts again */ |
888 | if (atomic_add_return(1, &dev->vblank_refcount[crtc]) == 1) { | 887 | if (atomic_add_return(1, &dev->vblank_refcount[crtc]) == 1) { |
889 | /* Disable preemption while holding vblank_time_lock. Do | ||
890 | * it explicitely to guard against PREEMPT_RT kernel. | ||
891 | */ | ||
892 | preempt_disable(); | ||
893 | spin_lock_irqsave(&dev->vblank_time_lock, irqflags2); | 888 | spin_lock_irqsave(&dev->vblank_time_lock, irqflags2); |
894 | if (!dev->vblank_enabled[crtc]) { | 889 | if (!dev->vblank_enabled[crtc]) { |
895 | /* Enable vblank irqs under vblank_time_lock protection. | 890 | /* Enable vblank irqs under vblank_time_lock protection. |
@@ -909,7 +904,6 @@ int drm_vblank_get(struct drm_device *dev, int crtc) | |||
909 | } | 904 | } |
910 | } | 905 | } |
911 | spin_unlock_irqrestore(&dev->vblank_time_lock, irqflags2); | 906 | spin_unlock_irqrestore(&dev->vblank_time_lock, irqflags2); |
912 | preempt_enable(); | ||
913 | } else { | 907 | } else { |
914 | if (!dev->vblank_enabled[crtc]) { | 908 | if (!dev->vblank_enabled[crtc]) { |
915 | atomic_dec(&dev->vblank_refcount[crtc]); | 909 | atomic_dec(&dev->vblank_refcount[crtc]); |
@@ -1125,6 +1119,7 @@ static int drm_queue_vblank_event(struct drm_device *dev, int pipe, | |||
1125 | trace_drm_vblank_event_delivered(current->pid, pipe, | 1119 | trace_drm_vblank_event_delivered(current->pid, pipe, |
1126 | vblwait->request.sequence); | 1120 | vblwait->request.sequence); |
1127 | } else { | 1121 | } else { |
1122 | /* drm_handle_vblank_events will call drm_vblank_put */ | ||
1128 | list_add_tail(&e->base.link, &dev->vblank_event_list); | 1123 | list_add_tail(&e->base.link, &dev->vblank_event_list); |
1129 | vblwait->reply.sequence = vblwait->request.sequence; | 1124 | vblwait->reply.sequence = vblwait->request.sequence; |
1130 | } | 1125 | } |
@@ -1205,8 +1200,12 @@ int drm_wait_vblank(struct drm_device *dev, void *data, | |||
1205 | goto done; | 1200 | goto done; |
1206 | } | 1201 | } |
1207 | 1202 | ||
1208 | if (flags & _DRM_VBLANK_EVENT) | 1203 | if (flags & _DRM_VBLANK_EVENT) { |
1204 | /* must hold on to the vblank ref until the event fires | ||
1205 | * drm_vblank_put will be called asynchronously | ||
1206 | */ | ||
1209 | return drm_queue_vblank_event(dev, crtc, vblwait, file_priv); | 1207 | return drm_queue_vblank_event(dev, crtc, vblwait, file_priv); |
1208 | } | ||
1210 | 1209 | ||
1211 | if ((flags & _DRM_VBLANK_NEXTONMISS) && | 1210 | if ((flags & _DRM_VBLANK_NEXTONMISS) && |
1212 | (seq - vblwait->request.sequence) <= (1<<23)) { | 1211 | (seq - vblwait->request.sequence) <= (1<<23)) { |
diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index d14b44e13f51..d09a6e02dc95 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c | |||
@@ -636,11 +636,16 @@ static int i915_ringbuffer_info(struct seq_file *m, void *data) | |||
636 | struct drm_device *dev = node->minor->dev; | 636 | struct drm_device *dev = node->minor->dev; |
637 | drm_i915_private_t *dev_priv = dev->dev_private; | 637 | drm_i915_private_t *dev_priv = dev->dev_private; |
638 | struct intel_ring_buffer *ring; | 638 | struct intel_ring_buffer *ring; |
639 | int ret; | ||
639 | 640 | ||
640 | ring = &dev_priv->ring[(uintptr_t)node->info_ent->data]; | 641 | ring = &dev_priv->ring[(uintptr_t)node->info_ent->data]; |
641 | if (ring->size == 0) | 642 | if (ring->size == 0) |
642 | return 0; | 643 | return 0; |
643 | 644 | ||
645 | ret = mutex_lock_interruptible(&dev->struct_mutex); | ||
646 | if (ret) | ||
647 | return ret; | ||
648 | |||
644 | seq_printf(m, "Ring %s:\n", ring->name); | 649 | seq_printf(m, "Ring %s:\n", ring->name); |
645 | seq_printf(m, " Head : %08x\n", I915_READ_HEAD(ring) & HEAD_ADDR); | 650 | seq_printf(m, " Head : %08x\n", I915_READ_HEAD(ring) & HEAD_ADDR); |
646 | seq_printf(m, " Tail : %08x\n", I915_READ_TAIL(ring) & TAIL_ADDR); | 651 | seq_printf(m, " Tail : %08x\n", I915_READ_TAIL(ring) & TAIL_ADDR); |
@@ -654,6 +659,8 @@ static int i915_ringbuffer_info(struct seq_file *m, void *data) | |||
654 | seq_printf(m, " Control : %08x\n", I915_READ_CTL(ring)); | 659 | seq_printf(m, " Control : %08x\n", I915_READ_CTL(ring)); |
655 | seq_printf(m, " Start : %08x\n", I915_READ_START(ring)); | 660 | seq_printf(m, " Start : %08x\n", I915_READ_START(ring)); |
656 | 661 | ||
662 | mutex_unlock(&dev->struct_mutex); | ||
663 | |||
657 | return 0; | 664 | return 0; |
658 | } | 665 | } |
659 | 666 | ||
@@ -842,7 +849,16 @@ static int i915_rstdby_delays(struct seq_file *m, void *unused) | |||
842 | struct drm_info_node *node = (struct drm_info_node *) m->private; | 849 | struct drm_info_node *node = (struct drm_info_node *) m->private; |
843 | struct drm_device *dev = node->minor->dev; | 850 | struct drm_device *dev = node->minor->dev; |
844 | drm_i915_private_t *dev_priv = dev->dev_private; | 851 | drm_i915_private_t *dev_priv = dev->dev_private; |
845 | u16 crstanddelay = I915_READ16(CRSTANDVID); | 852 | u16 crstanddelay; |
853 | int ret; | ||
854 | |||
855 | ret = mutex_lock_interruptible(&dev->struct_mutex); | ||
856 | if (ret) | ||
857 | return ret; | ||
858 | |||
859 | crstanddelay = I915_READ16(CRSTANDVID); | ||
860 | |||
861 | mutex_unlock(&dev->struct_mutex); | ||
846 | 862 | ||
847 | seq_printf(m, "w/ctx: %d, w/o ctx: %d\n", (crstanddelay >> 8) & 0x3f, (crstanddelay & 0x3f)); | 863 | seq_printf(m, "w/ctx: %d, w/o ctx: %d\n", (crstanddelay >> 8) & 0x3f, (crstanddelay & 0x3f)); |
848 | 864 | ||
@@ -940,7 +956,11 @@ static int i915_delayfreq_table(struct seq_file *m, void *unused) | |||
940 | struct drm_device *dev = node->minor->dev; | 956 | struct drm_device *dev = node->minor->dev; |
941 | drm_i915_private_t *dev_priv = dev->dev_private; | 957 | drm_i915_private_t *dev_priv = dev->dev_private; |
942 | u32 delayfreq; | 958 | u32 delayfreq; |
943 | int i; | 959 | int ret, i; |
960 | |||
961 | ret = mutex_lock_interruptible(&dev->struct_mutex); | ||
962 | if (ret) | ||
963 | return ret; | ||
944 | 964 | ||
945 | for (i = 0; i < 16; i++) { | 965 | for (i = 0; i < 16; i++) { |
946 | delayfreq = I915_READ(PXVFREQ_BASE + i * 4); | 966 | delayfreq = I915_READ(PXVFREQ_BASE + i * 4); |
@@ -948,6 +968,8 @@ static int i915_delayfreq_table(struct seq_file *m, void *unused) | |||
948 | (delayfreq & PXVFREQ_PX_MASK) >> PXVFREQ_PX_SHIFT); | 968 | (delayfreq & PXVFREQ_PX_MASK) >> PXVFREQ_PX_SHIFT); |
949 | } | 969 | } |
950 | 970 | ||
971 | mutex_unlock(&dev->struct_mutex); | ||
972 | |||
951 | return 0; | 973 | return 0; |
952 | } | 974 | } |
953 | 975 | ||
@@ -962,13 +984,19 @@ static int i915_inttoext_table(struct seq_file *m, void *unused) | |||
962 | struct drm_device *dev = node->minor->dev; | 984 | struct drm_device *dev = node->minor->dev; |
963 | drm_i915_private_t *dev_priv = dev->dev_private; | 985 | drm_i915_private_t *dev_priv = dev->dev_private; |
964 | u32 inttoext; | 986 | u32 inttoext; |
965 | int i; | 987 | int ret, i; |
988 | |||
989 | ret = mutex_lock_interruptible(&dev->struct_mutex); | ||
990 | if (ret) | ||
991 | return ret; | ||
966 | 992 | ||
967 | for (i = 1; i <= 32; i++) { | 993 | for (i = 1; i <= 32; i++) { |
968 | inttoext = I915_READ(INTTOEXT_BASE_ILK + i * 4); | 994 | inttoext = I915_READ(INTTOEXT_BASE_ILK + i * 4); |
969 | seq_printf(m, "INTTOEXT%02d: 0x%08x\n", i, inttoext); | 995 | seq_printf(m, "INTTOEXT%02d: 0x%08x\n", i, inttoext); |
970 | } | 996 | } |
971 | 997 | ||
998 | mutex_unlock(&dev->struct_mutex); | ||
999 | |||
972 | return 0; | 1000 | return 0; |
973 | } | 1001 | } |
974 | 1002 | ||
@@ -977,9 +1005,19 @@ static int i915_drpc_info(struct seq_file *m, void *unused) | |||
977 | struct drm_info_node *node = (struct drm_info_node *) m->private; | 1005 | struct drm_info_node *node = (struct drm_info_node *) m->private; |
978 | struct drm_device *dev = node->minor->dev; | 1006 | struct drm_device *dev = node->minor->dev; |
979 | drm_i915_private_t *dev_priv = dev->dev_private; | 1007 | drm_i915_private_t *dev_priv = dev->dev_private; |
980 | u32 rgvmodectl = I915_READ(MEMMODECTL); | 1008 | u32 rgvmodectl, rstdbyctl; |
981 | u32 rstdbyctl = I915_READ(RSTDBYCTL); | 1009 | u16 crstandvid; |
982 | u16 crstandvid = I915_READ16(CRSTANDVID); | 1010 | int ret; |
1011 | |||
1012 | ret = mutex_lock_interruptible(&dev->struct_mutex); | ||
1013 | if (ret) | ||
1014 | return ret; | ||
1015 | |||
1016 | rgvmodectl = I915_READ(MEMMODECTL); | ||
1017 | rstdbyctl = I915_READ(RSTDBYCTL); | ||
1018 | crstandvid = I915_READ16(CRSTANDVID); | ||
1019 | |||
1020 | mutex_unlock(&dev->struct_mutex); | ||
983 | 1021 | ||
984 | seq_printf(m, "HD boost: %s\n", (rgvmodectl & MEMMODE_BOOST_EN) ? | 1022 | seq_printf(m, "HD boost: %s\n", (rgvmodectl & MEMMODE_BOOST_EN) ? |
985 | "yes" : "no"); | 1023 | "yes" : "no"); |
@@ -1167,9 +1205,16 @@ static int i915_gfxec(struct seq_file *m, void *unused) | |||
1167 | struct drm_info_node *node = (struct drm_info_node *) m->private; | 1205 | struct drm_info_node *node = (struct drm_info_node *) m->private; |
1168 | struct drm_device *dev = node->minor->dev; | 1206 | struct drm_device *dev = node->minor->dev; |
1169 | drm_i915_private_t *dev_priv = dev->dev_private; | 1207 | drm_i915_private_t *dev_priv = dev->dev_private; |
1208 | int ret; | ||
1209 | |||
1210 | ret = mutex_lock_interruptible(&dev->struct_mutex); | ||
1211 | if (ret) | ||
1212 | return ret; | ||
1170 | 1213 | ||
1171 | seq_printf(m, "GFXEC: %ld\n", (unsigned long)I915_READ(0x112f4)); | 1214 | seq_printf(m, "GFXEC: %ld\n", (unsigned long)I915_READ(0x112f4)); |
1172 | 1215 | ||
1216 | mutex_unlock(&dev->struct_mutex); | ||
1217 | |||
1173 | return 0; | 1218 | return 0; |
1174 | } | 1219 | } |
1175 | 1220 | ||
@@ -1506,7 +1551,10 @@ drm_add_fake_info_node(struct drm_minor *minor, | |||
1506 | node->minor = minor; | 1551 | node->minor = minor; |
1507 | node->dent = ent; | 1552 | node->dent = ent; |
1508 | node->info_ent = (void *) key; | 1553 | node->info_ent = (void *) key; |
1509 | list_add(&node->list, &minor->debugfs_nodes.list); | 1554 | |
1555 | mutex_lock(&minor->debugfs_lock); | ||
1556 | list_add(&node->list, &minor->debugfs_list); | ||
1557 | mutex_unlock(&minor->debugfs_lock); | ||
1510 | 1558 | ||
1511 | return 0; | 1559 | return 0; |
1512 | } | 1560 | } |
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index cc531bb59c26..15bfa9145d2b 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c | |||
@@ -68,7 +68,7 @@ module_param_named(i915_enable_rc6, i915_enable_rc6, int, 0600); | |||
68 | MODULE_PARM_DESC(i915_enable_rc6, | 68 | MODULE_PARM_DESC(i915_enable_rc6, |
69 | "Enable power-saving render C-state 6 (default: true)"); | 69 | "Enable power-saving render C-state 6 (default: true)"); |
70 | 70 | ||
71 | unsigned int i915_enable_fbc __read_mostly = -1; | 71 | int i915_enable_fbc __read_mostly = -1; |
72 | module_param_named(i915_enable_fbc, i915_enable_fbc, int, 0600); | 72 | module_param_named(i915_enable_fbc, i915_enable_fbc, int, 0600); |
73 | MODULE_PARM_DESC(i915_enable_fbc, | 73 | MODULE_PARM_DESC(i915_enable_fbc, |
74 | "Enable frame buffer compression for power savings " | 74 | "Enable frame buffer compression for power savings " |
@@ -80,7 +80,7 @@ MODULE_PARM_DESC(lvds_downclock, | |||
80 | "Use panel (LVDS/eDP) downclocking for power savings " | 80 | "Use panel (LVDS/eDP) downclocking for power savings " |
81 | "(default: false)"); | 81 | "(default: false)"); |
82 | 82 | ||
83 | unsigned int i915_panel_use_ssc __read_mostly = -1; | 83 | int i915_panel_use_ssc __read_mostly = -1; |
84 | module_param_named(lvds_use_ssc, i915_panel_use_ssc, int, 0600); | 84 | module_param_named(lvds_use_ssc, i915_panel_use_ssc, int, 0600); |
85 | MODULE_PARM_DESC(lvds_use_ssc, | 85 | MODULE_PARM_DESC(lvds_use_ssc, |
86 | "Use Spread Spectrum Clock with panels [LVDS/eDP] " | 86 | "Use Spread Spectrum Clock with panels [LVDS/eDP] " |
@@ -107,7 +107,7 @@ static struct drm_driver driver; | |||
107 | extern int intel_agp_enabled; | 107 | extern int intel_agp_enabled; |
108 | 108 | ||
109 | #define INTEL_VGA_DEVICE(id, info) { \ | 109 | #define INTEL_VGA_DEVICE(id, info) { \ |
110 | .class = PCI_CLASS_DISPLAY_VGA << 8, \ | 110 | .class = PCI_BASE_CLASS_DISPLAY << 16, \ |
111 | .class_mask = 0xff0000, \ | 111 | .class_mask = 0xff0000, \ |
112 | .vendor = 0x8086, \ | 112 | .vendor = 0x8086, \ |
113 | .device = id, \ | 113 | .device = id, \ |
@@ -789,8 +789,8 @@ static struct vm_operations_struct i915_gem_vm_ops = { | |||
789 | }; | 789 | }; |
790 | 790 | ||
791 | static struct drm_driver driver = { | 791 | static struct drm_driver driver = { |
792 | /* don't use mtrr's here, the Xserver or user space app should | 792 | /* Don't use MTRRs here; the Xserver or userspace app should |
793 | * deal with them for intel hardware. | 793 | * deal with them for Intel hardware. |
794 | */ | 794 | */ |
795 | .driver_features = | 795 | .driver_features = |
796 | DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | /* DRIVER_USE_MTRR |*/ | 796 | DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | /* DRIVER_USE_MTRR |*/ |
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 06a37f4fd74b..4a9c1b979804 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h | |||
@@ -126,6 +126,9 @@ struct drm_i915_master_private { | |||
126 | struct _drm_i915_sarea *sarea_priv; | 126 | struct _drm_i915_sarea *sarea_priv; |
127 | }; | 127 | }; |
128 | #define I915_FENCE_REG_NONE -1 | 128 | #define I915_FENCE_REG_NONE -1 |
129 | #define I915_MAX_NUM_FENCES 16 | ||
130 | /* 16 fences + sign bit for FENCE_REG_NONE */ | ||
131 | #define I915_MAX_NUM_FENCE_BITS 5 | ||
129 | 132 | ||
130 | struct drm_i915_fence_reg { | 133 | struct drm_i915_fence_reg { |
131 | struct list_head lru_list; | 134 | struct list_head lru_list; |
@@ -168,7 +171,7 @@ struct drm_i915_error_state { | |||
168 | u32 instdone1; | 171 | u32 instdone1; |
169 | u32 seqno; | 172 | u32 seqno; |
170 | u64 bbaddr; | 173 | u64 bbaddr; |
171 | u64 fence[16]; | 174 | u64 fence[I915_MAX_NUM_FENCES]; |
172 | struct timeval time; | 175 | struct timeval time; |
173 | struct drm_i915_error_object { | 176 | struct drm_i915_error_object { |
174 | int page_count; | 177 | int page_count; |
@@ -182,7 +185,7 @@ struct drm_i915_error_state { | |||
182 | u32 gtt_offset; | 185 | u32 gtt_offset; |
183 | u32 read_domains; | 186 | u32 read_domains; |
184 | u32 write_domain; | 187 | u32 write_domain; |
185 | s32 fence_reg:5; | 188 | s32 fence_reg:I915_MAX_NUM_FENCE_BITS; |
186 | s32 pinned:2; | 189 | s32 pinned:2; |
187 | u32 tiling:2; | 190 | u32 tiling:2; |
188 | u32 dirty:1; | 191 | u32 dirty:1; |
@@ -375,7 +378,7 @@ typedef struct drm_i915_private { | |||
375 | struct notifier_block lid_notifier; | 378 | struct notifier_block lid_notifier; |
376 | 379 | ||
377 | int crt_ddc_pin; | 380 | int crt_ddc_pin; |
378 | struct drm_i915_fence_reg fence_regs[16]; /* assume 965 */ | 381 | struct drm_i915_fence_reg fence_regs[I915_MAX_NUM_FENCES]; /* assume 965 */ |
379 | int fence_reg_start; /* 4 if userland hasn't ioctl'd us yet */ | 382 | int fence_reg_start; /* 4 if userland hasn't ioctl'd us yet */ |
380 | int num_fence_regs; /* 8 on pre-965, 16 otherwise */ | 383 | int num_fence_regs; /* 8 on pre-965, 16 otherwise */ |
381 | 384 | ||
@@ -506,7 +509,7 @@ typedef struct drm_i915_private { | |||
506 | u8 saveAR[21]; | 509 | u8 saveAR[21]; |
507 | u8 saveDACMASK; | 510 | u8 saveDACMASK; |
508 | u8 saveCR[37]; | 511 | u8 saveCR[37]; |
509 | uint64_t saveFENCE[16]; | 512 | uint64_t saveFENCE[I915_MAX_NUM_FENCES]; |
510 | u32 saveCURACNTR; | 513 | u32 saveCURACNTR; |
511 | u32 saveCURAPOS; | 514 | u32 saveCURAPOS; |
512 | u32 saveCURABASE; | 515 | u32 saveCURABASE; |
@@ -777,10 +780,8 @@ struct drm_i915_gem_object { | |||
777 | * Fence register bits (if any) for this object. Will be set | 780 | * Fence register bits (if any) for this object. Will be set |
778 | * as needed when mapped into the GTT. | 781 | * as needed when mapped into the GTT. |
779 | * Protected by dev->struct_mutex. | 782 | * Protected by dev->struct_mutex. |
780 | * | ||
781 | * Size: 4 bits for 16 fences + sign (for FENCE_REG_NONE) | ||
782 | */ | 783 | */ |
783 | signed int fence_reg:5; | 784 | signed int fence_reg:I915_MAX_NUM_FENCE_BITS; |
784 | 785 | ||
785 | /** | 786 | /** |
786 | * Advice: are the backing pages purgeable? | 787 | * Advice: are the backing pages purgeable? |
@@ -999,10 +1000,10 @@ extern int i915_panel_ignore_lid __read_mostly; | |||
999 | extern unsigned int i915_powersave __read_mostly; | 1000 | extern unsigned int i915_powersave __read_mostly; |
1000 | extern unsigned int i915_semaphores __read_mostly; | 1001 | extern unsigned int i915_semaphores __read_mostly; |
1001 | extern unsigned int i915_lvds_downclock __read_mostly; | 1002 | extern unsigned int i915_lvds_downclock __read_mostly; |
1002 | extern unsigned int i915_panel_use_ssc __read_mostly; | 1003 | extern int i915_panel_use_ssc __read_mostly; |
1003 | extern int i915_vbt_sdvo_panel_type __read_mostly; | 1004 | extern int i915_vbt_sdvo_panel_type __read_mostly; |
1004 | extern unsigned int i915_enable_rc6 __read_mostly; | 1005 | extern unsigned int i915_enable_rc6 __read_mostly; |
1005 | extern unsigned int i915_enable_fbc __read_mostly; | 1006 | extern int i915_enable_fbc __read_mostly; |
1006 | extern bool i915_enable_hangcheck __read_mostly; | 1007 | extern bool i915_enable_hangcheck __read_mostly; |
1007 | 1008 | ||
1008 | extern int i915_suspend(struct drm_device *dev, pm_message_t state); | 1009 | extern int i915_suspend(struct drm_device *dev, pm_message_t state); |
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 6651c36b6e8a..8359dc777041 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c | |||
@@ -1396,7 +1396,7 @@ i915_gem_mmap_gtt(struct drm_file *file, | |||
1396 | 1396 | ||
1397 | if (obj->base.size > dev_priv->mm.gtt_mappable_end) { | 1397 | if (obj->base.size > dev_priv->mm.gtt_mappable_end) { |
1398 | ret = -E2BIG; | 1398 | ret = -E2BIG; |
1399 | goto unlock; | 1399 | goto out; |
1400 | } | 1400 | } |
1401 | 1401 | ||
1402 | if (obj->madv != I915_MADV_WILLNEED) { | 1402 | if (obj->madv != I915_MADV_WILLNEED) { |
@@ -1745,7 +1745,7 @@ static void i915_gem_reset_fences(struct drm_device *dev) | |||
1745 | struct drm_i915_private *dev_priv = dev->dev_private; | 1745 | struct drm_i915_private *dev_priv = dev->dev_private; |
1746 | int i; | 1746 | int i; |
1747 | 1747 | ||
1748 | for (i = 0; i < 16; i++) { | 1748 | for (i = 0; i < dev_priv->num_fence_regs; i++) { |
1749 | struct drm_i915_fence_reg *reg = &dev_priv->fence_regs[i]; | 1749 | struct drm_i915_fence_reg *reg = &dev_priv->fence_regs[i]; |
1750 | struct drm_i915_gem_object *obj = reg->obj; | 1750 | struct drm_i915_gem_object *obj = reg->obj; |
1751 | 1751 | ||
@@ -3512,9 +3512,11 @@ i915_gem_busy_ioctl(struct drm_device *dev, void *data, | |||
3512 | * so emit a request to do so. | 3512 | * so emit a request to do so. |
3513 | */ | 3513 | */ |
3514 | request = kzalloc(sizeof(*request), GFP_KERNEL); | 3514 | request = kzalloc(sizeof(*request), GFP_KERNEL); |
3515 | if (request) | 3515 | if (request) { |
3516 | ret = i915_add_request(obj->ring, NULL, request); | 3516 | ret = i915_add_request(obj->ring, NULL, request); |
3517 | else | 3517 | if (ret) |
3518 | kfree(request); | ||
3519 | } else | ||
3518 | ret = -ENOMEM; | 3520 | ret = -ENOMEM; |
3519 | } | 3521 | } |
3520 | 3522 | ||
@@ -3613,7 +3615,7 @@ struct drm_i915_gem_object *i915_gem_alloc_object(struct drm_device *dev, | |||
3613 | obj->base.write_domain = I915_GEM_DOMAIN_CPU; | 3615 | obj->base.write_domain = I915_GEM_DOMAIN_CPU; |
3614 | obj->base.read_domains = I915_GEM_DOMAIN_CPU; | 3616 | obj->base.read_domains = I915_GEM_DOMAIN_CPU; |
3615 | 3617 | ||
3616 | if (IS_GEN6(dev)) { | 3618 | if (IS_GEN6(dev) || IS_GEN7(dev)) { |
3617 | /* On Gen6, we can have the GPU use the LLC (the CPU | 3619 | /* On Gen6, we can have the GPU use the LLC (the CPU |
3618 | * cache) for about a 10% performance improvement | 3620 | * cache) for about a 10% performance improvement |
3619 | * compared to uncached. Graphics requests other than | 3621 | * compared to uncached. Graphics requests other than |
@@ -3877,7 +3879,7 @@ i915_gem_load(struct drm_device *dev) | |||
3877 | INIT_LIST_HEAD(&dev_priv->mm.gtt_list); | 3879 | INIT_LIST_HEAD(&dev_priv->mm.gtt_list); |
3878 | for (i = 0; i < I915_NUM_RINGS; i++) | 3880 | for (i = 0; i < I915_NUM_RINGS; i++) |
3879 | init_ring_lists(&dev_priv->ring[i]); | 3881 | init_ring_lists(&dev_priv->ring[i]); |
3880 | for (i = 0; i < 16; i++) | 3882 | for (i = 0; i < I915_MAX_NUM_FENCES; i++) |
3881 | INIT_LIST_HEAD(&dev_priv->fence_regs[i].lru_list); | 3883 | INIT_LIST_HEAD(&dev_priv->fence_regs[i].lru_list); |
3882 | INIT_DELAYED_WORK(&dev_priv->mm.retire_work, | 3884 | INIT_DELAYED_WORK(&dev_priv->mm.retire_work, |
3883 | i915_gem_retire_work_handler); | 3885 | i915_gem_retire_work_handler); |
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 9ee2729fe5c6..b40004b55977 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c | |||
@@ -824,6 +824,7 @@ static void i915_gem_record_fences(struct drm_device *dev, | |||
824 | 824 | ||
825 | /* Fences */ | 825 | /* Fences */ |
826 | switch (INTEL_INFO(dev)->gen) { | 826 | switch (INTEL_INFO(dev)->gen) { |
827 | case 7: | ||
827 | case 6: | 828 | case 6: |
828 | for (i = 0; i < 16; i++) | 829 | for (i = 0; i < 16; i++) |
829 | error->fence[i] = I915_READ64(FENCE_REG_SANDYBRIDGE_0 + (i * 8)); | 830 | error->fence[i] = I915_READ64(FENCE_REG_SANDYBRIDGE_0 + (i * 8)); |
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 5a09416e611f..b080cc824001 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h | |||
@@ -1553,12 +1553,21 @@ | |||
1553 | */ | 1553 | */ |
1554 | #define PP_READY (1 << 30) | 1554 | #define PP_READY (1 << 30) |
1555 | #define PP_SEQUENCE_NONE (0 << 28) | 1555 | #define PP_SEQUENCE_NONE (0 << 28) |
1556 | #define PP_SEQUENCE_ON (1 << 28) | 1556 | #define PP_SEQUENCE_POWER_UP (1 << 28) |
1557 | #define PP_SEQUENCE_OFF (2 << 28) | 1557 | #define PP_SEQUENCE_POWER_DOWN (2 << 28) |
1558 | #define PP_SEQUENCE_MASK 0x30000000 | 1558 | #define PP_SEQUENCE_MASK (3 << 28) |
1559 | #define PP_SEQUENCE_SHIFT 28 | ||
1559 | #define PP_CYCLE_DELAY_ACTIVE (1 << 27) | 1560 | #define PP_CYCLE_DELAY_ACTIVE (1 << 27) |
1560 | #define PP_SEQUENCE_STATE_ON_IDLE (1 << 3) | ||
1561 | #define PP_SEQUENCE_STATE_MASK 0x0000000f | 1561 | #define PP_SEQUENCE_STATE_MASK 0x0000000f |
1562 | #define PP_SEQUENCE_STATE_OFF_IDLE (0x0 << 0) | ||
1563 | #define PP_SEQUENCE_STATE_OFF_S0_1 (0x1 << 0) | ||
1564 | #define PP_SEQUENCE_STATE_OFF_S0_2 (0x2 << 0) | ||
1565 | #define PP_SEQUENCE_STATE_OFF_S0_3 (0x3 << 0) | ||
1566 | #define PP_SEQUENCE_STATE_ON_IDLE (0x8 << 0) | ||
1567 | #define PP_SEQUENCE_STATE_ON_S1_0 (0x9 << 0) | ||
1568 | #define PP_SEQUENCE_STATE_ON_S1_2 (0xa << 0) | ||
1569 | #define PP_SEQUENCE_STATE_ON_S1_3 (0xb << 0) | ||
1570 | #define PP_SEQUENCE_STATE_RESET (0xf << 0) | ||
1562 | #define PP_CONTROL 0x61204 | 1571 | #define PP_CONTROL 0x61204 |
1563 | #define POWER_TARGET_ON (1 << 0) | 1572 | #define POWER_TARGET_ON (1 << 0) |
1564 | #define PP_ON_DELAYS 0x61208 | 1573 | #define PP_ON_DELAYS 0x61208 |
@@ -3444,6 +3453,10 @@ | |||
3444 | #define GT_FIFO_FREE_ENTRIES 0x120008 | 3453 | #define GT_FIFO_FREE_ENTRIES 0x120008 |
3445 | #define GT_FIFO_NUM_RESERVED_ENTRIES 20 | 3454 | #define GT_FIFO_NUM_RESERVED_ENTRIES 20 |
3446 | 3455 | ||
3456 | #define GEN6_UCGCTL2 0x9404 | ||
3457 | # define GEN6_RCPBUNIT_CLOCK_GATE_DISABLE (1 << 12) | ||
3458 | # define GEN6_RCCUNIT_CLOCK_GATE_DISABLE (1 << 11) | ||
3459 | |||
3447 | #define GEN6_RPNSWREQ 0xA008 | 3460 | #define GEN6_RPNSWREQ 0xA008 |
3448 | #define GEN6_TURBO_DISABLE (1<<31) | 3461 | #define GEN6_TURBO_DISABLE (1<<31) |
3449 | #define GEN6_FREQUENCY(x) ((x)<<25) | 3462 | #define GEN6_FREQUENCY(x) ((x)<<25) |
diff --git a/drivers/gpu/drm/i915/i915_suspend.c b/drivers/gpu/drm/i915/i915_suspend.c index f8f602d76650..7886e4fb60e3 100644 --- a/drivers/gpu/drm/i915/i915_suspend.c +++ b/drivers/gpu/drm/i915/i915_suspend.c | |||
@@ -370,6 +370,7 @@ static void i915_save_modeset_reg(struct drm_device *dev) | |||
370 | 370 | ||
371 | /* Fences */ | 371 | /* Fences */ |
372 | switch (INTEL_INFO(dev)->gen) { | 372 | switch (INTEL_INFO(dev)->gen) { |
373 | case 7: | ||
373 | case 6: | 374 | case 6: |
374 | for (i = 0; i < 16; i++) | 375 | for (i = 0; i < 16; i++) |
375 | dev_priv->saveFENCE[i] = I915_READ64(FENCE_REG_SANDYBRIDGE_0 + (i * 8)); | 376 | dev_priv->saveFENCE[i] = I915_READ64(FENCE_REG_SANDYBRIDGE_0 + (i * 8)); |
@@ -404,6 +405,7 @@ static void i915_restore_modeset_reg(struct drm_device *dev) | |||
404 | 405 | ||
405 | /* Fences */ | 406 | /* Fences */ |
406 | switch (INTEL_INFO(dev)->gen) { | 407 | switch (INTEL_INFO(dev)->gen) { |
408 | case 7: | ||
407 | case 6: | 409 | case 6: |
408 | for (i = 0; i < 16; i++) | 410 | for (i = 0; i < 16; i++) |
409 | I915_WRITE64(FENCE_REG_SANDYBRIDGE_0 + (i * 8), dev_priv->saveFENCE[i]); | 411 | I915_WRITE64(FENCE_REG_SANDYBRIDGE_0 + (i * 8), dev_priv->saveFENCE[i]); |
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 981b1f1c04d8..e77a863a3833 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
@@ -2933,7 +2933,8 @@ static void ironlake_pch_enable(struct drm_crtc *crtc) | |||
2933 | 2933 | ||
2934 | /* For PCH DP, enable TRANS_DP_CTL */ | 2934 | /* For PCH DP, enable TRANS_DP_CTL */ |
2935 | if (HAS_PCH_CPT(dev) && | 2935 | if (HAS_PCH_CPT(dev) && |
2936 | intel_pipe_has_type(crtc, INTEL_OUTPUT_DISPLAYPORT)) { | 2936 | (intel_pipe_has_type(crtc, INTEL_OUTPUT_DISPLAYPORT) || |
2937 | intel_pipe_has_type(crtc, INTEL_OUTPUT_EDP))) { | ||
2937 | u32 bpc = (I915_READ(PIPECONF(pipe)) & PIPE_BPC_MASK) >> 5; | 2938 | u32 bpc = (I915_READ(PIPECONF(pipe)) & PIPE_BPC_MASK) >> 5; |
2938 | reg = TRANS_DP_CTL(pipe); | 2939 | reg = TRANS_DP_CTL(pipe); |
2939 | temp = I915_READ(reg); | 2940 | temp = I915_READ(reg); |
@@ -4711,7 +4712,7 @@ static bool intel_choose_pipe_bpp_dither(struct drm_crtc *crtc, | |||
4711 | lvds_bpc = 6; | 4712 | lvds_bpc = 6; |
4712 | 4713 | ||
4713 | if (lvds_bpc < display_bpc) { | 4714 | if (lvds_bpc < display_bpc) { |
4714 | DRM_DEBUG_DRIVER("clamping display bpc (was %d) to LVDS (%d)\n", display_bpc, lvds_bpc); | 4715 | DRM_DEBUG_KMS("clamping display bpc (was %d) to LVDS (%d)\n", display_bpc, lvds_bpc); |
4715 | display_bpc = lvds_bpc; | 4716 | display_bpc = lvds_bpc; |
4716 | } | 4717 | } |
4717 | continue; | 4718 | continue; |
@@ -4722,7 +4723,7 @@ static bool intel_choose_pipe_bpp_dither(struct drm_crtc *crtc, | |||
4722 | unsigned int edp_bpc = dev_priv->edp.bpp / 3; | 4723 | unsigned int edp_bpc = dev_priv->edp.bpp / 3; |
4723 | 4724 | ||
4724 | if (edp_bpc < display_bpc) { | 4725 | if (edp_bpc < display_bpc) { |
4725 | DRM_DEBUG_DRIVER("clamping display bpc (was %d) to eDP (%d)\n", display_bpc, edp_bpc); | 4726 | DRM_DEBUG_KMS("clamping display bpc (was %d) to eDP (%d)\n", display_bpc, edp_bpc); |
4726 | display_bpc = edp_bpc; | 4727 | display_bpc = edp_bpc; |
4727 | } | 4728 | } |
4728 | continue; | 4729 | continue; |
@@ -4737,7 +4738,7 @@ static bool intel_choose_pipe_bpp_dither(struct drm_crtc *crtc, | |||
4737 | /* Don't use an invalid EDID bpc value */ | 4738 | /* Don't use an invalid EDID bpc value */ |
4738 | if (connector->display_info.bpc && | 4739 | if (connector->display_info.bpc && |
4739 | connector->display_info.bpc < display_bpc) { | 4740 | connector->display_info.bpc < display_bpc) { |
4740 | DRM_DEBUG_DRIVER("clamping display bpc (was %d) to EDID reported max of %d\n", display_bpc, connector->display_info.bpc); | 4741 | DRM_DEBUG_KMS("clamping display bpc (was %d) to EDID reported max of %d\n", display_bpc, connector->display_info.bpc); |
4741 | display_bpc = connector->display_info.bpc; | 4742 | display_bpc = connector->display_info.bpc; |
4742 | } | 4743 | } |
4743 | } | 4744 | } |
@@ -4748,10 +4749,10 @@ static bool intel_choose_pipe_bpp_dither(struct drm_crtc *crtc, | |||
4748 | */ | 4749 | */ |
4749 | if (intel_encoder->type == INTEL_OUTPUT_HDMI) { | 4750 | if (intel_encoder->type == INTEL_OUTPUT_HDMI) { |
4750 | if (display_bpc > 8 && display_bpc < 12) { | 4751 | if (display_bpc > 8 && display_bpc < 12) { |
4751 | DRM_DEBUG_DRIVER("forcing bpc to 12 for HDMI\n"); | 4752 | DRM_DEBUG_KMS("forcing bpc to 12 for HDMI\n"); |
4752 | display_bpc = 12; | 4753 | display_bpc = 12; |
4753 | } else { | 4754 | } else { |
4754 | DRM_DEBUG_DRIVER("forcing bpc to 8 for HDMI\n"); | 4755 | DRM_DEBUG_KMS("forcing bpc to 8 for HDMI\n"); |
4755 | display_bpc = 8; | 4756 | display_bpc = 8; |
4756 | } | 4757 | } |
4757 | } | 4758 | } |
@@ -4789,8 +4790,8 @@ static bool intel_choose_pipe_bpp_dither(struct drm_crtc *crtc, | |||
4789 | 4790 | ||
4790 | display_bpc = min(display_bpc, bpc); | 4791 | display_bpc = min(display_bpc, bpc); |
4791 | 4792 | ||
4792 | DRM_DEBUG_DRIVER("setting pipe bpc to %d (max display bpc %d)\n", | 4793 | DRM_DEBUG_KMS("setting pipe bpc to %d (max display bpc %d)\n", |
4793 | bpc, display_bpc); | 4794 | bpc, display_bpc); |
4794 | 4795 | ||
4795 | *pipe_bpp = display_bpc * 3; | 4796 | *pipe_bpp = display_bpc * 3; |
4796 | 4797 | ||
@@ -5671,7 +5672,7 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc, | |||
5671 | pipeconf &= ~PIPECONF_DITHER_TYPE_MASK; | 5672 | pipeconf &= ~PIPECONF_DITHER_TYPE_MASK; |
5672 | if ((is_lvds && dev_priv->lvds_dither) || dither) { | 5673 | if ((is_lvds && dev_priv->lvds_dither) || dither) { |
5673 | pipeconf |= PIPECONF_DITHER_EN; | 5674 | pipeconf |= PIPECONF_DITHER_EN; |
5674 | pipeconf |= PIPECONF_DITHER_TYPE_ST1; | 5675 | pipeconf |= PIPECONF_DITHER_TYPE_SP; |
5675 | } | 5676 | } |
5676 | if (is_dp || intel_encoder_is_pch_edp(&has_edp_encoder->base)) { | 5677 | if (is_dp || intel_encoder_is_pch_edp(&has_edp_encoder->base)) { |
5677 | intel_dp_set_m_n(crtc, mode, adjusted_mode); | 5678 | intel_dp_set_m_n(crtc, mode, adjusted_mode); |
@@ -8148,6 +8149,20 @@ static void gen6_init_clock_gating(struct drm_device *dev) | |||
8148 | I915_WRITE(WM2_LP_ILK, 0); | 8149 | I915_WRITE(WM2_LP_ILK, 0); |
8149 | I915_WRITE(WM1_LP_ILK, 0); | 8150 | I915_WRITE(WM1_LP_ILK, 0); |
8150 | 8151 | ||
8152 | /* According to the BSpec vol1g, bit 12 (RCPBUNIT) clock | ||
8153 | * gating disable must be set. Failure to set it results in | ||
8154 | * flickering pixels due to Z write ordering failures after | ||
8155 | * some amount of runtime in the Mesa "fire" demo, and Unigine | ||
8156 | * Sanctuary and Tropics, and apparently anything else with | ||
8157 | * alpha test or pixel discard. | ||
8158 | * | ||
8159 | * According to the spec, bit 11 (RCCUNIT) must also be set, | ||
8160 | * but we didn't debug actual testcases to find it out. | ||
8161 | */ | ||
8162 | I915_WRITE(GEN6_UCGCTL2, | ||
8163 | GEN6_RCPBUNIT_CLOCK_GATE_DISABLE | | ||
8164 | GEN6_RCCUNIT_CLOCK_GATE_DISABLE); | ||
8165 | |||
8151 | /* | 8166 | /* |
8152 | * According to the spec the following bits should be | 8167 | * According to the spec the following bits should be |
8153 | * set in order to enable memory self-refresh and fbc: | 8168 | * set in order to enable memory self-refresh and fbc: |
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 09b318b0227f..4d0358fad937 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c | |||
@@ -59,7 +59,6 @@ struct intel_dp { | |||
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 | uint8_t train_set[4]; | 61 | uint8_t train_set[4]; |
62 | uint8_t link_status[DP_LINK_STATUS_SIZE]; | ||
63 | int panel_power_up_delay; | 62 | int panel_power_up_delay; |
64 | int panel_power_down_delay; | 63 | int panel_power_down_delay; |
65 | int panel_power_cycle_delay; | 64 | int panel_power_cycle_delay; |
@@ -68,7 +67,6 @@ struct intel_dp { | |||
68 | struct drm_display_mode *panel_fixed_mode; /* for eDP */ | 67 | struct drm_display_mode *panel_fixed_mode; /* for eDP */ |
69 | struct delayed_work panel_vdd_work; | 68 | struct delayed_work panel_vdd_work; |
70 | bool want_panel_vdd; | 69 | bool want_panel_vdd; |
71 | unsigned long panel_off_jiffies; | ||
72 | }; | 70 | }; |
73 | 71 | ||
74 | /** | 72 | /** |
@@ -157,16 +155,12 @@ intel_edp_link_config(struct intel_encoder *intel_encoder, | |||
157 | static int | 155 | static int |
158 | intel_dp_max_lane_count(struct intel_dp *intel_dp) | 156 | intel_dp_max_lane_count(struct intel_dp *intel_dp) |
159 | { | 157 | { |
160 | int max_lane_count = 4; | 158 | int max_lane_count = intel_dp->dpcd[DP_MAX_LANE_COUNT] & 0x1f; |
161 | 159 | switch (max_lane_count) { | |
162 | if (intel_dp->dpcd[DP_DPCD_REV] >= 0x11) { | 160 | case 1: case 2: case 4: |
163 | max_lane_count = intel_dp->dpcd[DP_MAX_LANE_COUNT] & 0x1f; | 161 | break; |
164 | switch (max_lane_count) { | 162 | default: |
165 | case 1: case 2: case 4: | 163 | max_lane_count = 4; |
166 | break; | ||
167 | default: | ||
168 | max_lane_count = 4; | ||
169 | } | ||
170 | } | 164 | } |
171 | return max_lane_count; | 165 | return max_lane_count; |
172 | } | 166 | } |
@@ -768,12 +762,11 @@ intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode, | |||
768 | continue; | 762 | continue; |
769 | 763 | ||
770 | intel_dp = enc_to_intel_dp(encoder); | 764 | intel_dp = enc_to_intel_dp(encoder); |
771 | if (intel_dp->base.type == INTEL_OUTPUT_DISPLAYPORT) { | 765 | if (intel_dp->base.type == INTEL_OUTPUT_DISPLAYPORT || |
766 | intel_dp->base.type == INTEL_OUTPUT_EDP) | ||
767 | { | ||
772 | lane_count = intel_dp->lane_count; | 768 | lane_count = intel_dp->lane_count; |
773 | break; | 769 | break; |
774 | } else if (is_edp(intel_dp)) { | ||
775 | lane_count = dev_priv->edp.lanes; | ||
776 | break; | ||
777 | } | 770 | } |
778 | } | 771 | } |
779 | 772 | ||
@@ -810,6 +803,7 @@ intel_dp_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, | |||
810 | struct drm_display_mode *adjusted_mode) | 803 | struct drm_display_mode *adjusted_mode) |
811 | { | 804 | { |
812 | struct drm_device *dev = encoder->dev; | 805 | struct drm_device *dev = encoder->dev; |
806 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
813 | struct intel_dp *intel_dp = enc_to_intel_dp(encoder); | 807 | struct intel_dp *intel_dp = enc_to_intel_dp(encoder); |
814 | struct drm_crtc *crtc = intel_dp->base.base.crtc; | 808 | struct drm_crtc *crtc = intel_dp->base.base.crtc; |
815 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | 809 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
@@ -822,18 +816,31 @@ intel_dp_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, | |||
822 | ironlake_edp_pll_off(encoder); | 816 | ironlake_edp_pll_off(encoder); |
823 | } | 817 | } |
824 | 818 | ||
825 | intel_dp->DP = DP_VOLTAGE_0_4 | DP_PRE_EMPHASIS_0; | 819 | /* |
826 | intel_dp->DP |= intel_dp->color_range; | 820 | * There are three kinds of DP registers: |
821 | * | ||
822 | * IBX PCH | ||
823 | * CPU | ||
824 | * CPT PCH | ||
825 | * | ||
826 | * IBX PCH and CPU are the same for almost everything, | ||
827 | * except that the CPU DP PLL is configured in this | ||
828 | * register | ||
829 | * | ||
830 | * CPT PCH is quite different, having many bits moved | ||
831 | * to the TRANS_DP_CTL register instead. That | ||
832 | * configuration happens (oddly) in ironlake_pch_enable | ||
833 | */ | ||
827 | 834 | ||
828 | if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC) | 835 | /* Preserve the BIOS-computed detected bit. This is |
829 | intel_dp->DP |= DP_SYNC_HS_HIGH; | 836 | * supposed to be read-only. |
830 | if (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC) | 837 | */ |
831 | intel_dp->DP |= DP_SYNC_VS_HIGH; | 838 | intel_dp->DP = I915_READ(intel_dp->output_reg) & DP_DETECTED; |
839 | intel_dp->DP |= DP_VOLTAGE_0_4 | DP_PRE_EMPHASIS_0; | ||
832 | 840 | ||
833 | if (HAS_PCH_CPT(dev) && !is_cpu_edp(intel_dp)) | 841 | /* Handle DP bits in common between all three register formats */ |
834 | intel_dp->DP |= DP_LINK_TRAIN_OFF_CPT; | 842 | |
835 | else | 843 | intel_dp->DP |= DP_VOLTAGE_0_4 | DP_PRE_EMPHASIS_0; |
836 | intel_dp->DP |= DP_LINK_TRAIN_OFF; | ||
837 | 844 | ||
838 | switch (intel_dp->lane_count) { | 845 | switch (intel_dp->lane_count) { |
839 | case 1: | 846 | case 1: |
@@ -852,59 +859,106 @@ intel_dp_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, | |||
852 | intel_dp->DP |= DP_AUDIO_OUTPUT_ENABLE; | 859 | intel_dp->DP |= DP_AUDIO_OUTPUT_ENABLE; |
853 | intel_write_eld(encoder, adjusted_mode); | 860 | intel_write_eld(encoder, adjusted_mode); |
854 | } | 861 | } |
855 | |||
856 | memset(intel_dp->link_configuration, 0, DP_LINK_CONFIGURATION_SIZE); | 862 | memset(intel_dp->link_configuration, 0, DP_LINK_CONFIGURATION_SIZE); |
857 | intel_dp->link_configuration[0] = intel_dp->link_bw; | 863 | intel_dp->link_configuration[0] = intel_dp->link_bw; |
858 | intel_dp->link_configuration[1] = intel_dp->lane_count; | 864 | intel_dp->link_configuration[1] = intel_dp->lane_count; |
859 | intel_dp->link_configuration[8] = DP_SET_ANSI_8B10B; | 865 | intel_dp->link_configuration[8] = DP_SET_ANSI_8B10B; |
860 | |||
861 | /* | 866 | /* |
862 | * Check for DPCD version > 1.1 and enhanced framing support | 867 | * Check for DPCD version > 1.1 and enhanced framing support |
863 | */ | 868 | */ |
864 | if (intel_dp->dpcd[DP_DPCD_REV] >= 0x11 && | 869 | if (intel_dp->dpcd[DP_DPCD_REV] >= 0x11 && |
865 | (intel_dp->dpcd[DP_MAX_LANE_COUNT] & DP_ENHANCED_FRAME_CAP)) { | 870 | (intel_dp->dpcd[DP_MAX_LANE_COUNT] & DP_ENHANCED_FRAME_CAP)) { |
866 | intel_dp->link_configuration[1] |= DP_LANE_COUNT_ENHANCED_FRAME_EN; | 871 | intel_dp->link_configuration[1] |= DP_LANE_COUNT_ENHANCED_FRAME_EN; |
867 | intel_dp->DP |= DP_ENHANCED_FRAMING; | ||
868 | } | 872 | } |
869 | 873 | ||
870 | /* CPT DP's pipe select is decided in TRANS_DP_CTL */ | 874 | /* Split out the IBX/CPU vs CPT settings */ |
871 | if (intel_crtc->pipe == 1 && !HAS_PCH_CPT(dev)) | ||
872 | intel_dp->DP |= DP_PIPEB_SELECT; | ||
873 | 875 | ||
874 | if (is_cpu_edp(intel_dp)) { | 876 | if (!HAS_PCH_CPT(dev) || is_cpu_edp(intel_dp)) { |
875 | /* don't miss out required setting for eDP */ | 877 | intel_dp->DP |= intel_dp->color_range; |
876 | intel_dp->DP |= DP_PLL_ENABLE; | 878 | |
877 | if (adjusted_mode->clock < 200000) | 879 | if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC) |
878 | intel_dp->DP |= DP_PLL_FREQ_160MHZ; | 880 | intel_dp->DP |= DP_SYNC_HS_HIGH; |
879 | else | 881 | if (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC) |
880 | intel_dp->DP |= DP_PLL_FREQ_270MHZ; | 882 | intel_dp->DP |= DP_SYNC_VS_HIGH; |
883 | intel_dp->DP |= DP_LINK_TRAIN_OFF; | ||
884 | |||
885 | if (intel_dp->link_configuration[1] & DP_LANE_COUNT_ENHANCED_FRAME_EN) | ||
886 | intel_dp->DP |= DP_ENHANCED_FRAMING; | ||
887 | |||
888 | if (intel_crtc->pipe == 1) | ||
889 | intel_dp->DP |= DP_PIPEB_SELECT; | ||
890 | |||
891 | if (is_cpu_edp(intel_dp)) { | ||
892 | /* don't miss out required setting for eDP */ | ||
893 | intel_dp->DP |= DP_PLL_ENABLE; | ||
894 | if (adjusted_mode->clock < 200000) | ||
895 | intel_dp->DP |= DP_PLL_FREQ_160MHZ; | ||
896 | else | ||
897 | intel_dp->DP |= DP_PLL_FREQ_270MHZ; | ||
898 | } | ||
899 | } else { | ||
900 | intel_dp->DP |= DP_LINK_TRAIN_OFF_CPT; | ||
881 | } | 901 | } |
882 | } | 902 | } |
883 | 903 | ||
884 | static void ironlake_wait_panel_off(struct intel_dp *intel_dp) | 904 | #define IDLE_ON_MASK (PP_ON | 0 | PP_SEQUENCE_MASK | 0 | PP_SEQUENCE_STATE_MASK) |
905 | #define IDLE_ON_VALUE (PP_ON | 0 | PP_SEQUENCE_NONE | 0 | PP_SEQUENCE_STATE_ON_IDLE) | ||
906 | |||
907 | #define IDLE_OFF_MASK (PP_ON | 0 | PP_SEQUENCE_MASK | 0 | PP_SEQUENCE_STATE_MASK) | ||
908 | #define IDLE_OFF_VALUE (0 | 0 | PP_SEQUENCE_NONE | 0 | PP_SEQUENCE_STATE_OFF_IDLE) | ||
909 | |||
910 | #define IDLE_CYCLE_MASK (PP_ON | 0 | PP_SEQUENCE_MASK | PP_CYCLE_DELAY_ACTIVE | PP_SEQUENCE_STATE_MASK) | ||
911 | #define IDLE_CYCLE_VALUE (0 | 0 | PP_SEQUENCE_NONE | 0 | PP_SEQUENCE_STATE_OFF_IDLE) | ||
912 | |||
913 | static void ironlake_wait_panel_status(struct intel_dp *intel_dp, | ||
914 | u32 mask, | ||
915 | u32 value) | ||
885 | { | 916 | { |
886 | unsigned long off_time; | 917 | struct drm_device *dev = intel_dp->base.base.dev; |
887 | unsigned long delay; | 918 | struct drm_i915_private *dev_priv = dev->dev_private; |
888 | 919 | ||
889 | DRM_DEBUG_KMS("Wait for panel power off time\n"); | 920 | DRM_DEBUG_KMS("mask %08x value %08x status %08x control %08x\n", |
921 | mask, value, | ||
922 | I915_READ(PCH_PP_STATUS), | ||
923 | I915_READ(PCH_PP_CONTROL)); | ||
890 | 924 | ||
891 | if (ironlake_edp_have_panel_power(intel_dp) || | 925 | if (_wait_for((I915_READ(PCH_PP_STATUS) & mask) == value, 5000, 10)) { |
892 | ironlake_edp_have_panel_vdd(intel_dp)) | 926 | DRM_ERROR("Panel status timeout: status %08x control %08x\n", |
893 | { | 927 | I915_READ(PCH_PP_STATUS), |
894 | DRM_DEBUG_KMS("Panel still on, no delay needed\n"); | 928 | I915_READ(PCH_PP_CONTROL)); |
895 | return; | ||
896 | } | 929 | } |
930 | } | ||
897 | 931 | ||
898 | off_time = intel_dp->panel_off_jiffies + msecs_to_jiffies(intel_dp->panel_power_down_delay); | 932 | static void ironlake_wait_panel_on(struct intel_dp *intel_dp) |
899 | if (time_after(jiffies, off_time)) { | 933 | { |
900 | DRM_DEBUG_KMS("Time already passed"); | 934 | DRM_DEBUG_KMS("Wait for panel power on\n"); |
901 | return; | 935 | ironlake_wait_panel_status(intel_dp, IDLE_ON_MASK, IDLE_ON_VALUE); |
902 | } | 936 | } |
903 | delay = jiffies_to_msecs(off_time - jiffies); | 937 | |
904 | if (delay > intel_dp->panel_power_down_delay) | 938 | static void ironlake_wait_panel_off(struct intel_dp *intel_dp) |
905 | delay = intel_dp->panel_power_down_delay; | 939 | { |
906 | DRM_DEBUG_KMS("Waiting an additional %ld ms\n", delay); | 940 | DRM_DEBUG_KMS("Wait for panel power off time\n"); |
907 | msleep(delay); | 941 | ironlake_wait_panel_status(intel_dp, IDLE_OFF_MASK, IDLE_OFF_VALUE); |
942 | } | ||
943 | |||
944 | static void ironlake_wait_panel_power_cycle(struct intel_dp *intel_dp) | ||
945 | { | ||
946 | DRM_DEBUG_KMS("Wait for panel power cycle\n"); | ||
947 | ironlake_wait_panel_status(intel_dp, IDLE_CYCLE_MASK, IDLE_CYCLE_VALUE); | ||
948 | } | ||
949 | |||
950 | |||
951 | /* Read the current pp_control value, unlocking the register if it | ||
952 | * is locked | ||
953 | */ | ||
954 | |||
955 | static u32 ironlake_get_pp_control(struct drm_i915_private *dev_priv) | ||
956 | { | ||
957 | u32 control = I915_READ(PCH_PP_CONTROL); | ||
958 | |||
959 | control &= ~PANEL_UNLOCK_MASK; | ||
960 | control |= PANEL_UNLOCK_REGS; | ||
961 | return control; | ||
908 | } | 962 | } |
909 | 963 | ||
910 | static void ironlake_edp_panel_vdd_on(struct intel_dp *intel_dp) | 964 | static void ironlake_edp_panel_vdd_on(struct intel_dp *intel_dp) |
@@ -921,15 +975,16 @@ static void ironlake_edp_panel_vdd_on(struct intel_dp *intel_dp) | |||
921 | "eDP VDD already requested on\n"); | 975 | "eDP VDD already requested on\n"); |
922 | 976 | ||
923 | intel_dp->want_panel_vdd = true; | 977 | intel_dp->want_panel_vdd = true; |
978 | |||
924 | if (ironlake_edp_have_panel_vdd(intel_dp)) { | 979 | if (ironlake_edp_have_panel_vdd(intel_dp)) { |
925 | DRM_DEBUG_KMS("eDP VDD already on\n"); | 980 | DRM_DEBUG_KMS("eDP VDD already on\n"); |
926 | return; | 981 | return; |
927 | } | 982 | } |
928 | 983 | ||
929 | ironlake_wait_panel_off(intel_dp); | 984 | if (!ironlake_edp_have_panel_power(intel_dp)) |
930 | pp = I915_READ(PCH_PP_CONTROL); | 985 | ironlake_wait_panel_power_cycle(intel_dp); |
931 | pp &= ~PANEL_UNLOCK_MASK; | 986 | |
932 | pp |= PANEL_UNLOCK_REGS; | 987 | pp = ironlake_get_pp_control(dev_priv); |
933 | pp |= EDP_FORCE_VDD; | 988 | pp |= EDP_FORCE_VDD; |
934 | I915_WRITE(PCH_PP_CONTROL, pp); | 989 | I915_WRITE(PCH_PP_CONTROL, pp); |
935 | POSTING_READ(PCH_PP_CONTROL); | 990 | POSTING_READ(PCH_PP_CONTROL); |
@@ -952,9 +1007,7 @@ static void ironlake_panel_vdd_off_sync(struct intel_dp *intel_dp) | |||
952 | u32 pp; | 1007 | u32 pp; |
953 | 1008 | ||
954 | if (!intel_dp->want_panel_vdd && ironlake_edp_have_panel_vdd(intel_dp)) { | 1009 | if (!intel_dp->want_panel_vdd && ironlake_edp_have_panel_vdd(intel_dp)) { |
955 | pp = I915_READ(PCH_PP_CONTROL); | 1010 | pp = ironlake_get_pp_control(dev_priv); |
956 | pp &= ~PANEL_UNLOCK_MASK; | ||
957 | pp |= PANEL_UNLOCK_REGS; | ||
958 | pp &= ~EDP_FORCE_VDD; | 1011 | pp &= ~EDP_FORCE_VDD; |
959 | I915_WRITE(PCH_PP_CONTROL, pp); | 1012 | I915_WRITE(PCH_PP_CONTROL, pp); |
960 | POSTING_READ(PCH_PP_CONTROL); | 1013 | POSTING_READ(PCH_PP_CONTROL); |
@@ -962,7 +1015,8 @@ static void ironlake_panel_vdd_off_sync(struct intel_dp *intel_dp) | |||
962 | /* Make sure sequencer is idle before allowing subsequent activity */ | 1015 | /* Make sure sequencer is idle before allowing subsequent activity */ |
963 | DRM_DEBUG_KMS("PCH_PP_STATUS: 0x%08x PCH_PP_CONTROL: 0x%08x\n", | 1016 | DRM_DEBUG_KMS("PCH_PP_STATUS: 0x%08x PCH_PP_CONTROL: 0x%08x\n", |
964 | I915_READ(PCH_PP_STATUS), I915_READ(PCH_PP_CONTROL)); | 1017 | I915_READ(PCH_PP_STATUS), I915_READ(PCH_PP_CONTROL)); |
965 | intel_dp->panel_off_jiffies = jiffies; | 1018 | |
1019 | msleep(intel_dp->panel_power_down_delay); | ||
966 | } | 1020 | } |
967 | } | 1021 | } |
968 | 1022 | ||
@@ -972,9 +1026,9 @@ static void ironlake_panel_vdd_work(struct work_struct *__work) | |||
972 | struct intel_dp, panel_vdd_work); | 1026 | struct intel_dp, panel_vdd_work); |
973 | struct drm_device *dev = intel_dp->base.base.dev; | 1027 | struct drm_device *dev = intel_dp->base.base.dev; |
974 | 1028 | ||
975 | mutex_lock(&dev->struct_mutex); | 1029 | mutex_lock(&dev->mode_config.mutex); |
976 | ironlake_panel_vdd_off_sync(intel_dp); | 1030 | ironlake_panel_vdd_off_sync(intel_dp); |
977 | mutex_unlock(&dev->struct_mutex); | 1031 | mutex_unlock(&dev->mode_config.mutex); |
978 | } | 1032 | } |
979 | 1033 | ||
980 | static void ironlake_edp_panel_vdd_off(struct intel_dp *intel_dp, bool sync) | 1034 | static void ironlake_edp_panel_vdd_off(struct intel_dp *intel_dp, bool sync) |
@@ -984,7 +1038,7 @@ static void ironlake_edp_panel_vdd_off(struct intel_dp *intel_dp, bool sync) | |||
984 | 1038 | ||
985 | DRM_DEBUG_KMS("Turn eDP VDD off %d\n", intel_dp->want_panel_vdd); | 1039 | DRM_DEBUG_KMS("Turn eDP VDD off %d\n", intel_dp->want_panel_vdd); |
986 | WARN(!intel_dp->want_panel_vdd, "eDP VDD not forced on"); | 1040 | WARN(!intel_dp->want_panel_vdd, "eDP VDD not forced on"); |
987 | 1041 | ||
988 | intel_dp->want_panel_vdd = false; | 1042 | intel_dp->want_panel_vdd = false; |
989 | 1043 | ||
990 | if (sync) { | 1044 | if (sync) { |
@@ -1000,23 +1054,25 @@ static void ironlake_edp_panel_vdd_off(struct intel_dp *intel_dp, bool sync) | |||
1000 | } | 1054 | } |
1001 | } | 1055 | } |
1002 | 1056 | ||
1003 | /* Returns true if the panel was already on when called */ | ||
1004 | static void ironlake_edp_panel_on(struct intel_dp *intel_dp) | 1057 | static void ironlake_edp_panel_on(struct intel_dp *intel_dp) |
1005 | { | 1058 | { |
1006 | struct drm_device *dev = intel_dp->base.base.dev; | 1059 | struct drm_device *dev = intel_dp->base.base.dev; |
1007 | struct drm_i915_private *dev_priv = dev->dev_private; | 1060 | struct drm_i915_private *dev_priv = dev->dev_private; |
1008 | u32 pp, idle_on_mask = PP_ON | PP_SEQUENCE_STATE_ON_IDLE; | 1061 | u32 pp; |
1009 | 1062 | ||
1010 | if (!is_edp(intel_dp)) | 1063 | if (!is_edp(intel_dp)) |
1011 | return; | 1064 | return; |
1012 | if (ironlake_edp_have_panel_power(intel_dp)) | 1065 | |
1066 | DRM_DEBUG_KMS("Turn eDP power on\n"); | ||
1067 | |||
1068 | if (ironlake_edp_have_panel_power(intel_dp)) { | ||
1069 | DRM_DEBUG_KMS("eDP power already on\n"); | ||
1013 | return; | 1070 | return; |
1071 | } | ||
1014 | 1072 | ||
1015 | ironlake_wait_panel_off(intel_dp); | 1073 | ironlake_wait_panel_power_cycle(intel_dp); |
1016 | pp = I915_READ(PCH_PP_CONTROL); | ||
1017 | pp &= ~PANEL_UNLOCK_MASK; | ||
1018 | pp |= PANEL_UNLOCK_REGS; | ||
1019 | 1074 | ||
1075 | pp = ironlake_get_pp_control(dev_priv); | ||
1020 | if (IS_GEN5(dev)) { | 1076 | if (IS_GEN5(dev)) { |
1021 | /* ILK workaround: disable reset around power sequence */ | 1077 | /* ILK workaround: disable reset around power sequence */ |
1022 | pp &= ~PANEL_POWER_RESET; | 1078 | pp &= ~PANEL_POWER_RESET; |
@@ -1025,13 +1081,13 @@ static void ironlake_edp_panel_on(struct intel_dp *intel_dp) | |||
1025 | } | 1081 | } |
1026 | 1082 | ||
1027 | pp |= POWER_TARGET_ON; | 1083 | pp |= POWER_TARGET_ON; |
1084 | if (!IS_GEN5(dev)) | ||
1085 | pp |= PANEL_POWER_RESET; | ||
1086 | |||
1028 | I915_WRITE(PCH_PP_CONTROL, pp); | 1087 | I915_WRITE(PCH_PP_CONTROL, pp); |
1029 | POSTING_READ(PCH_PP_CONTROL); | 1088 | POSTING_READ(PCH_PP_CONTROL); |
1030 | 1089 | ||
1031 | if (wait_for((I915_READ(PCH_PP_STATUS) & idle_on_mask) == idle_on_mask, | 1090 | ironlake_wait_panel_on(intel_dp); |
1032 | 5000)) | ||
1033 | DRM_ERROR("panel on wait timed out: 0x%08x\n", | ||
1034 | I915_READ(PCH_PP_STATUS)); | ||
1035 | 1091 | ||
1036 | if (IS_GEN5(dev)) { | 1092 | if (IS_GEN5(dev)) { |
1037 | pp |= PANEL_POWER_RESET; /* restore panel reset bit */ | 1093 | pp |= PANEL_POWER_RESET; /* restore panel reset bit */ |
@@ -1040,46 +1096,25 @@ static void ironlake_edp_panel_on(struct intel_dp *intel_dp) | |||
1040 | } | 1096 | } |
1041 | } | 1097 | } |
1042 | 1098 | ||
1043 | static void ironlake_edp_panel_off(struct drm_encoder *encoder) | 1099 | static void ironlake_edp_panel_off(struct intel_dp *intel_dp) |
1044 | { | 1100 | { |
1045 | struct intel_dp *intel_dp = enc_to_intel_dp(encoder); | 1101 | struct drm_device *dev = intel_dp->base.base.dev; |
1046 | struct drm_device *dev = encoder->dev; | ||
1047 | struct drm_i915_private *dev_priv = dev->dev_private; | 1102 | struct drm_i915_private *dev_priv = dev->dev_private; |
1048 | u32 pp, idle_off_mask = PP_ON | PP_SEQUENCE_MASK | | 1103 | u32 pp; |
1049 | PP_CYCLE_DELAY_ACTIVE | PP_SEQUENCE_STATE_MASK; | ||
1050 | 1104 | ||
1051 | if (!is_edp(intel_dp)) | 1105 | if (!is_edp(intel_dp)) |
1052 | return; | 1106 | return; |
1053 | pp = I915_READ(PCH_PP_CONTROL); | ||
1054 | pp &= ~PANEL_UNLOCK_MASK; | ||
1055 | pp |= PANEL_UNLOCK_REGS; | ||
1056 | 1107 | ||
1057 | if (IS_GEN5(dev)) { | 1108 | DRM_DEBUG_KMS("Turn eDP power off\n"); |
1058 | /* ILK workaround: disable reset around power sequence */ | ||
1059 | pp &= ~PANEL_POWER_RESET; | ||
1060 | I915_WRITE(PCH_PP_CONTROL, pp); | ||
1061 | POSTING_READ(PCH_PP_CONTROL); | ||
1062 | } | ||
1063 | 1109 | ||
1064 | intel_dp->panel_off_jiffies = jiffies; | 1110 | WARN(intel_dp->want_panel_vdd, "Cannot turn power off while VDD is on\n"); |
1065 | 1111 | ||
1066 | if (IS_GEN5(dev)) { | 1112 | pp = ironlake_get_pp_control(dev_priv); |
1067 | pp &= ~POWER_TARGET_ON; | 1113 | pp &= ~(POWER_TARGET_ON | EDP_FORCE_VDD | PANEL_POWER_RESET | EDP_BLC_ENABLE); |
1068 | I915_WRITE(PCH_PP_CONTROL, pp); | 1114 | I915_WRITE(PCH_PP_CONTROL, pp); |
1069 | POSTING_READ(PCH_PP_CONTROL); | 1115 | POSTING_READ(PCH_PP_CONTROL); |
1070 | pp &= ~POWER_TARGET_ON; | ||
1071 | I915_WRITE(PCH_PP_CONTROL, pp); | ||
1072 | POSTING_READ(PCH_PP_CONTROL); | ||
1073 | msleep(intel_dp->panel_power_cycle_delay); | ||
1074 | |||
1075 | if (wait_for((I915_READ(PCH_PP_STATUS) & idle_off_mask) == 0, 5000)) | ||
1076 | DRM_ERROR("panel off wait timed out: 0x%08x\n", | ||
1077 | I915_READ(PCH_PP_STATUS)); | ||
1078 | 1116 | ||
1079 | pp |= PANEL_POWER_RESET; /* restore panel reset bit */ | 1117 | ironlake_wait_panel_off(intel_dp); |
1080 | I915_WRITE(PCH_PP_CONTROL, pp); | ||
1081 | POSTING_READ(PCH_PP_CONTROL); | ||
1082 | } | ||
1083 | } | 1118 | } |
1084 | 1119 | ||
1085 | static void ironlake_edp_backlight_on(struct intel_dp *intel_dp) | 1120 | static void ironlake_edp_backlight_on(struct intel_dp *intel_dp) |
@@ -1099,9 +1134,7 @@ static void ironlake_edp_backlight_on(struct intel_dp *intel_dp) | |||
1099 | * allowing it to appear. | 1134 | * allowing it to appear. |
1100 | */ | 1135 | */ |
1101 | msleep(intel_dp->backlight_on_delay); | 1136 | msleep(intel_dp->backlight_on_delay); |
1102 | pp = I915_READ(PCH_PP_CONTROL); | 1137 | pp = ironlake_get_pp_control(dev_priv); |
1103 | pp &= ~PANEL_UNLOCK_MASK; | ||
1104 | pp |= PANEL_UNLOCK_REGS; | ||
1105 | pp |= EDP_BLC_ENABLE; | 1138 | pp |= EDP_BLC_ENABLE; |
1106 | I915_WRITE(PCH_PP_CONTROL, pp); | 1139 | I915_WRITE(PCH_PP_CONTROL, pp); |
1107 | POSTING_READ(PCH_PP_CONTROL); | 1140 | POSTING_READ(PCH_PP_CONTROL); |
@@ -1117,9 +1150,7 @@ static void ironlake_edp_backlight_off(struct intel_dp *intel_dp) | |||
1117 | return; | 1150 | return; |
1118 | 1151 | ||
1119 | DRM_DEBUG_KMS("\n"); | 1152 | DRM_DEBUG_KMS("\n"); |
1120 | pp = I915_READ(PCH_PP_CONTROL); | 1153 | pp = ironlake_get_pp_control(dev_priv); |
1121 | pp &= ~PANEL_UNLOCK_MASK; | ||
1122 | pp |= PANEL_UNLOCK_REGS; | ||
1123 | pp &= ~EDP_BLC_ENABLE; | 1154 | pp &= ~EDP_BLC_ENABLE; |
1124 | I915_WRITE(PCH_PP_CONTROL, pp); | 1155 | I915_WRITE(PCH_PP_CONTROL, pp); |
1125 | POSTING_READ(PCH_PP_CONTROL); | 1156 | POSTING_READ(PCH_PP_CONTROL); |
@@ -1187,17 +1218,18 @@ static void intel_dp_prepare(struct drm_encoder *encoder) | |||
1187 | { | 1218 | { |
1188 | struct intel_dp *intel_dp = enc_to_intel_dp(encoder); | 1219 | struct intel_dp *intel_dp = enc_to_intel_dp(encoder); |
1189 | 1220 | ||
1221 | ironlake_edp_backlight_off(intel_dp); | ||
1222 | ironlake_edp_panel_off(intel_dp); | ||
1223 | |||
1190 | /* Wake up the sink first */ | 1224 | /* Wake up the sink first */ |
1191 | ironlake_edp_panel_vdd_on(intel_dp); | 1225 | ironlake_edp_panel_vdd_on(intel_dp); |
1192 | intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON); | 1226 | intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON); |
1227 | intel_dp_link_down(intel_dp); | ||
1193 | ironlake_edp_panel_vdd_off(intel_dp, false); | 1228 | ironlake_edp_panel_vdd_off(intel_dp, false); |
1194 | 1229 | ||
1195 | /* Make sure the panel is off before trying to | 1230 | /* Make sure the panel is off before trying to |
1196 | * change the mode | 1231 | * change the mode |
1197 | */ | 1232 | */ |
1198 | ironlake_edp_backlight_off(intel_dp); | ||
1199 | intel_dp_link_down(intel_dp); | ||
1200 | ironlake_edp_panel_off(encoder); | ||
1201 | } | 1233 | } |
1202 | 1234 | ||
1203 | static void intel_dp_commit(struct drm_encoder *encoder) | 1235 | static void intel_dp_commit(struct drm_encoder *encoder) |
@@ -1211,7 +1243,6 @@ static void intel_dp_commit(struct drm_encoder *encoder) | |||
1211 | intel_dp_start_link_train(intel_dp); | 1243 | intel_dp_start_link_train(intel_dp); |
1212 | ironlake_edp_panel_on(intel_dp); | 1244 | ironlake_edp_panel_on(intel_dp); |
1213 | ironlake_edp_panel_vdd_off(intel_dp, true); | 1245 | ironlake_edp_panel_vdd_off(intel_dp, true); |
1214 | |||
1215 | intel_dp_complete_link_train(intel_dp); | 1246 | intel_dp_complete_link_train(intel_dp); |
1216 | ironlake_edp_backlight_on(intel_dp); | 1247 | ironlake_edp_backlight_on(intel_dp); |
1217 | 1248 | ||
@@ -1230,16 +1261,20 @@ intel_dp_dpms(struct drm_encoder *encoder, int mode) | |||
1230 | uint32_t dp_reg = I915_READ(intel_dp->output_reg); | 1261 | uint32_t dp_reg = I915_READ(intel_dp->output_reg); |
1231 | 1262 | ||
1232 | if (mode != DRM_MODE_DPMS_ON) { | 1263 | if (mode != DRM_MODE_DPMS_ON) { |
1264 | ironlake_edp_backlight_off(intel_dp); | ||
1265 | ironlake_edp_panel_off(intel_dp); | ||
1266 | |||
1233 | ironlake_edp_panel_vdd_on(intel_dp); | 1267 | ironlake_edp_panel_vdd_on(intel_dp); |
1234 | if (is_edp(intel_dp)) | ||
1235 | ironlake_edp_backlight_off(intel_dp); | ||
1236 | intel_dp_sink_dpms(intel_dp, mode); | 1268 | intel_dp_sink_dpms(intel_dp, mode); |
1237 | intel_dp_link_down(intel_dp); | 1269 | intel_dp_link_down(intel_dp); |
1238 | ironlake_edp_panel_off(encoder); | ||
1239 | if (is_edp(intel_dp) && !is_pch_edp(intel_dp)) | ||
1240 | ironlake_edp_pll_off(encoder); | ||
1241 | ironlake_edp_panel_vdd_off(intel_dp, false); | 1270 | ironlake_edp_panel_vdd_off(intel_dp, false); |
1271 | |||
1272 | if (is_cpu_edp(intel_dp)) | ||
1273 | ironlake_edp_pll_off(encoder); | ||
1242 | } else { | 1274 | } else { |
1275 | if (is_cpu_edp(intel_dp)) | ||
1276 | ironlake_edp_pll_on(encoder); | ||
1277 | |||
1243 | ironlake_edp_panel_vdd_on(intel_dp); | 1278 | ironlake_edp_panel_vdd_on(intel_dp); |
1244 | intel_dp_sink_dpms(intel_dp, mode); | 1279 | intel_dp_sink_dpms(intel_dp, mode); |
1245 | if (!(dp_reg & DP_PORT_EN)) { | 1280 | if (!(dp_reg & DP_PORT_EN)) { |
@@ -1247,7 +1282,6 @@ intel_dp_dpms(struct drm_encoder *encoder, int mode) | |||
1247 | ironlake_edp_panel_on(intel_dp); | 1282 | ironlake_edp_panel_on(intel_dp); |
1248 | ironlake_edp_panel_vdd_off(intel_dp, true); | 1283 | ironlake_edp_panel_vdd_off(intel_dp, true); |
1249 | intel_dp_complete_link_train(intel_dp); | 1284 | intel_dp_complete_link_train(intel_dp); |
1250 | ironlake_edp_backlight_on(intel_dp); | ||
1251 | } else | 1285 | } else |
1252 | ironlake_edp_panel_vdd_off(intel_dp, false); | 1286 | ironlake_edp_panel_vdd_off(intel_dp, false); |
1253 | ironlake_edp_backlight_on(intel_dp); | 1287 | ironlake_edp_backlight_on(intel_dp); |
@@ -1285,11 +1319,11 @@ intel_dp_aux_native_read_retry(struct intel_dp *intel_dp, uint16_t address, | |||
1285 | * link status information | 1319 | * link status information |
1286 | */ | 1320 | */ |
1287 | static bool | 1321 | static bool |
1288 | intel_dp_get_link_status(struct intel_dp *intel_dp) | 1322 | intel_dp_get_link_status(struct intel_dp *intel_dp, uint8_t link_status[DP_LINK_STATUS_SIZE]) |
1289 | { | 1323 | { |
1290 | return intel_dp_aux_native_read_retry(intel_dp, | 1324 | return intel_dp_aux_native_read_retry(intel_dp, |
1291 | DP_LANE0_1_STATUS, | 1325 | DP_LANE0_1_STATUS, |
1292 | intel_dp->link_status, | 1326 | link_status, |
1293 | DP_LINK_STATUS_SIZE); | 1327 | DP_LINK_STATUS_SIZE); |
1294 | } | 1328 | } |
1295 | 1329 | ||
@@ -1301,27 +1335,25 @@ intel_dp_link_status(uint8_t link_status[DP_LINK_STATUS_SIZE], | |||
1301 | } | 1335 | } |
1302 | 1336 | ||
1303 | static uint8_t | 1337 | static uint8_t |
1304 | intel_get_adjust_request_voltage(uint8_t link_status[DP_LINK_STATUS_SIZE], | 1338 | intel_get_adjust_request_voltage(uint8_t adjust_request[2], |
1305 | int lane) | 1339 | int lane) |
1306 | { | 1340 | { |
1307 | int i = DP_ADJUST_REQUEST_LANE0_1 + (lane >> 1); | ||
1308 | int s = ((lane & 1) ? | 1341 | int s = ((lane & 1) ? |
1309 | DP_ADJUST_VOLTAGE_SWING_LANE1_SHIFT : | 1342 | DP_ADJUST_VOLTAGE_SWING_LANE1_SHIFT : |
1310 | DP_ADJUST_VOLTAGE_SWING_LANE0_SHIFT); | 1343 | DP_ADJUST_VOLTAGE_SWING_LANE0_SHIFT); |
1311 | uint8_t l = intel_dp_link_status(link_status, i); | 1344 | uint8_t l = adjust_request[lane>>1]; |
1312 | 1345 | ||
1313 | return ((l >> s) & 3) << DP_TRAIN_VOLTAGE_SWING_SHIFT; | 1346 | return ((l >> s) & 3) << DP_TRAIN_VOLTAGE_SWING_SHIFT; |
1314 | } | 1347 | } |
1315 | 1348 | ||
1316 | static uint8_t | 1349 | static uint8_t |
1317 | intel_get_adjust_request_pre_emphasis(uint8_t link_status[DP_LINK_STATUS_SIZE], | 1350 | intel_get_adjust_request_pre_emphasis(uint8_t adjust_request[2], |
1318 | int lane) | 1351 | int lane) |
1319 | { | 1352 | { |
1320 | int i = DP_ADJUST_REQUEST_LANE0_1 + (lane >> 1); | ||
1321 | int s = ((lane & 1) ? | 1353 | int s = ((lane & 1) ? |
1322 | DP_ADJUST_PRE_EMPHASIS_LANE1_SHIFT : | 1354 | DP_ADJUST_PRE_EMPHASIS_LANE1_SHIFT : |
1323 | DP_ADJUST_PRE_EMPHASIS_LANE0_SHIFT); | 1355 | DP_ADJUST_PRE_EMPHASIS_LANE0_SHIFT); |
1324 | uint8_t l = intel_dp_link_status(link_status, i); | 1356 | uint8_t l = adjust_request[lane>>1]; |
1325 | 1357 | ||
1326 | return ((l >> s) & 3) << DP_TRAIN_PRE_EMPHASIS_SHIFT; | 1358 | return ((l >> s) & 3) << DP_TRAIN_PRE_EMPHASIS_SHIFT; |
1327 | } | 1359 | } |
@@ -1344,6 +1376,7 @@ static char *link_train_names[] = { | |||
1344 | * a maximum voltage of 800mV and a maximum pre-emphasis of 6dB | 1376 | * a maximum voltage of 800mV and a maximum pre-emphasis of 6dB |
1345 | */ | 1377 | */ |
1346 | #define I830_DP_VOLTAGE_MAX DP_TRAIN_VOLTAGE_SWING_800 | 1378 | #define I830_DP_VOLTAGE_MAX DP_TRAIN_VOLTAGE_SWING_800 |
1379 | #define I830_DP_VOLTAGE_MAX_CPT DP_TRAIN_VOLTAGE_SWING_1200 | ||
1347 | 1380 | ||
1348 | static uint8_t | 1381 | static uint8_t |
1349 | intel_dp_pre_emphasis_max(uint8_t voltage_swing) | 1382 | intel_dp_pre_emphasis_max(uint8_t voltage_swing) |
@@ -1362,15 +1395,18 @@ intel_dp_pre_emphasis_max(uint8_t voltage_swing) | |||
1362 | } | 1395 | } |
1363 | 1396 | ||
1364 | static void | 1397 | static void |
1365 | intel_get_adjust_train(struct intel_dp *intel_dp) | 1398 | intel_get_adjust_train(struct intel_dp *intel_dp, uint8_t link_status[DP_LINK_STATUS_SIZE]) |
1366 | { | 1399 | { |
1400 | struct drm_device *dev = intel_dp->base.base.dev; | ||
1367 | uint8_t v = 0; | 1401 | uint8_t v = 0; |
1368 | uint8_t p = 0; | 1402 | uint8_t p = 0; |
1369 | int lane; | 1403 | int lane; |
1404 | uint8_t *adjust_request = link_status + (DP_ADJUST_REQUEST_LANE0_1 - DP_LANE0_1_STATUS); | ||
1405 | int voltage_max; | ||
1370 | 1406 | ||
1371 | for (lane = 0; lane < intel_dp->lane_count; lane++) { | 1407 | for (lane = 0; lane < intel_dp->lane_count; lane++) { |
1372 | uint8_t this_v = intel_get_adjust_request_voltage(intel_dp->link_status, lane); | 1408 | uint8_t this_v = intel_get_adjust_request_voltage(adjust_request, lane); |
1373 | uint8_t this_p = intel_get_adjust_request_pre_emphasis(intel_dp->link_status, lane); | 1409 | uint8_t this_p = intel_get_adjust_request_pre_emphasis(adjust_request, lane); |
1374 | 1410 | ||
1375 | if (this_v > v) | 1411 | if (this_v > v) |
1376 | v = this_v; | 1412 | v = this_v; |
@@ -1378,8 +1414,12 @@ intel_get_adjust_train(struct intel_dp *intel_dp) | |||
1378 | p = this_p; | 1414 | p = this_p; |
1379 | } | 1415 | } |
1380 | 1416 | ||
1381 | if (v >= I830_DP_VOLTAGE_MAX) | 1417 | if (HAS_PCH_CPT(dev) && !is_cpu_edp(intel_dp)) |
1382 | v = I830_DP_VOLTAGE_MAX | DP_TRAIN_MAX_SWING_REACHED; | 1418 | voltage_max = I830_DP_VOLTAGE_MAX_CPT; |
1419 | else | ||
1420 | voltage_max = I830_DP_VOLTAGE_MAX; | ||
1421 | if (v >= voltage_max) | ||
1422 | v = voltage_max | DP_TRAIN_MAX_SWING_REACHED; | ||
1383 | 1423 | ||
1384 | if (p >= intel_dp_pre_emphasis_max(v)) | 1424 | if (p >= intel_dp_pre_emphasis_max(v)) |
1385 | p = intel_dp_pre_emphasis_max(v) | DP_TRAIN_MAX_PRE_EMPHASIS_REACHED; | 1425 | p = intel_dp_pre_emphasis_max(v) | DP_TRAIN_MAX_PRE_EMPHASIS_REACHED; |
@@ -1389,7 +1429,7 @@ intel_get_adjust_train(struct intel_dp *intel_dp) | |||
1389 | } | 1429 | } |
1390 | 1430 | ||
1391 | static uint32_t | 1431 | static uint32_t |
1392 | intel_dp_signal_levels(uint8_t train_set, int lane_count) | 1432 | intel_dp_signal_levels(uint8_t train_set) |
1393 | { | 1433 | { |
1394 | uint32_t signal_levels = 0; | 1434 | uint32_t signal_levels = 0; |
1395 | 1435 | ||
@@ -1458,9 +1498,8 @@ static uint8_t | |||
1458 | intel_get_lane_status(uint8_t link_status[DP_LINK_STATUS_SIZE], | 1498 | intel_get_lane_status(uint8_t link_status[DP_LINK_STATUS_SIZE], |
1459 | int lane) | 1499 | int lane) |
1460 | { | 1500 | { |
1461 | int i = DP_LANE0_1_STATUS + (lane >> 1); | ||
1462 | int s = (lane & 1) * 4; | 1501 | int s = (lane & 1) * 4; |
1463 | uint8_t l = intel_dp_link_status(link_status, i); | 1502 | uint8_t l = link_status[lane>>1]; |
1464 | 1503 | ||
1465 | return (l >> s) & 0xf; | 1504 | return (l >> s) & 0xf; |
1466 | } | 1505 | } |
@@ -1485,18 +1524,18 @@ intel_clock_recovery_ok(uint8_t link_status[DP_LINK_STATUS_SIZE], int lane_count | |||
1485 | DP_LANE_CHANNEL_EQ_DONE|\ | 1524 | DP_LANE_CHANNEL_EQ_DONE|\ |
1486 | DP_LANE_SYMBOL_LOCKED) | 1525 | DP_LANE_SYMBOL_LOCKED) |
1487 | static bool | 1526 | static bool |
1488 | intel_channel_eq_ok(struct intel_dp *intel_dp) | 1527 | intel_channel_eq_ok(struct intel_dp *intel_dp, uint8_t link_status[DP_LINK_STATUS_SIZE]) |
1489 | { | 1528 | { |
1490 | uint8_t lane_align; | 1529 | uint8_t lane_align; |
1491 | uint8_t lane_status; | 1530 | uint8_t lane_status; |
1492 | int lane; | 1531 | int lane; |
1493 | 1532 | ||
1494 | lane_align = intel_dp_link_status(intel_dp->link_status, | 1533 | lane_align = intel_dp_link_status(link_status, |
1495 | DP_LANE_ALIGN_STATUS_UPDATED); | 1534 | DP_LANE_ALIGN_STATUS_UPDATED); |
1496 | if ((lane_align & DP_INTERLANE_ALIGN_DONE) == 0) | 1535 | if ((lane_align & DP_INTERLANE_ALIGN_DONE) == 0) |
1497 | return false; | 1536 | return false; |
1498 | for (lane = 0; lane < intel_dp->lane_count; lane++) { | 1537 | for (lane = 0; lane < intel_dp->lane_count; lane++) { |
1499 | lane_status = intel_get_lane_status(intel_dp->link_status, lane); | 1538 | lane_status = intel_get_lane_status(link_status, lane); |
1500 | if ((lane_status & CHANNEL_EQ_BITS) != CHANNEL_EQ_BITS) | 1539 | if ((lane_status & CHANNEL_EQ_BITS) != CHANNEL_EQ_BITS) |
1501 | return false; | 1540 | return false; |
1502 | } | 1541 | } |
@@ -1521,8 +1560,9 @@ intel_dp_set_link_train(struct intel_dp *intel_dp, | |||
1521 | 1560 | ||
1522 | ret = intel_dp_aux_native_write(intel_dp, | 1561 | ret = intel_dp_aux_native_write(intel_dp, |
1523 | DP_TRAINING_LANE0_SET, | 1562 | DP_TRAINING_LANE0_SET, |
1524 | intel_dp->train_set, 4); | 1563 | intel_dp->train_set, |
1525 | if (ret != 4) | 1564 | intel_dp->lane_count); |
1565 | if (ret != intel_dp->lane_count) | ||
1526 | return false; | 1566 | return false; |
1527 | 1567 | ||
1528 | return true; | 1568 | return true; |
@@ -1538,7 +1578,7 @@ intel_dp_start_link_train(struct intel_dp *intel_dp) | |||
1538 | int i; | 1578 | int i; |
1539 | uint8_t voltage; | 1579 | uint8_t voltage; |
1540 | bool clock_recovery = false; | 1580 | bool clock_recovery = false; |
1541 | int tries; | 1581 | int voltage_tries, loop_tries; |
1542 | u32 reg; | 1582 | u32 reg; |
1543 | uint32_t DP = intel_dp->DP; | 1583 | uint32_t DP = intel_dp->DP; |
1544 | 1584 | ||
@@ -1565,16 +1605,20 @@ intel_dp_start_link_train(struct intel_dp *intel_dp) | |||
1565 | DP &= ~DP_LINK_TRAIN_MASK; | 1605 | DP &= ~DP_LINK_TRAIN_MASK; |
1566 | memset(intel_dp->train_set, 0, 4); | 1606 | memset(intel_dp->train_set, 0, 4); |
1567 | voltage = 0xff; | 1607 | voltage = 0xff; |
1568 | tries = 0; | 1608 | voltage_tries = 0; |
1609 | loop_tries = 0; | ||
1569 | clock_recovery = false; | 1610 | clock_recovery = false; |
1570 | for (;;) { | 1611 | for (;;) { |
1571 | /* Use intel_dp->train_set[0] to set the voltage and pre emphasis values */ | 1612 | /* Use intel_dp->train_set[0] to set the voltage and pre emphasis values */ |
1613 | uint8_t link_status[DP_LINK_STATUS_SIZE]; | ||
1572 | uint32_t signal_levels; | 1614 | uint32_t signal_levels; |
1573 | if (IS_GEN6(dev) && is_edp(intel_dp)) { | 1615 | |
1616 | if (IS_GEN6(dev) && is_cpu_edp(intel_dp)) { | ||
1574 | signal_levels = intel_gen6_edp_signal_levels(intel_dp->train_set[0]); | 1617 | signal_levels = intel_gen6_edp_signal_levels(intel_dp->train_set[0]); |
1575 | DP = (DP & ~EDP_LINK_TRAIN_VOL_EMP_MASK_SNB) | signal_levels; | 1618 | DP = (DP & ~EDP_LINK_TRAIN_VOL_EMP_MASK_SNB) | signal_levels; |
1576 | } else { | 1619 | } else { |
1577 | signal_levels = intel_dp_signal_levels(intel_dp->train_set[0], intel_dp->lane_count); | 1620 | signal_levels = intel_dp_signal_levels(intel_dp->train_set[0]); |
1621 | DRM_DEBUG_KMS("training pattern 1 signal levels %08x\n", signal_levels); | ||
1578 | DP = (DP & ~(DP_VOLTAGE_MASK|DP_PRE_EMPHASIS_MASK)) | signal_levels; | 1622 | DP = (DP & ~(DP_VOLTAGE_MASK|DP_PRE_EMPHASIS_MASK)) | signal_levels; |
1579 | } | 1623 | } |
1580 | 1624 | ||
@@ -1590,10 +1634,13 @@ intel_dp_start_link_train(struct intel_dp *intel_dp) | |||
1590 | /* Set training pattern 1 */ | 1634 | /* Set training pattern 1 */ |
1591 | 1635 | ||
1592 | udelay(100); | 1636 | udelay(100); |
1593 | if (!intel_dp_get_link_status(intel_dp)) | 1637 | if (!intel_dp_get_link_status(intel_dp, link_status)) { |
1638 | DRM_ERROR("failed to get link status\n"); | ||
1594 | break; | 1639 | break; |
1640 | } | ||
1595 | 1641 | ||
1596 | if (intel_clock_recovery_ok(intel_dp->link_status, intel_dp->lane_count)) { | 1642 | if (intel_clock_recovery_ok(link_status, intel_dp->lane_count)) { |
1643 | DRM_DEBUG_KMS("clock recovery OK\n"); | ||
1597 | clock_recovery = true; | 1644 | clock_recovery = true; |
1598 | break; | 1645 | break; |
1599 | } | 1646 | } |
@@ -1602,20 +1649,30 @@ intel_dp_start_link_train(struct intel_dp *intel_dp) | |||
1602 | for (i = 0; i < intel_dp->lane_count; i++) | 1649 | for (i = 0; i < intel_dp->lane_count; i++) |
1603 | if ((intel_dp->train_set[i] & DP_TRAIN_MAX_SWING_REACHED) == 0) | 1650 | if ((intel_dp->train_set[i] & DP_TRAIN_MAX_SWING_REACHED) == 0) |
1604 | break; | 1651 | break; |
1605 | if (i == intel_dp->lane_count) | 1652 | if (i == intel_dp->lane_count) { |
1606 | break; | 1653 | ++loop_tries; |
1654 | if (loop_tries == 5) { | ||
1655 | DRM_DEBUG_KMS("too many full retries, give up\n"); | ||
1656 | break; | ||
1657 | } | ||
1658 | memset(intel_dp->train_set, 0, 4); | ||
1659 | voltage_tries = 0; | ||
1660 | continue; | ||
1661 | } | ||
1607 | 1662 | ||
1608 | /* Check to see if we've tried the same voltage 5 times */ | 1663 | /* Check to see if we've tried the same voltage 5 times */ |
1609 | if ((intel_dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK) == voltage) { | 1664 | if ((intel_dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK) == voltage) { |
1610 | ++tries; | 1665 | ++voltage_tries; |
1611 | if (tries == 5) | 1666 | if (voltage_tries == 5) { |
1667 | DRM_DEBUG_KMS("too many voltage retries, give up\n"); | ||
1612 | break; | 1668 | break; |
1669 | } | ||
1613 | } else | 1670 | } else |
1614 | tries = 0; | 1671 | voltage_tries = 0; |
1615 | voltage = intel_dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK; | 1672 | voltage = intel_dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK; |
1616 | 1673 | ||
1617 | /* Compute new intel_dp->train_set as requested by target */ | 1674 | /* Compute new intel_dp->train_set as requested by target */ |
1618 | intel_get_adjust_train(intel_dp); | 1675 | intel_get_adjust_train(intel_dp, link_status); |
1619 | } | 1676 | } |
1620 | 1677 | ||
1621 | intel_dp->DP = DP; | 1678 | intel_dp->DP = DP; |
@@ -1638,6 +1695,7 @@ intel_dp_complete_link_train(struct intel_dp *intel_dp) | |||
1638 | for (;;) { | 1695 | for (;;) { |
1639 | /* Use intel_dp->train_set[0] to set the voltage and pre emphasis values */ | 1696 | /* Use intel_dp->train_set[0] to set the voltage and pre emphasis values */ |
1640 | uint32_t signal_levels; | 1697 | uint32_t signal_levels; |
1698 | uint8_t link_status[DP_LINK_STATUS_SIZE]; | ||
1641 | 1699 | ||
1642 | if (cr_tries > 5) { | 1700 | if (cr_tries > 5) { |
1643 | DRM_ERROR("failed to train DP, aborting\n"); | 1701 | DRM_ERROR("failed to train DP, aborting\n"); |
@@ -1645,11 +1703,11 @@ intel_dp_complete_link_train(struct intel_dp *intel_dp) | |||
1645 | break; | 1703 | break; |
1646 | } | 1704 | } |
1647 | 1705 | ||
1648 | if (IS_GEN6(dev) && is_edp(intel_dp)) { | 1706 | if (IS_GEN6(dev) && is_cpu_edp(intel_dp)) { |
1649 | signal_levels = intel_gen6_edp_signal_levels(intel_dp->train_set[0]); | 1707 | signal_levels = intel_gen6_edp_signal_levels(intel_dp->train_set[0]); |
1650 | DP = (DP & ~EDP_LINK_TRAIN_VOL_EMP_MASK_SNB) | signal_levels; | 1708 | DP = (DP & ~EDP_LINK_TRAIN_VOL_EMP_MASK_SNB) | signal_levels; |
1651 | } else { | 1709 | } else { |
1652 | signal_levels = intel_dp_signal_levels(intel_dp->train_set[0], intel_dp->lane_count); | 1710 | signal_levels = intel_dp_signal_levels(intel_dp->train_set[0]); |
1653 | DP = (DP & ~(DP_VOLTAGE_MASK|DP_PRE_EMPHASIS_MASK)) | signal_levels; | 1711 | DP = (DP & ~(DP_VOLTAGE_MASK|DP_PRE_EMPHASIS_MASK)) | signal_levels; |
1654 | } | 1712 | } |
1655 | 1713 | ||
@@ -1665,17 +1723,17 @@ intel_dp_complete_link_train(struct intel_dp *intel_dp) | |||
1665 | break; | 1723 | break; |
1666 | 1724 | ||
1667 | udelay(400); | 1725 | udelay(400); |
1668 | if (!intel_dp_get_link_status(intel_dp)) | 1726 | if (!intel_dp_get_link_status(intel_dp, link_status)) |
1669 | break; | 1727 | break; |
1670 | 1728 | ||
1671 | /* Make sure clock is still ok */ | 1729 | /* Make sure clock is still ok */ |
1672 | if (!intel_clock_recovery_ok(intel_dp->link_status, intel_dp->lane_count)) { | 1730 | if (!intel_clock_recovery_ok(link_status, intel_dp->lane_count)) { |
1673 | intel_dp_start_link_train(intel_dp); | 1731 | intel_dp_start_link_train(intel_dp); |
1674 | cr_tries++; | 1732 | cr_tries++; |
1675 | continue; | 1733 | continue; |
1676 | } | 1734 | } |
1677 | 1735 | ||
1678 | if (intel_channel_eq_ok(intel_dp)) { | 1736 | if (intel_channel_eq_ok(intel_dp, link_status)) { |
1679 | channel_eq = true; | 1737 | channel_eq = true; |
1680 | break; | 1738 | break; |
1681 | } | 1739 | } |
@@ -1690,7 +1748,7 @@ intel_dp_complete_link_train(struct intel_dp *intel_dp) | |||
1690 | } | 1748 | } |
1691 | 1749 | ||
1692 | /* Compute new intel_dp->train_set as requested by target */ | 1750 | /* Compute new intel_dp->train_set as requested by target */ |
1693 | intel_get_adjust_train(intel_dp); | 1751 | intel_get_adjust_train(intel_dp, link_status); |
1694 | ++tries; | 1752 | ++tries; |
1695 | } | 1753 | } |
1696 | 1754 | ||
@@ -1735,8 +1793,12 @@ intel_dp_link_down(struct intel_dp *intel_dp) | |||
1735 | 1793 | ||
1736 | msleep(17); | 1794 | msleep(17); |
1737 | 1795 | ||
1738 | if (is_edp(intel_dp)) | 1796 | if (is_edp(intel_dp)) { |
1739 | DP |= DP_LINK_TRAIN_OFF; | 1797 | if (HAS_PCH_CPT(dev) && !is_cpu_edp(intel_dp)) |
1798 | DP |= DP_LINK_TRAIN_OFF_CPT; | ||
1799 | else | ||
1800 | DP |= DP_LINK_TRAIN_OFF; | ||
1801 | } | ||
1740 | 1802 | ||
1741 | if (!HAS_PCH_CPT(dev) && | 1803 | if (!HAS_PCH_CPT(dev) && |
1742 | I915_READ(intel_dp->output_reg) & DP_PIPEB_SELECT) { | 1804 | I915_READ(intel_dp->output_reg) & DP_PIPEB_SELECT) { |
@@ -1822,6 +1884,7 @@ static void | |||
1822 | intel_dp_check_link_status(struct intel_dp *intel_dp) | 1884 | intel_dp_check_link_status(struct intel_dp *intel_dp) |
1823 | { | 1885 | { |
1824 | u8 sink_irq_vector; | 1886 | u8 sink_irq_vector; |
1887 | u8 link_status[DP_LINK_STATUS_SIZE]; | ||
1825 | 1888 | ||
1826 | if (intel_dp->dpms_mode != DRM_MODE_DPMS_ON) | 1889 | if (intel_dp->dpms_mode != DRM_MODE_DPMS_ON) |
1827 | return; | 1890 | return; |
@@ -1830,7 +1893,7 @@ intel_dp_check_link_status(struct intel_dp *intel_dp) | |||
1830 | return; | 1893 | return; |
1831 | 1894 | ||
1832 | /* Try to read receiver status if the link appears to be up */ | 1895 | /* Try to read receiver status if the link appears to be up */ |
1833 | if (!intel_dp_get_link_status(intel_dp)) { | 1896 | if (!intel_dp_get_link_status(intel_dp, link_status)) { |
1834 | intel_dp_link_down(intel_dp); | 1897 | intel_dp_link_down(intel_dp); |
1835 | return; | 1898 | return; |
1836 | } | 1899 | } |
@@ -1855,7 +1918,7 @@ intel_dp_check_link_status(struct intel_dp *intel_dp) | |||
1855 | DRM_DEBUG_DRIVER("CP or sink specific irq unhandled\n"); | 1918 | DRM_DEBUG_DRIVER("CP or sink specific irq unhandled\n"); |
1856 | } | 1919 | } |
1857 | 1920 | ||
1858 | if (!intel_channel_eq_ok(intel_dp)) { | 1921 | if (!intel_channel_eq_ok(intel_dp, link_status)) { |
1859 | DRM_DEBUG_KMS("%s: channel EQ not ok, retraining\n", | 1922 | DRM_DEBUG_KMS("%s: channel EQ not ok, retraining\n", |
1860 | drm_get_encoder_name(&intel_dp->base.base)); | 1923 | drm_get_encoder_name(&intel_dp->base.base)); |
1861 | intel_dp_start_link_train(intel_dp); | 1924 | intel_dp_start_link_train(intel_dp); |
@@ -2179,7 +2242,8 @@ intel_trans_dp_port_sel(struct drm_crtc *crtc) | |||
2179 | continue; | 2242 | continue; |
2180 | 2243 | ||
2181 | intel_dp = enc_to_intel_dp(encoder); | 2244 | intel_dp = enc_to_intel_dp(encoder); |
2182 | if (intel_dp->base.type == INTEL_OUTPUT_DISPLAYPORT) | 2245 | if (intel_dp->base.type == INTEL_OUTPUT_DISPLAYPORT || |
2246 | intel_dp->base.type == INTEL_OUTPUT_EDP) | ||
2183 | return intel_dp->output_reg; | 2247 | return intel_dp->output_reg; |
2184 | } | 2248 | } |
2185 | 2249 | ||
@@ -2321,7 +2385,7 @@ intel_dp_init(struct drm_device *dev, int output_reg) | |||
2321 | 2385 | ||
2322 | cur.t8 = (pp_on & PANEL_LIGHT_ON_DELAY_MASK) >> | 2386 | cur.t8 = (pp_on & PANEL_LIGHT_ON_DELAY_MASK) >> |
2323 | PANEL_LIGHT_ON_DELAY_SHIFT; | 2387 | PANEL_LIGHT_ON_DELAY_SHIFT; |
2324 | 2388 | ||
2325 | cur.t9 = (pp_off & PANEL_LIGHT_OFF_DELAY_MASK) >> | 2389 | cur.t9 = (pp_off & PANEL_LIGHT_OFF_DELAY_MASK) >> |
2326 | PANEL_LIGHT_OFF_DELAY_SHIFT; | 2390 | PANEL_LIGHT_OFF_DELAY_SHIFT; |
2327 | 2391 | ||
@@ -2354,11 +2418,10 @@ intel_dp_init(struct drm_device *dev, int output_reg) | |||
2354 | DRM_DEBUG_KMS("backlight on delay %d, off delay %d\n", | 2418 | DRM_DEBUG_KMS("backlight on delay %d, off delay %d\n", |
2355 | intel_dp->backlight_on_delay, intel_dp->backlight_off_delay); | 2419 | intel_dp->backlight_on_delay, intel_dp->backlight_off_delay); |
2356 | 2420 | ||
2357 | intel_dp->panel_off_jiffies = jiffies - intel_dp->panel_power_down_delay; | ||
2358 | |||
2359 | ironlake_edp_panel_vdd_on(intel_dp); | 2421 | ironlake_edp_panel_vdd_on(intel_dp); |
2360 | ret = intel_dp_get_dpcd(intel_dp); | 2422 | ret = intel_dp_get_dpcd(intel_dp); |
2361 | ironlake_edp_panel_vdd_off(intel_dp, false); | 2423 | ironlake_edp_panel_vdd_off(intel_dp, false); |
2424 | |||
2362 | if (ret) { | 2425 | if (ret) { |
2363 | if (intel_dp->dpcd[DP_DPCD_REV] >= 0x11) | 2426 | if (intel_dp->dpcd[DP_DPCD_REV] >= 0x11) |
2364 | dev_priv->no_aux_handshake = | 2427 | dev_priv->no_aux_handshake = |
diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c index 499d4c0dbeeb..21f60b7d69a3 100644 --- a/drivers/gpu/drm/i915/intel_panel.c +++ b/drivers/gpu/drm/i915/intel_panel.c | |||
@@ -326,7 +326,8 @@ static int intel_panel_update_status(struct backlight_device *bd) | |||
326 | static int intel_panel_get_brightness(struct backlight_device *bd) | 326 | static int intel_panel_get_brightness(struct backlight_device *bd) |
327 | { | 327 | { |
328 | struct drm_device *dev = bl_get_data(bd); | 328 | struct drm_device *dev = bl_get_data(bd); |
329 | return intel_panel_get_backlight(dev); | 329 | struct drm_i915_private *dev_priv = dev->dev_private; |
330 | return dev_priv->backlight_level; | ||
330 | } | 331 | } |
331 | 332 | ||
332 | static const struct backlight_ops intel_panel_bl_ops = { | 333 | static const struct backlight_ops intel_panel_bl_ops = { |
diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.c b/drivers/gpu/drm/nouveau/nouveau_bios.c index 032a82098136..5fc201b49d30 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bios.c +++ b/drivers/gpu/drm/nouveau/nouveau_bios.c | |||
@@ -640,10 +640,9 @@ static int | |||
640 | nv50_pll_set(struct drm_device *dev, uint32_t reg, uint32_t clk) | 640 | nv50_pll_set(struct drm_device *dev, uint32_t reg, uint32_t clk) |
641 | { | 641 | { |
642 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 642 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
643 | uint32_t reg0 = nv_rd32(dev, reg + 0); | ||
644 | uint32_t reg1 = nv_rd32(dev, reg + 4); | ||
645 | struct nouveau_pll_vals pll; | 643 | struct nouveau_pll_vals pll; |
646 | struct pll_lims pll_limits; | 644 | struct pll_lims pll_limits; |
645 | u32 ctrl, mask, coef; | ||
647 | int ret; | 646 | int ret; |
648 | 647 | ||
649 | ret = get_pll_limits(dev, reg, &pll_limits); | 648 | ret = get_pll_limits(dev, reg, &pll_limits); |
@@ -654,15 +653,20 @@ nv50_pll_set(struct drm_device *dev, uint32_t reg, uint32_t clk) | |||
654 | if (!clk) | 653 | if (!clk) |
655 | return -ERANGE; | 654 | return -ERANGE; |
656 | 655 | ||
657 | reg0 = (reg0 & 0xfff8ffff) | (pll.log2P << 16); | 656 | coef = pll.N1 << 8 | pll.M1; |
658 | reg1 = (reg1 & 0xffff0000) | (pll.N1 << 8) | pll.M1; | 657 | ctrl = pll.log2P << 16; |
659 | 658 | mask = 0x00070000; | |
660 | if (dev_priv->vbios.execute) { | 659 | if (reg == 0x004008) { |
661 | still_alive(); | 660 | mask |= 0x01f80000; |
662 | nv_wr32(dev, reg + 4, reg1); | 661 | ctrl |= (pll_limits.log2p_bias << 19); |
663 | nv_wr32(dev, reg + 0, reg0); | 662 | ctrl |= (pll.log2P << 22); |
664 | } | 663 | } |
665 | 664 | ||
665 | if (!dev_priv->vbios.execute) | ||
666 | return 0; | ||
667 | |||
668 | nv_mask(dev, reg + 0, mask, ctrl); | ||
669 | nv_wr32(dev, reg + 4, coef); | ||
666 | return 0; | 670 | return 0; |
667 | } | 671 | } |
668 | 672 | ||
diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c index 7226f419e178..7cc37e690860 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.c +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c | |||
@@ -148,7 +148,7 @@ set_placement_range(struct nouveau_bo *nvbo, uint32_t type) | |||
148 | 148 | ||
149 | if (dev_priv->card_type == NV_10 && | 149 | if (dev_priv->card_type == NV_10 && |
150 | nvbo->tile_mode && (type & TTM_PL_FLAG_VRAM) && | 150 | nvbo->tile_mode && (type & TTM_PL_FLAG_VRAM) && |
151 | nvbo->bo.mem.num_pages < vram_pages / 2) { | 151 | nvbo->bo.mem.num_pages < vram_pages / 4) { |
152 | /* | 152 | /* |
153 | * Make sure that the color and depth buffers are handled | 153 | * Make sure that the color and depth buffers are handled |
154 | * by independent memory controller units. Up to a 9x | 154 | * by independent memory controller units. Up to a 9x |
diff --git a/drivers/gpu/drm/nouveau/nouveau_channel.c b/drivers/gpu/drm/nouveau/nouveau_channel.c index a319d5646ea9..bb6ec9ef8676 100644 --- a/drivers/gpu/drm/nouveau/nouveau_channel.c +++ b/drivers/gpu/drm/nouveau/nouveau_channel.c | |||
@@ -158,6 +158,7 @@ nouveau_channel_alloc(struct drm_device *dev, struct nouveau_channel **chan_ret, | |||
158 | INIT_LIST_HEAD(&chan->nvsw.vbl_wait); | 158 | INIT_LIST_HEAD(&chan->nvsw.vbl_wait); |
159 | INIT_LIST_HEAD(&chan->nvsw.flip); | 159 | INIT_LIST_HEAD(&chan->nvsw.flip); |
160 | INIT_LIST_HEAD(&chan->fence.pending); | 160 | INIT_LIST_HEAD(&chan->fence.pending); |
161 | spin_lock_init(&chan->fence.lock); | ||
161 | 162 | ||
162 | /* setup channel's memory and vm */ | 163 | /* setup channel's memory and vm */ |
163 | ret = nouveau_gpuobj_channel_init(chan, vram_handle, gart_handle); | 164 | ret = nouveau_gpuobj_channel_init(chan, vram_handle, gart_handle); |
diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c b/drivers/gpu/drm/nouveau/nouveau_connector.c index e0d275e1c96c..cea6696b1906 100644 --- a/drivers/gpu/drm/nouveau/nouveau_connector.c +++ b/drivers/gpu/drm/nouveau/nouveau_connector.c | |||
@@ -710,7 +710,7 @@ nouveau_connector_mode_valid(struct drm_connector *connector, | |||
710 | case OUTPUT_DP: | 710 | case OUTPUT_DP: |
711 | max_clock = nv_encoder->dp.link_nr; | 711 | max_clock = nv_encoder->dp.link_nr; |
712 | max_clock *= nv_encoder->dp.link_bw; | 712 | max_clock *= nv_encoder->dp.link_bw; |
713 | clock = clock * nouveau_connector_bpp(connector) / 8; | 713 | clock = clock * nouveau_connector_bpp(connector) / 10; |
714 | break; | 714 | break; |
715 | default: | 715 | default: |
716 | BUG_ON(1); | 716 | BUG_ON(1); |
diff --git a/drivers/gpu/drm/nouveau/nouveau_fbcon.c b/drivers/gpu/drm/nouveau/nouveau_fbcon.c index 14a8627efe4d..3a4cc32b9e44 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fbcon.c +++ b/drivers/gpu/drm/nouveau/nouveau_fbcon.c | |||
@@ -487,6 +487,7 @@ int nouveau_fbcon_init(struct drm_device *dev) | |||
487 | { | 487 | { |
488 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 488 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
489 | struct nouveau_fbdev *nfbdev; | 489 | struct nouveau_fbdev *nfbdev; |
490 | int preferred_bpp; | ||
490 | int ret; | 491 | int ret; |
491 | 492 | ||
492 | nfbdev = kzalloc(sizeof(struct nouveau_fbdev), GFP_KERNEL); | 493 | nfbdev = kzalloc(sizeof(struct nouveau_fbdev), GFP_KERNEL); |
@@ -505,7 +506,15 @@ int nouveau_fbcon_init(struct drm_device *dev) | |||
505 | } | 506 | } |
506 | 507 | ||
507 | drm_fb_helper_single_add_all_connectors(&nfbdev->helper); | 508 | drm_fb_helper_single_add_all_connectors(&nfbdev->helper); |
508 | drm_fb_helper_initial_config(&nfbdev->helper, 32); | 509 | |
510 | if (dev_priv->vram_size <= 32 * 1024 * 1024) | ||
511 | preferred_bpp = 8; | ||
512 | else if (dev_priv->vram_size <= 64 * 1024 * 1024) | ||
513 | preferred_bpp = 16; | ||
514 | else | ||
515 | preferred_bpp = 32; | ||
516 | |||
517 | drm_fb_helper_initial_config(&nfbdev->helper, preferred_bpp); | ||
509 | return 0; | 518 | return 0; |
510 | } | 519 | } |
511 | 520 | ||
diff --git a/drivers/gpu/drm/nouveau/nouveau_fence.c b/drivers/gpu/drm/nouveau/nouveau_fence.c index 81116cfea275..2f6daae68b9d 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fence.c +++ b/drivers/gpu/drm/nouveau/nouveau_fence.c | |||
@@ -539,8 +539,6 @@ nouveau_fence_channel_init(struct nouveau_channel *chan) | |||
539 | return ret; | 539 | return ret; |
540 | } | 540 | } |
541 | 541 | ||
542 | INIT_LIST_HEAD(&chan->fence.pending); | ||
543 | spin_lock_init(&chan->fence.lock); | ||
544 | atomic_set(&chan->fence.last_sequence_irq, 0); | 542 | atomic_set(&chan->fence.last_sequence_irq, 0); |
545 | return 0; | 543 | return 0; |
546 | } | 544 | } |
diff --git a/drivers/gpu/drm/nouveau/nouveau_i2c.c b/drivers/gpu/drm/nouveau/nouveau_i2c.c index c6143df48b9f..d39b2202b197 100644 --- a/drivers/gpu/drm/nouveau/nouveau_i2c.c +++ b/drivers/gpu/drm/nouveau/nouveau_i2c.c | |||
@@ -333,7 +333,7 @@ nouveau_i2c_identify(struct drm_device *dev, const char *what, | |||
333 | 333 | ||
334 | NV_DEBUG(dev, "Probing %ss on I2C bus: %d\n", what, index); | 334 | NV_DEBUG(dev, "Probing %ss on I2C bus: %d\n", what, index); |
335 | 335 | ||
336 | for (i = 0; info[i].addr; i++) { | 336 | for (i = 0; i2c && info[i].addr; i++) { |
337 | if (nouveau_probe_i2c_addr(i2c, info[i].addr) && | 337 | if (nouveau_probe_i2c_addr(i2c, info[i].addr) && |
338 | (!match || match(i2c, &info[i]))) { | 338 | (!match || match(i2c, &info[i]))) { |
339 | NV_INFO(dev, "Detected %s: %s\n", what, info[i].type); | 339 | NV_INFO(dev, "Detected %s: %s\n", what, info[i].type); |
diff --git a/drivers/gpu/drm/nouveau/nouveau_perf.c b/drivers/gpu/drm/nouveau/nouveau_perf.c index 9f178aa94162..33d03fbf00df 100644 --- a/drivers/gpu/drm/nouveau/nouveau_perf.c +++ b/drivers/gpu/drm/nouveau/nouveau_perf.c | |||
@@ -239,7 +239,7 @@ nouveau_perf_init(struct drm_device *dev) | |||
239 | if(version == 0x15) { | 239 | if(version == 0x15) { |
240 | memtimings->timing = | 240 | memtimings->timing = |
241 | kcalloc(entries, sizeof(*memtimings->timing), GFP_KERNEL); | 241 | kcalloc(entries, sizeof(*memtimings->timing), GFP_KERNEL); |
242 | if(!memtimings) { | 242 | if (!memtimings->timing) { |
243 | NV_WARN(dev,"Could not allocate memtiming table\n"); | 243 | NV_WARN(dev,"Could not allocate memtiming table\n"); |
244 | return; | 244 | return; |
245 | } | 245 | } |
diff --git a/drivers/gpu/drm/nouveau/nouveau_state.c b/drivers/gpu/drm/nouveau/nouveau_state.c index 82478e0998e5..d8831ab42bb9 100644 --- a/drivers/gpu/drm/nouveau/nouveau_state.c +++ b/drivers/gpu/drm/nouveau/nouveau_state.c | |||
@@ -579,6 +579,14 @@ nouveau_card_init(struct drm_device *dev) | |||
579 | if (ret) | 579 | if (ret) |
580 | goto out_display_early; | 580 | goto out_display_early; |
581 | 581 | ||
582 | /* workaround an odd issue on nvc1 by disabling the device's | ||
583 | * nosnoop capability. hopefully won't cause issues until a | ||
584 | * better fix is found - assuming there is one... | ||
585 | */ | ||
586 | if (dev_priv->chipset == 0xc1) { | ||
587 | nv_mask(dev, 0x00088080, 0x00000800, 0x00000000); | ||
588 | } | ||
589 | |||
582 | nouveau_pm_init(dev); | 590 | nouveau_pm_init(dev); |
583 | 591 | ||
584 | ret = engine->vram.init(dev); | 592 | ret = engine->vram.init(dev); |
@@ -1102,12 +1110,13 @@ int nouveau_load(struct drm_device *dev, unsigned long flags) | |||
1102 | dev_priv->noaccel = !!nouveau_noaccel; | 1110 | dev_priv->noaccel = !!nouveau_noaccel; |
1103 | if (nouveau_noaccel == -1) { | 1111 | if (nouveau_noaccel == -1) { |
1104 | switch (dev_priv->chipset) { | 1112 | switch (dev_priv->chipset) { |
1105 | case 0xc1: /* known broken */ | 1113 | #if 0 |
1106 | case 0xc8: /* never tested */ | 1114 | case 0xXX: /* known broken */ |
1107 | NV_INFO(dev, "acceleration disabled by default, pass " | 1115 | NV_INFO(dev, "acceleration disabled by default, pass " |
1108 | "noaccel=0 to force enable\n"); | 1116 | "noaccel=0 to force enable\n"); |
1109 | dev_priv->noaccel = true; | 1117 | dev_priv->noaccel = true; |
1110 | break; | 1118 | break; |
1119 | #endif | ||
1111 | default: | 1120 | default: |
1112 | dev_priv->noaccel = false; | 1121 | dev_priv->noaccel = false; |
1113 | break; | 1122 | break; |
diff --git a/drivers/gpu/drm/nouveau/nv40_pm.c b/drivers/gpu/drm/nouveau/nv40_pm.c index bbc0b9c7e1f7..e676b0d53478 100644 --- a/drivers/gpu/drm/nouveau/nv40_pm.c +++ b/drivers/gpu/drm/nouveau/nv40_pm.c | |||
@@ -57,12 +57,14 @@ read_pll_2(struct drm_device *dev, u32 reg) | |||
57 | int P = (ctrl & 0x00070000) >> 16; | 57 | int P = (ctrl & 0x00070000) >> 16; |
58 | u32 ref = 27000, clk = 0; | 58 | u32 ref = 27000, clk = 0; |
59 | 59 | ||
60 | if (ctrl & 0x80000000) | 60 | if ((ctrl & 0x80000000) && M1) { |
61 | clk = ref * N1 / M1; | 61 | clk = ref * N1 / M1; |
62 | 62 | if ((ctrl & 0x40000100) == 0x40000000) { | |
63 | if (!(ctrl & 0x00000100)) { | 63 | if (M2) |
64 | if (ctrl & 0x40000000) | 64 | clk = clk * N2 / M2; |
65 | clk = clk * N2 / M2; | 65 | else |
66 | clk = 0; | ||
67 | } | ||
66 | } | 68 | } |
67 | 69 | ||
68 | return clk >> P; | 70 | return clk >> P; |
@@ -177,6 +179,11 @@ nv40_pm_clocks_pre(struct drm_device *dev, struct nouveau_pm_level *perflvl) | |||
177 | } | 179 | } |
178 | 180 | ||
179 | /* memory clock */ | 181 | /* memory clock */ |
182 | if (!perflvl->memory) { | ||
183 | info->mpll_ctrl = 0x00000000; | ||
184 | goto out; | ||
185 | } | ||
186 | |||
180 | ret = nv40_calc_pll(dev, 0x004020, &pll, perflvl->memory, | 187 | ret = nv40_calc_pll(dev, 0x004020, &pll, perflvl->memory, |
181 | &N1, &M1, &N2, &M2, &log2P); | 188 | &N1, &M1, &N2, &M2, &log2P); |
182 | if (ret < 0) | 189 | if (ret < 0) |
@@ -264,6 +271,9 @@ nv40_pm_clocks_set(struct drm_device *dev, void *pre_state) | |||
264 | mdelay(5); | 271 | mdelay(5); |
265 | nv_mask(dev, 0x00c040, 0x00000333, info->ctrl); | 272 | nv_mask(dev, 0x00c040, 0x00000333, info->ctrl); |
266 | 273 | ||
274 | if (!info->mpll_ctrl) | ||
275 | goto resume; | ||
276 | |||
267 | /* wait for vblank start on active crtcs, disable memory access */ | 277 | /* wait for vblank start on active crtcs, disable memory access */ |
268 | for (i = 0; i < 2; i++) { | 278 | for (i = 0; i < 2; i++) { |
269 | if (!(crtc_mask & (1 << i))) | 279 | if (!(crtc_mask & (1 << i))) |
diff --git a/drivers/gpu/drm/nouveau/nv50_graph.c b/drivers/gpu/drm/nouveau/nv50_graph.c index 8c979b31ff61..ac601f7c4e1a 100644 --- a/drivers/gpu/drm/nouveau/nv50_graph.c +++ b/drivers/gpu/drm/nouveau/nv50_graph.c | |||
@@ -131,8 +131,8 @@ nv50_graph_init(struct drm_device *dev, int engine) | |||
131 | NV_DEBUG(dev, "\n"); | 131 | NV_DEBUG(dev, "\n"); |
132 | 132 | ||
133 | /* master reset */ | 133 | /* master reset */ |
134 | nv_mask(dev, 0x000200, 0x00200100, 0x00000000); | 134 | nv_mask(dev, 0x000200, 0x00201000, 0x00000000); |
135 | nv_mask(dev, 0x000200, 0x00200100, 0x00200100); | 135 | nv_mask(dev, 0x000200, 0x00201000, 0x00201000); |
136 | nv_wr32(dev, 0x40008c, 0x00000004); /* HW_CTX_SWITCH_ENABLED */ | 136 | nv_wr32(dev, 0x40008c, 0x00000004); /* HW_CTX_SWITCH_ENABLED */ |
137 | 137 | ||
138 | /* reset/enable traps and interrupts */ | 138 | /* reset/enable traps and interrupts */ |
diff --git a/drivers/gpu/drm/nouveau/nv50_grctx.c b/drivers/gpu/drm/nouveau/nv50_grctx.c index d05c2c3b2444..4b46d6968566 100644 --- a/drivers/gpu/drm/nouveau/nv50_grctx.c +++ b/drivers/gpu/drm/nouveau/nv50_grctx.c | |||
@@ -601,7 +601,7 @@ nv50_graph_construct_mmio(struct nouveau_grctx *ctx) | |||
601 | gr_def(ctx, offset + 0x1c, 0x00880000); | 601 | gr_def(ctx, offset + 0x1c, 0x00880000); |
602 | break; | 602 | break; |
603 | case 0x86: | 603 | case 0x86: |
604 | gr_def(ctx, offset + 0x1c, 0x008c0000); | 604 | gr_def(ctx, offset + 0x1c, 0x018c0000); |
605 | break; | 605 | break; |
606 | case 0x92: | 606 | case 0x92: |
607 | case 0x96: | 607 | case 0x96: |
diff --git a/drivers/gpu/drm/nouveau/nv50_vram.c b/drivers/gpu/drm/nouveau/nv50_vram.c index 9da23838e63e..2e45e57fd869 100644 --- a/drivers/gpu/drm/nouveau/nv50_vram.c +++ b/drivers/gpu/drm/nouveau/nv50_vram.c | |||
@@ -160,7 +160,7 @@ nv50_vram_rblock(struct drm_device *dev) | |||
160 | colbits = (r4 & 0x0000f000) >> 12; | 160 | colbits = (r4 & 0x0000f000) >> 12; |
161 | rowbitsa = ((r4 & 0x000f0000) >> 16) + 8; | 161 | rowbitsa = ((r4 & 0x000f0000) >> 16) + 8; |
162 | rowbitsb = ((r4 & 0x00f00000) >> 20) + 8; | 162 | rowbitsb = ((r4 & 0x00f00000) >> 20) + 8; |
163 | banks = ((r4 & 0x01000000) ? 8 : 4); | 163 | banks = 1 << (((r4 & 0x03000000) >> 24) + 2); |
164 | 164 | ||
165 | rowsize = parts * banks * (1 << colbits) * 8; | 165 | rowsize = parts * banks * (1 << colbits) * 8; |
166 | predicted = rowsize << rowbitsa; | 166 | predicted = rowsize << rowbitsa; |
diff --git a/drivers/gpu/drm/nouveau/nvc0_graph.c b/drivers/gpu/drm/nouveau/nvc0_graph.c index bbdbc51830c8..a74e501afd25 100644 --- a/drivers/gpu/drm/nouveau/nvc0_graph.c +++ b/drivers/gpu/drm/nouveau/nvc0_graph.c | |||
@@ -157,8 +157,8 @@ nvc0_graph_create_context_mmio_list(struct nouveau_channel *chan) | |||
157 | struct nvc0_graph_priv *priv = nv_engine(chan->dev, NVOBJ_ENGINE_GR); | 157 | struct nvc0_graph_priv *priv = nv_engine(chan->dev, NVOBJ_ENGINE_GR); |
158 | struct nvc0_graph_chan *grch = chan->engctx[NVOBJ_ENGINE_GR]; | 158 | struct nvc0_graph_chan *grch = chan->engctx[NVOBJ_ENGINE_GR]; |
159 | struct drm_device *dev = chan->dev; | 159 | struct drm_device *dev = chan->dev; |
160 | struct drm_nouveau_private *dev_priv = dev->dev_private; | ||
160 | int i = 0, gpc, tp, ret; | 161 | int i = 0, gpc, tp, ret; |
161 | u32 magic; | ||
162 | 162 | ||
163 | ret = nouveau_gpuobj_new(dev, chan, 0x2000, 256, NVOBJ_FLAG_VM, | 163 | ret = nouveau_gpuobj_new(dev, chan, 0x2000, 256, NVOBJ_FLAG_VM, |
164 | &grch->unk408004); | 164 | &grch->unk408004); |
@@ -207,14 +207,37 @@ nvc0_graph_create_context_mmio_list(struct nouveau_channel *chan) | |||
207 | nv_wo32(grch->mmio, i++ * 4, 0x0041880c); | 207 | nv_wo32(grch->mmio, i++ * 4, 0x0041880c); |
208 | nv_wo32(grch->mmio, i++ * 4, 0x80000018); | 208 | nv_wo32(grch->mmio, i++ * 4, 0x80000018); |
209 | 209 | ||
210 | magic = 0x02180000; | 210 | if (dev_priv->chipset != 0xc1) { |
211 | nv_wo32(grch->mmio, i++ * 4, 0x00405830); | 211 | u32 magic = 0x02180000; |
212 | nv_wo32(grch->mmio, i++ * 4, magic); | 212 | nv_wo32(grch->mmio, i++ * 4, 0x00405830); |
213 | for (gpc = 0; gpc < priv->gpc_nr; gpc++) { | 213 | nv_wo32(grch->mmio, i++ * 4, magic); |
214 | for (tp = 0; tp < priv->tp_nr[gpc]; tp++, magic += 0x0324) { | 214 | for (gpc = 0; gpc < priv->gpc_nr; gpc++) { |
215 | u32 reg = 0x504520 + (gpc * 0x8000) + (tp * 0x0800); | 215 | for (tp = 0; tp < priv->tp_nr[gpc]; tp++) { |
216 | nv_wo32(grch->mmio, i++ * 4, reg); | 216 | u32 reg = TP_UNIT(gpc, tp, 0x520); |
217 | nv_wo32(grch->mmio, i++ * 4, magic); | 217 | nv_wo32(grch->mmio, i++ * 4, reg); |
218 | nv_wo32(grch->mmio, i++ * 4, magic); | ||
219 | magic += 0x0324; | ||
220 | } | ||
221 | } | ||
222 | } else { | ||
223 | u32 magic = 0x02180000; | ||
224 | nv_wo32(grch->mmio, i++ * 4, 0x00405830); | ||
225 | nv_wo32(grch->mmio, i++ * 4, magic | 0x0000218); | ||
226 | nv_wo32(grch->mmio, i++ * 4, 0x004064c4); | ||
227 | nv_wo32(grch->mmio, i++ * 4, 0x0086ffff); | ||
228 | for (gpc = 0; gpc < priv->gpc_nr; gpc++) { | ||
229 | for (tp = 0; tp < priv->tp_nr[gpc]; tp++) { | ||
230 | u32 reg = TP_UNIT(gpc, tp, 0x520); | ||
231 | nv_wo32(grch->mmio, i++ * 4, reg); | ||
232 | nv_wo32(grch->mmio, i++ * 4, (1 << 28) | magic); | ||
233 | magic += 0x0324; | ||
234 | } | ||
235 | for (tp = 0; tp < priv->tp_nr[gpc]; tp++) { | ||
236 | u32 reg = TP_UNIT(gpc, tp, 0x544); | ||
237 | nv_wo32(grch->mmio, i++ * 4, reg); | ||
238 | nv_wo32(grch->mmio, i++ * 4, magic); | ||
239 | magic += 0x0324; | ||
240 | } | ||
218 | } | 241 | } |
219 | } | 242 | } |
220 | 243 | ||
diff --git a/drivers/gpu/drm/nouveau/nvc0_grctx.c b/drivers/gpu/drm/nouveau/nvc0_grctx.c index dd0e6a736b3b..96b0b93d94ca 100644 --- a/drivers/gpu/drm/nouveau/nvc0_grctx.c +++ b/drivers/gpu/drm/nouveau/nvc0_grctx.c | |||
@@ -1812,6 +1812,7 @@ nvc0_grctx_generate(struct nouveau_channel *chan) | |||
1812 | /* calculate first set of magics */ | 1812 | /* calculate first set of magics */ |
1813 | memcpy(tpnr, priv->tp_nr, sizeof(priv->tp_nr)); | 1813 | memcpy(tpnr, priv->tp_nr, sizeof(priv->tp_nr)); |
1814 | 1814 | ||
1815 | gpc = -1; | ||
1815 | for (tp = 0; tp < priv->tp_total; tp++) { | 1816 | for (tp = 0; tp < priv->tp_total; tp++) { |
1816 | do { | 1817 | do { |
1817 | gpc = (gpc + 1) % priv->gpc_nr; | 1818 | gpc = (gpc + 1) % priv->gpc_nr; |
@@ -1861,30 +1862,26 @@ nvc0_grctx_generate(struct nouveau_channel *chan) | |||
1861 | 1862 | ||
1862 | if (1) { | 1863 | if (1) { |
1863 | u32 tp_mask = 0, tp_set = 0; | 1864 | u32 tp_mask = 0, tp_set = 0; |
1864 | u8 tpnr[GPC_MAX]; | 1865 | u8 tpnr[GPC_MAX], a, b; |
1865 | 1866 | ||
1866 | memcpy(tpnr, priv->tp_nr, sizeof(priv->tp_nr)); | 1867 | memcpy(tpnr, priv->tp_nr, sizeof(priv->tp_nr)); |
1867 | for (gpc = 0; gpc < priv->gpc_nr; gpc++) | 1868 | for (gpc = 0; gpc < priv->gpc_nr; gpc++) |
1868 | tp_mask |= ((1 << priv->tp_nr[gpc]) - 1) << (gpc * 8); | 1869 | tp_mask |= ((1 << priv->tp_nr[gpc]) - 1) << (gpc * 8); |
1869 | 1870 | ||
1870 | gpc = -1; | 1871 | for (i = 0, gpc = -1, b = -1; i < 32; i++) { |
1871 | for (i = 0, gpc = -1; i < 32; i++) { | 1872 | a = (i * (priv->tp_total - 1)) / 32; |
1872 | int ltp = i * (priv->tp_total - 1) / 32; | 1873 | if (a != b) { |
1873 | 1874 | b = a; | |
1874 | do { | 1875 | do { |
1875 | gpc = (gpc + 1) % priv->gpc_nr; | 1876 | gpc = (gpc + 1) % priv->gpc_nr; |
1876 | } while (!tpnr[gpc]); | 1877 | } while (!tpnr[gpc]); |
1877 | tp = priv->tp_nr[gpc] - tpnr[gpc]--; | 1878 | tp = priv->tp_nr[gpc] - tpnr[gpc]--; |
1878 | 1879 | ||
1879 | tp_set |= 1 << ((gpc * 8) + tp); | 1880 | tp_set |= 1 << ((gpc * 8) + tp); |
1881 | } | ||
1880 | 1882 | ||
1881 | do { | 1883 | nv_wr32(dev, 0x406800 + (i * 0x20), tp_set); |
1882 | nv_wr32(dev, 0x406800 + (i * 0x20), tp_set); | 1884 | nv_wr32(dev, 0x406c00 + (i * 0x20), tp_set ^ tp_mask); |
1883 | tp_set ^= tp_mask; | ||
1884 | nv_wr32(dev, 0x406c00 + (i * 0x20), tp_set); | ||
1885 | tp_set ^= tp_mask; | ||
1886 | } while (ltp == (++i * (priv->tp_total - 1) / 32)); | ||
1887 | i--; | ||
1888 | } | 1885 | } |
1889 | } | 1886 | } |
1890 | 1887 | ||
diff --git a/drivers/gpu/drm/nouveau/nvc0_vram.c b/drivers/gpu/drm/nouveau/nvc0_vram.c index edbfe9360ae2..ce984d573a51 100644 --- a/drivers/gpu/drm/nouveau/nvc0_vram.c +++ b/drivers/gpu/drm/nouveau/nvc0_vram.c | |||
@@ -43,7 +43,7 @@ static const u8 types[256] = { | |||
43 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 43 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
44 | 0, 0, 0, 3, 3, 3, 3, 1, 1, 1, 1, 0, 0, 0, 0, 0, | 44 | 0, 0, 0, 3, 3, 3, 3, 1, 1, 1, 1, 0, 0, 0, 0, 0, |
45 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, | 45 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, |
46 | 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, | 46 | 3, 3, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, |
47 | 3, 3, 0, 0, 0, 0, 0, 0, 3, 0, 0, 3, 0, 3, 0, 3, | 47 | 3, 3, 0, 0, 0, 0, 0, 0, 3, 0, 0, 3, 0, 3, 0, 3, |
48 | 3, 0, 3, 3, 3, 3, 3, 0, 0, 3, 0, 3, 0, 3, 3, 0, | 48 | 3, 0, 3, 3, 3, 3, 3, 0, 0, 3, 0, 3, 0, 3, 3, 0, |
49 | 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 1, 1, 0 | 49 | 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 1, 1, 0 |
@@ -110,22 +110,26 @@ nvc0_vram_init(struct drm_device *dev) | |||
110 | u32 bsize = nv_rd32(dev, 0x10f20c); | 110 | u32 bsize = nv_rd32(dev, 0x10f20c); |
111 | u32 offset, length; | 111 | u32 offset, length; |
112 | bool uniform = true; | 112 | bool uniform = true; |
113 | int ret, i; | 113 | int ret, part; |
114 | 114 | ||
115 | NV_DEBUG(dev, "0x100800: 0x%08x\n", nv_rd32(dev, 0x100800)); | 115 | NV_DEBUG(dev, "0x100800: 0x%08x\n", nv_rd32(dev, 0x100800)); |
116 | NV_DEBUG(dev, "parts 0x%08x bcast_mem_amount 0x%08x\n", parts, bsize); | 116 | NV_DEBUG(dev, "parts 0x%08x bcast_mem_amount 0x%08x\n", parts, bsize); |
117 | 117 | ||
118 | /* read amount of vram attached to each memory controller */ | 118 | /* read amount of vram attached to each memory controller */ |
119 | for (i = 0; i < parts; i++) { | 119 | part = 0; |
120 | u32 psize = nv_rd32(dev, 0x11020c + (i * 0x1000)); | 120 | while (parts) { |
121 | u32 psize = nv_rd32(dev, 0x11020c + (part++ * 0x1000)); | ||
122 | if (psize == 0) | ||
123 | continue; | ||
124 | parts--; | ||
125 | |||
121 | if (psize != bsize) { | 126 | if (psize != bsize) { |
122 | if (psize < bsize) | 127 | if (psize < bsize) |
123 | bsize = psize; | 128 | bsize = psize; |
124 | uniform = false; | 129 | uniform = false; |
125 | } | 130 | } |
126 | 131 | ||
127 | NV_DEBUG(dev, "%d: mem_amount 0x%08x\n", i, psize); | 132 | NV_DEBUG(dev, "%d: mem_amount 0x%08x\n", part, psize); |
128 | |||
129 | dev_priv->vram_size += (u64)psize << 20; | 133 | dev_priv->vram_size += (u64)psize << 20; |
130 | } | 134 | } |
131 | 135 | ||
diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c index 87921c88a95c..87631fede1f8 100644 --- a/drivers/gpu/drm/radeon/atombios_crtc.c +++ b/drivers/gpu/drm/radeon/atombios_crtc.c | |||
@@ -1522,12 +1522,6 @@ static bool atombios_crtc_mode_fixup(struct drm_crtc *crtc, | |||
1522 | struct drm_display_mode *mode, | 1522 | struct drm_display_mode *mode, |
1523 | struct drm_display_mode *adjusted_mode) | 1523 | struct drm_display_mode *adjusted_mode) |
1524 | { | 1524 | { |
1525 | struct drm_device *dev = crtc->dev; | ||
1526 | struct radeon_device *rdev = dev->dev_private; | ||
1527 | |||
1528 | /* adjust pm to upcoming mode change */ | ||
1529 | radeon_pm_compute_clocks(rdev); | ||
1530 | |||
1531 | if (!radeon_crtc_scaling_mode_fixup(crtc, mode, adjusted_mode)) | 1525 | if (!radeon_crtc_scaling_mode_fixup(crtc, mode, adjusted_mode)) |
1532 | return false; | 1526 | return false; |
1533 | return true; | 1527 | return true; |
diff --git a/drivers/gpu/drm/radeon/atombios_dp.c b/drivers/gpu/drm/radeon/atombios_dp.c index a0de48542f71..6fb335a4fdda 100644 --- a/drivers/gpu/drm/radeon/atombios_dp.c +++ b/drivers/gpu/drm/radeon/atombios_dp.c | |||
@@ -283,7 +283,7 @@ int radeon_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode, | |||
283 | } | 283 | } |
284 | } | 284 | } |
285 | 285 | ||
286 | DRM_ERROR("aux i2c too many retries, giving up\n"); | 286 | DRM_DEBUG_KMS("aux i2c too many retries, giving up\n"); |
287 | return -EREMOTEIO; | 287 | return -EREMOTEIO; |
288 | } | 288 | } |
289 | 289 | ||
diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index e4c384b9511c..1d603a3335db 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c | |||
@@ -157,6 +157,57 @@ int sumo_get_temp(struct radeon_device *rdev) | |||
157 | return actual_temp * 1000; | 157 | return actual_temp * 1000; |
158 | } | 158 | } |
159 | 159 | ||
160 | void sumo_pm_init_profile(struct radeon_device *rdev) | ||
161 | { | ||
162 | int idx; | ||
163 | |||
164 | /* default */ | ||
165 | rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_off_ps_idx = rdev->pm.default_power_state_index; | ||
166 | rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_on_ps_idx = rdev->pm.default_power_state_index; | ||
167 | rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_off_cm_idx = 0; | ||
168 | rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_on_cm_idx = 0; | ||
169 | |||
170 | /* low,mid sh/mh */ | ||
171 | if (rdev->flags & RADEON_IS_MOBILITY) | ||
172 | idx = radeon_pm_get_type_index(rdev, POWER_STATE_TYPE_BATTERY, 0); | ||
173 | else | ||
174 | idx = radeon_pm_get_type_index(rdev, POWER_STATE_TYPE_PERFORMANCE, 0); | ||
175 | |||
176 | rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_off_ps_idx = idx; | ||
177 | rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_ps_idx = idx; | ||
178 | rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_off_cm_idx = 0; | ||
179 | rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_cm_idx = 0; | ||
180 | |||
181 | rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_off_ps_idx = idx; | ||
182 | rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_ps_idx = idx; | ||
183 | rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_off_cm_idx = 0; | ||
184 | rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_cm_idx = 0; | ||
185 | |||
186 | rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_off_ps_idx = idx; | ||
187 | rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_on_ps_idx = idx; | ||
188 | rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_off_cm_idx = 0; | ||
189 | rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_on_cm_idx = 0; | ||
190 | |||
191 | rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_off_ps_idx = idx; | ||
192 | rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_on_ps_idx = idx; | ||
193 | rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_off_cm_idx = 0; | ||
194 | rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_on_cm_idx = 0; | ||
195 | |||
196 | /* high sh/mh */ | ||
197 | idx = radeon_pm_get_type_index(rdev, POWER_STATE_TYPE_PERFORMANCE, 0); | ||
198 | rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_off_ps_idx = idx; | ||
199 | rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_on_ps_idx = idx; | ||
200 | rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_off_cm_idx = 0; | ||
201 | rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_on_cm_idx = | ||
202 | rdev->pm.power_state[idx].num_clock_modes - 1; | ||
203 | |||
204 | rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_off_ps_idx = idx; | ||
205 | rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_on_ps_idx = idx; | ||
206 | rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_off_cm_idx = 0; | ||
207 | rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_on_cm_idx = | ||
208 | rdev->pm.power_state[idx].num_clock_modes - 1; | ||
209 | } | ||
210 | |||
160 | void evergreen_pm_misc(struct radeon_device *rdev) | 211 | void evergreen_pm_misc(struct radeon_device *rdev) |
161 | { | 212 | { |
162 | int req_ps_idx = rdev->pm.requested_power_state_index; | 213 | int req_ps_idx = rdev->pm.requested_power_state_index; |
@@ -1219,7 +1270,7 @@ void evergreen_mc_program(struct radeon_device *rdev) | |||
1219 | WREG32(MC_VM_SYSTEM_APERTURE_HIGH_ADDR, | 1270 | WREG32(MC_VM_SYSTEM_APERTURE_HIGH_ADDR, |
1220 | rdev->mc.vram_end >> 12); | 1271 | rdev->mc.vram_end >> 12); |
1221 | } | 1272 | } |
1222 | WREG32(MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR, 0); | 1273 | WREG32(MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR, rdev->vram_scratch.gpu_addr >> 12); |
1223 | if (rdev->flags & RADEON_IS_IGP) { | 1274 | if (rdev->flags & RADEON_IS_IGP) { |
1224 | tmp = RREG32(MC_FUS_VM_FB_OFFSET) & 0x000FFFFF; | 1275 | tmp = RREG32(MC_FUS_VM_FB_OFFSET) & 0x000FFFFF; |
1225 | tmp |= ((rdev->mc.vram_end >> 20) & 0xF) << 24; | 1276 | tmp |= ((rdev->mc.vram_end >> 20) & 0xF) << 24; |
diff --git a/drivers/gpu/drm/radeon/evergreen_cs.c b/drivers/gpu/drm/radeon/evergreen_cs.c index 7fdfa8ea7570..38e1bda73d33 100644 --- a/drivers/gpu/drm/radeon/evergreen_cs.c +++ b/drivers/gpu/drm/radeon/evergreen_cs.c | |||
@@ -480,21 +480,23 @@ static int evergreen_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) | |||
480 | } | 480 | } |
481 | break; | 481 | break; |
482 | case DB_Z_INFO: | 482 | case DB_Z_INFO: |
483 | r = evergreen_cs_packet_next_reloc(p, &reloc); | ||
484 | if (r) { | ||
485 | dev_warn(p->dev, "bad SET_CONTEXT_REG " | ||
486 | "0x%04X\n", reg); | ||
487 | return -EINVAL; | ||
488 | } | ||
489 | track->db_z_info = radeon_get_ib_value(p, idx); | 483 | track->db_z_info = radeon_get_ib_value(p, idx); |
490 | ib[idx] &= ~Z_ARRAY_MODE(0xf); | 484 | if (!p->keep_tiling_flags) { |
491 | track->db_z_info &= ~Z_ARRAY_MODE(0xf); | 485 | r = evergreen_cs_packet_next_reloc(p, &reloc); |
492 | if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) { | 486 | if (r) { |
493 | ib[idx] |= Z_ARRAY_MODE(ARRAY_2D_TILED_THIN1); | 487 | dev_warn(p->dev, "bad SET_CONTEXT_REG " |
494 | track->db_z_info |= Z_ARRAY_MODE(ARRAY_2D_TILED_THIN1); | 488 | "0x%04X\n", reg); |
495 | } else { | 489 | return -EINVAL; |
496 | ib[idx] |= Z_ARRAY_MODE(ARRAY_1D_TILED_THIN1); | 490 | } |
497 | track->db_z_info |= Z_ARRAY_MODE(ARRAY_1D_TILED_THIN1); | 491 | ib[idx] &= ~Z_ARRAY_MODE(0xf); |
492 | track->db_z_info &= ~Z_ARRAY_MODE(0xf); | ||
493 | if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) { | ||
494 | ib[idx] |= Z_ARRAY_MODE(ARRAY_2D_TILED_THIN1); | ||
495 | track->db_z_info |= Z_ARRAY_MODE(ARRAY_2D_TILED_THIN1); | ||
496 | } else { | ||
497 | ib[idx] |= Z_ARRAY_MODE(ARRAY_1D_TILED_THIN1); | ||
498 | track->db_z_info |= Z_ARRAY_MODE(ARRAY_1D_TILED_THIN1); | ||
499 | } | ||
498 | } | 500 | } |
499 | break; | 501 | break; |
500 | case DB_STENCIL_INFO: | 502 | case DB_STENCIL_INFO: |
@@ -607,40 +609,44 @@ static int evergreen_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) | |||
607 | case CB_COLOR5_INFO: | 609 | case CB_COLOR5_INFO: |
608 | case CB_COLOR6_INFO: | 610 | case CB_COLOR6_INFO: |
609 | case CB_COLOR7_INFO: | 611 | case CB_COLOR7_INFO: |
610 | r = evergreen_cs_packet_next_reloc(p, &reloc); | ||
611 | if (r) { | ||
612 | dev_warn(p->dev, "bad SET_CONTEXT_REG " | ||
613 | "0x%04X\n", reg); | ||
614 | return -EINVAL; | ||
615 | } | ||
616 | tmp = (reg - CB_COLOR0_INFO) / 0x3c; | 612 | tmp = (reg - CB_COLOR0_INFO) / 0x3c; |
617 | track->cb_color_info[tmp] = radeon_get_ib_value(p, idx); | 613 | track->cb_color_info[tmp] = radeon_get_ib_value(p, idx); |
618 | if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) { | 614 | if (!p->keep_tiling_flags) { |
619 | ib[idx] |= CB_ARRAY_MODE(ARRAY_2D_TILED_THIN1); | 615 | r = evergreen_cs_packet_next_reloc(p, &reloc); |
620 | track->cb_color_info[tmp] |= CB_ARRAY_MODE(ARRAY_2D_TILED_THIN1); | 616 | if (r) { |
621 | } else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) { | 617 | dev_warn(p->dev, "bad SET_CONTEXT_REG " |
622 | ib[idx] |= CB_ARRAY_MODE(ARRAY_1D_TILED_THIN1); | 618 | "0x%04X\n", reg); |
623 | track->cb_color_info[tmp] |= CB_ARRAY_MODE(ARRAY_1D_TILED_THIN1); | 619 | return -EINVAL; |
620 | } | ||
621 | if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) { | ||
622 | ib[idx] |= CB_ARRAY_MODE(ARRAY_2D_TILED_THIN1); | ||
623 | track->cb_color_info[tmp] |= CB_ARRAY_MODE(ARRAY_2D_TILED_THIN1); | ||
624 | } else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) { | ||
625 | ib[idx] |= CB_ARRAY_MODE(ARRAY_1D_TILED_THIN1); | ||
626 | track->cb_color_info[tmp] |= CB_ARRAY_MODE(ARRAY_1D_TILED_THIN1); | ||
627 | } | ||
624 | } | 628 | } |
625 | break; | 629 | break; |
626 | case CB_COLOR8_INFO: | 630 | case CB_COLOR8_INFO: |
627 | case CB_COLOR9_INFO: | 631 | case CB_COLOR9_INFO: |
628 | case CB_COLOR10_INFO: | 632 | case CB_COLOR10_INFO: |
629 | case CB_COLOR11_INFO: | 633 | case CB_COLOR11_INFO: |
630 | r = evergreen_cs_packet_next_reloc(p, &reloc); | ||
631 | if (r) { | ||
632 | dev_warn(p->dev, "bad SET_CONTEXT_REG " | ||
633 | "0x%04X\n", reg); | ||
634 | return -EINVAL; | ||
635 | } | ||
636 | tmp = ((reg - CB_COLOR8_INFO) / 0x1c) + 8; | 634 | tmp = ((reg - CB_COLOR8_INFO) / 0x1c) + 8; |
637 | track->cb_color_info[tmp] = radeon_get_ib_value(p, idx); | 635 | track->cb_color_info[tmp] = radeon_get_ib_value(p, idx); |
638 | if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) { | 636 | if (!p->keep_tiling_flags) { |
639 | ib[idx] |= CB_ARRAY_MODE(ARRAY_2D_TILED_THIN1); | 637 | r = evergreen_cs_packet_next_reloc(p, &reloc); |
640 | track->cb_color_info[tmp] |= CB_ARRAY_MODE(ARRAY_2D_TILED_THIN1); | 638 | if (r) { |
641 | } else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) { | 639 | dev_warn(p->dev, "bad SET_CONTEXT_REG " |
642 | ib[idx] |= CB_ARRAY_MODE(ARRAY_1D_TILED_THIN1); | 640 | "0x%04X\n", reg); |
643 | track->cb_color_info[tmp] |= CB_ARRAY_MODE(ARRAY_1D_TILED_THIN1); | 641 | return -EINVAL; |
642 | } | ||
643 | if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) { | ||
644 | ib[idx] |= CB_ARRAY_MODE(ARRAY_2D_TILED_THIN1); | ||
645 | track->cb_color_info[tmp] |= CB_ARRAY_MODE(ARRAY_2D_TILED_THIN1); | ||
646 | } else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) { | ||
647 | ib[idx] |= CB_ARRAY_MODE(ARRAY_1D_TILED_THIN1); | ||
648 | track->cb_color_info[tmp] |= CB_ARRAY_MODE(ARRAY_1D_TILED_THIN1); | ||
649 | } | ||
644 | } | 650 | } |
645 | break; | 651 | break; |
646 | case CB_COLOR0_PITCH: | 652 | case CB_COLOR0_PITCH: |
@@ -1311,10 +1317,12 @@ static int evergreen_packet3_check(struct radeon_cs_parser *p, | |||
1311 | return -EINVAL; | 1317 | return -EINVAL; |
1312 | } | 1318 | } |
1313 | ib[idx+1+(i*8)+2] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); | 1319 | ib[idx+1+(i*8)+2] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); |
1314 | if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) | 1320 | if (!p->keep_tiling_flags) { |
1315 | ib[idx+1+(i*8)+1] |= TEX_ARRAY_MODE(ARRAY_2D_TILED_THIN1); | 1321 | if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) |
1316 | else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) | 1322 | ib[idx+1+(i*8)+1] |= TEX_ARRAY_MODE(ARRAY_2D_TILED_THIN1); |
1317 | ib[idx+1+(i*8)+1] |= TEX_ARRAY_MODE(ARRAY_1D_TILED_THIN1); | 1323 | else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) |
1324 | ib[idx+1+(i*8)+1] |= TEX_ARRAY_MODE(ARRAY_1D_TILED_THIN1); | ||
1325 | } | ||
1318 | texture = reloc->robj; | 1326 | texture = reloc->robj; |
1319 | /* tex mip base */ | 1327 | /* tex mip base */ |
1320 | r = evergreen_cs_packet_next_reloc(p, &reloc); | 1328 | r = evergreen_cs_packet_next_reloc(p, &reloc); |
diff --git a/drivers/gpu/drm/radeon/r300.c b/drivers/gpu/drm/radeon/r300.c index 400b26df652a..c93bc64707e1 100644 --- a/drivers/gpu/drm/radeon/r300.c +++ b/drivers/gpu/drm/radeon/r300.c | |||
@@ -701,16 +701,21 @@ static int r300_packet0_check(struct radeon_cs_parser *p, | |||
701 | return r; | 701 | return r; |
702 | } | 702 | } |
703 | 703 | ||
704 | if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) | 704 | if (p->keep_tiling_flags) { |
705 | tile_flags |= R300_TXO_MACRO_TILE; | 705 | ib[idx] = (idx_value & 31) | /* keep the 1st 5 bits */ |
706 | if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) | 706 | ((idx_value & ~31) + (u32)reloc->lobj.gpu_offset); |
707 | tile_flags |= R300_TXO_MICRO_TILE; | 707 | } else { |
708 | else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO_SQUARE) | 708 | if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) |
709 | tile_flags |= R300_TXO_MICRO_TILE_SQUARE; | 709 | tile_flags |= R300_TXO_MACRO_TILE; |
710 | 710 | if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) | |
711 | tmp = idx_value + ((u32)reloc->lobj.gpu_offset); | 711 | tile_flags |= R300_TXO_MICRO_TILE; |
712 | tmp |= tile_flags; | 712 | else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO_SQUARE) |
713 | ib[idx] = tmp; | 713 | tile_flags |= R300_TXO_MICRO_TILE_SQUARE; |
714 | |||
715 | tmp = idx_value + ((u32)reloc->lobj.gpu_offset); | ||
716 | tmp |= tile_flags; | ||
717 | ib[idx] = tmp; | ||
718 | } | ||
714 | track->textures[i].robj = reloc->robj; | 719 | track->textures[i].robj = reloc->robj; |
715 | track->tex_dirty = true; | 720 | track->tex_dirty = true; |
716 | break; | 721 | break; |
@@ -760,24 +765,26 @@ static int r300_packet0_check(struct radeon_cs_parser *p, | |||
760 | /* RB3D_COLORPITCH1 */ | 765 | /* RB3D_COLORPITCH1 */ |
761 | /* RB3D_COLORPITCH2 */ | 766 | /* RB3D_COLORPITCH2 */ |
762 | /* RB3D_COLORPITCH3 */ | 767 | /* RB3D_COLORPITCH3 */ |
763 | r = r100_cs_packet_next_reloc(p, &reloc); | 768 | if (!p->keep_tiling_flags) { |
764 | if (r) { | 769 | r = r100_cs_packet_next_reloc(p, &reloc); |
765 | DRM_ERROR("No reloc for ib[%d]=0x%04X\n", | 770 | if (r) { |
766 | idx, reg); | 771 | DRM_ERROR("No reloc for ib[%d]=0x%04X\n", |
767 | r100_cs_dump_packet(p, pkt); | 772 | idx, reg); |
768 | return r; | 773 | r100_cs_dump_packet(p, pkt); |
769 | } | 774 | return r; |
775 | } | ||
770 | 776 | ||
771 | if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) | 777 | if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) |
772 | tile_flags |= R300_COLOR_TILE_ENABLE; | 778 | tile_flags |= R300_COLOR_TILE_ENABLE; |
773 | if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) | 779 | if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) |
774 | tile_flags |= R300_COLOR_MICROTILE_ENABLE; | 780 | tile_flags |= R300_COLOR_MICROTILE_ENABLE; |
775 | else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO_SQUARE) | 781 | else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO_SQUARE) |
776 | tile_flags |= R300_COLOR_MICROTILE_SQUARE_ENABLE; | 782 | tile_flags |= R300_COLOR_MICROTILE_SQUARE_ENABLE; |
777 | 783 | ||
778 | tmp = idx_value & ~(0x7 << 16); | 784 | tmp = idx_value & ~(0x7 << 16); |
779 | tmp |= tile_flags; | 785 | tmp |= tile_flags; |
780 | ib[idx] = tmp; | 786 | ib[idx] = tmp; |
787 | } | ||
781 | i = (reg - 0x4E38) >> 2; | 788 | i = (reg - 0x4E38) >> 2; |
782 | track->cb[i].pitch = idx_value & 0x3FFE; | 789 | track->cb[i].pitch = idx_value & 0x3FFE; |
783 | switch (((idx_value >> 21) & 0xF)) { | 790 | switch (((idx_value >> 21) & 0xF)) { |
@@ -843,25 +850,26 @@ static int r300_packet0_check(struct radeon_cs_parser *p, | |||
843 | break; | 850 | break; |
844 | case 0x4F24: | 851 | case 0x4F24: |
845 | /* ZB_DEPTHPITCH */ | 852 | /* ZB_DEPTHPITCH */ |
846 | r = r100_cs_packet_next_reloc(p, &reloc); | 853 | if (!p->keep_tiling_flags) { |
847 | if (r) { | 854 | r = r100_cs_packet_next_reloc(p, &reloc); |
848 | DRM_ERROR("No reloc for ib[%d]=0x%04X\n", | 855 | if (r) { |
849 | idx, reg); | 856 | DRM_ERROR("No reloc for ib[%d]=0x%04X\n", |
850 | r100_cs_dump_packet(p, pkt); | 857 | idx, reg); |
851 | return r; | 858 | r100_cs_dump_packet(p, pkt); |
852 | } | 859 | return r; |
853 | 860 | } | |
854 | if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) | ||
855 | tile_flags |= R300_DEPTHMACROTILE_ENABLE; | ||
856 | if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) | ||
857 | tile_flags |= R300_DEPTHMICROTILE_TILED; | ||
858 | else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO_SQUARE) | ||
859 | tile_flags |= R300_DEPTHMICROTILE_TILED_SQUARE; | ||
860 | 861 | ||
861 | tmp = idx_value & ~(0x7 << 16); | 862 | if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) |
862 | tmp |= tile_flags; | 863 | tile_flags |= R300_DEPTHMACROTILE_ENABLE; |
863 | ib[idx] = tmp; | 864 | if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) |
865 | tile_flags |= R300_DEPTHMICROTILE_TILED; | ||
866 | else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO_SQUARE) | ||
867 | tile_flags |= R300_DEPTHMICROTILE_TILED_SQUARE; | ||
864 | 868 | ||
869 | tmp = idx_value & ~(0x7 << 16); | ||
870 | tmp |= tile_flags; | ||
871 | ib[idx] = tmp; | ||
872 | } | ||
865 | track->zb.pitch = idx_value & 0x3FFC; | 873 | track->zb.pitch = idx_value & 0x3FFC; |
866 | track->zb_dirty = true; | 874 | track->zb_dirty = true; |
867 | break; | 875 | break; |
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index 19afc43ad173..9cdda0b3b081 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c | |||
@@ -288,24 +288,6 @@ void r600_pm_get_dynpm_state(struct radeon_device *rdev) | |||
288 | pcie_lanes); | 288 | pcie_lanes); |
289 | } | 289 | } |
290 | 290 | ||
291 | static int r600_pm_get_type_index(struct radeon_device *rdev, | ||
292 | enum radeon_pm_state_type ps_type, | ||
293 | int instance) | ||
294 | { | ||
295 | int i; | ||
296 | int found_instance = -1; | ||
297 | |||
298 | for (i = 0; i < rdev->pm.num_power_states; i++) { | ||
299 | if (rdev->pm.power_state[i].type == ps_type) { | ||
300 | found_instance++; | ||
301 | if (found_instance == instance) | ||
302 | return i; | ||
303 | } | ||
304 | } | ||
305 | /* return default if no match */ | ||
306 | return rdev->pm.default_power_state_index; | ||
307 | } | ||
308 | |||
309 | void rs780_pm_init_profile(struct radeon_device *rdev) | 291 | void rs780_pm_init_profile(struct radeon_device *rdev) |
310 | { | 292 | { |
311 | if (rdev->pm.num_power_states == 2) { | 293 | if (rdev->pm.num_power_states == 2) { |
@@ -421,6 +403,8 @@ void rs780_pm_init_profile(struct radeon_device *rdev) | |||
421 | 403 | ||
422 | void r600_pm_init_profile(struct radeon_device *rdev) | 404 | void r600_pm_init_profile(struct radeon_device *rdev) |
423 | { | 405 | { |
406 | int idx; | ||
407 | |||
424 | if (rdev->family == CHIP_R600) { | 408 | if (rdev->family == CHIP_R600) { |
425 | /* XXX */ | 409 | /* XXX */ |
426 | /* default */ | 410 | /* default */ |
@@ -502,81 +486,43 @@ void r600_pm_init_profile(struct radeon_device *rdev) | |||
502 | rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_off_cm_idx = 0; | 486 | rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_off_cm_idx = 0; |
503 | rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_on_cm_idx = 2; | 487 | rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_on_cm_idx = 2; |
504 | /* low sh */ | 488 | /* low sh */ |
505 | if (rdev->flags & RADEON_IS_MOBILITY) { | 489 | if (rdev->flags & RADEON_IS_MOBILITY) |
506 | rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_off_ps_idx = | 490 | idx = radeon_pm_get_type_index(rdev, POWER_STATE_TYPE_BATTERY, 0); |
507 | r600_pm_get_type_index(rdev, POWER_STATE_TYPE_BATTERY, 0); | 491 | else |
508 | rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_ps_idx = | 492 | idx = radeon_pm_get_type_index(rdev, POWER_STATE_TYPE_PERFORMANCE, 0); |
509 | r600_pm_get_type_index(rdev, POWER_STATE_TYPE_BATTERY, 0); | 493 | rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_off_ps_idx = idx; |
510 | rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_off_cm_idx = 0; | 494 | rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_ps_idx = idx; |
511 | rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_cm_idx = 0; | 495 | rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_off_cm_idx = 0; |
512 | } else { | 496 | rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_cm_idx = 0; |
513 | rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_off_ps_idx = | ||
514 | r600_pm_get_type_index(rdev, POWER_STATE_TYPE_PERFORMANCE, 0); | ||
515 | rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_ps_idx = | ||
516 | r600_pm_get_type_index(rdev, POWER_STATE_TYPE_PERFORMANCE, 0); | ||
517 | rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_off_cm_idx = 0; | ||
518 | rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_cm_idx = 0; | ||
519 | } | ||
520 | /* mid sh */ | 497 | /* mid sh */ |
521 | if (rdev->flags & RADEON_IS_MOBILITY) { | 498 | rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_off_ps_idx = idx; |
522 | rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_off_ps_idx = | 499 | rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_on_ps_idx = idx; |
523 | r600_pm_get_type_index(rdev, POWER_STATE_TYPE_BATTERY, 0); | 500 | rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_off_cm_idx = 0; |
524 | rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_on_ps_idx = | 501 | rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_on_cm_idx = 1; |
525 | r600_pm_get_type_index(rdev, POWER_STATE_TYPE_BATTERY, 0); | ||
526 | rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_off_cm_idx = 0; | ||
527 | rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_on_cm_idx = 1; | ||
528 | } else { | ||
529 | rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_off_ps_idx = | ||
530 | r600_pm_get_type_index(rdev, POWER_STATE_TYPE_PERFORMANCE, 0); | ||
531 | rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_on_ps_idx = | ||
532 | r600_pm_get_type_index(rdev, POWER_STATE_TYPE_PERFORMANCE, 0); | ||
533 | rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_off_cm_idx = 0; | ||
534 | rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_on_cm_idx = 1; | ||
535 | } | ||
536 | /* high sh */ | 502 | /* high sh */ |
537 | rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_off_ps_idx = | 503 | idx = radeon_pm_get_type_index(rdev, POWER_STATE_TYPE_PERFORMANCE, 0); |
538 | r600_pm_get_type_index(rdev, POWER_STATE_TYPE_PERFORMANCE, 0); | 504 | rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_off_ps_idx = idx; |
539 | rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_on_ps_idx = | 505 | rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_on_ps_idx = idx; |
540 | r600_pm_get_type_index(rdev, POWER_STATE_TYPE_PERFORMANCE, 0); | ||
541 | rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_off_cm_idx = 0; | 506 | rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_off_cm_idx = 0; |
542 | rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_on_cm_idx = 2; | 507 | rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_on_cm_idx = 2; |
543 | /* low mh */ | 508 | /* low mh */ |
544 | if (rdev->flags & RADEON_IS_MOBILITY) { | 509 | if (rdev->flags & RADEON_IS_MOBILITY) |
545 | rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_off_ps_idx = | 510 | idx = radeon_pm_get_type_index(rdev, POWER_STATE_TYPE_BATTERY, 1); |
546 | r600_pm_get_type_index(rdev, POWER_STATE_TYPE_BATTERY, 1); | 511 | else |
547 | rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_ps_idx = | 512 | idx = radeon_pm_get_type_index(rdev, POWER_STATE_TYPE_PERFORMANCE, 1); |
548 | r600_pm_get_type_index(rdev, POWER_STATE_TYPE_BATTERY, 1); | 513 | rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_off_ps_idx = idx; |
549 | rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_off_cm_idx = 0; | 514 | rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_ps_idx = idx; |
550 | rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_cm_idx = 0; | 515 | rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_off_cm_idx = 0; |
551 | } else { | 516 | rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_cm_idx = 0; |
552 | rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_off_ps_idx = | ||
553 | r600_pm_get_type_index(rdev, POWER_STATE_TYPE_PERFORMANCE, 1); | ||
554 | rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_ps_idx = | ||
555 | r600_pm_get_type_index(rdev, POWER_STATE_TYPE_PERFORMANCE, 1); | ||
556 | rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_off_cm_idx = 0; | ||
557 | rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_cm_idx = 0; | ||
558 | } | ||
559 | /* mid mh */ | 517 | /* mid mh */ |
560 | if (rdev->flags & RADEON_IS_MOBILITY) { | 518 | rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_off_ps_idx = idx; |
561 | rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_off_ps_idx = | 519 | rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_on_ps_idx = idx; |
562 | r600_pm_get_type_index(rdev, POWER_STATE_TYPE_BATTERY, 1); | 520 | rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_off_cm_idx = 0; |
563 | rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_on_ps_idx = | 521 | rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_on_cm_idx = 1; |
564 | r600_pm_get_type_index(rdev, POWER_STATE_TYPE_BATTERY, 1); | ||
565 | rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_off_cm_idx = 0; | ||
566 | rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_on_cm_idx = 1; | ||
567 | } else { | ||
568 | rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_off_ps_idx = | ||
569 | r600_pm_get_type_index(rdev, POWER_STATE_TYPE_PERFORMANCE, 1); | ||
570 | rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_on_ps_idx = | ||
571 | r600_pm_get_type_index(rdev, POWER_STATE_TYPE_PERFORMANCE, 1); | ||
572 | rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_off_cm_idx = 0; | ||
573 | rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_on_cm_idx = 1; | ||
574 | } | ||
575 | /* high mh */ | 522 | /* high mh */ |
576 | rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_off_ps_idx = | 523 | idx = radeon_pm_get_type_index(rdev, POWER_STATE_TYPE_PERFORMANCE, 1); |
577 | r600_pm_get_type_index(rdev, POWER_STATE_TYPE_PERFORMANCE, 1); | 524 | rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_off_ps_idx = idx; |
578 | rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_on_ps_idx = | 525 | rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_on_ps_idx = idx; |
579 | r600_pm_get_type_index(rdev, POWER_STATE_TYPE_PERFORMANCE, 1); | ||
580 | rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_off_cm_idx = 0; | 526 | rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_off_cm_idx = 0; |
581 | rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_on_cm_idx = 2; | 527 | rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_on_cm_idx = 2; |
582 | } | 528 | } |
diff --git a/drivers/gpu/drm/radeon/r600_cs.c b/drivers/gpu/drm/radeon/r600_cs.c index 0a2e023c1557..cb1acffd2430 100644 --- a/drivers/gpu/drm/radeon/r600_cs.c +++ b/drivers/gpu/drm/radeon/r600_cs.c | |||
@@ -941,7 +941,8 @@ static int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) | |||
941 | track->db_depth_control = radeon_get_ib_value(p, idx); | 941 | track->db_depth_control = radeon_get_ib_value(p, idx); |
942 | break; | 942 | break; |
943 | case R_028010_DB_DEPTH_INFO: | 943 | case R_028010_DB_DEPTH_INFO: |
944 | if (r600_cs_packet_next_is_pkt3_nop(p)) { | 944 | if (!p->keep_tiling_flags && |
945 | r600_cs_packet_next_is_pkt3_nop(p)) { | ||
945 | r = r600_cs_packet_next_reloc(p, &reloc); | 946 | r = r600_cs_packet_next_reloc(p, &reloc); |
946 | if (r) { | 947 | if (r) { |
947 | dev_warn(p->dev, "bad SET_CONTEXT_REG " | 948 | dev_warn(p->dev, "bad SET_CONTEXT_REG " |
@@ -992,7 +993,8 @@ static int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) | |||
992 | case R_0280B4_CB_COLOR5_INFO: | 993 | case R_0280B4_CB_COLOR5_INFO: |
993 | case R_0280B8_CB_COLOR6_INFO: | 994 | case R_0280B8_CB_COLOR6_INFO: |
994 | case R_0280BC_CB_COLOR7_INFO: | 995 | case R_0280BC_CB_COLOR7_INFO: |
995 | if (r600_cs_packet_next_is_pkt3_nop(p)) { | 996 | if (!p->keep_tiling_flags && |
997 | r600_cs_packet_next_is_pkt3_nop(p)) { | ||
996 | r = r600_cs_packet_next_reloc(p, &reloc); | 998 | r = r600_cs_packet_next_reloc(p, &reloc); |
997 | if (r) { | 999 | if (r) { |
998 | dev_err(p->dev, "bad SET_CONTEXT_REG 0x%04X\n", reg); | 1000 | dev_err(p->dev, "bad SET_CONTEXT_REG 0x%04X\n", reg); |
@@ -1291,10 +1293,12 @@ static int r600_check_texture_resource(struct radeon_cs_parser *p, u32 idx, | |||
1291 | mip_offset <<= 8; | 1293 | mip_offset <<= 8; |
1292 | 1294 | ||
1293 | word0 = radeon_get_ib_value(p, idx + 0); | 1295 | word0 = radeon_get_ib_value(p, idx + 0); |
1294 | if (tiling_flags & RADEON_TILING_MACRO) | 1296 | if (!p->keep_tiling_flags) { |
1295 | word0 |= S_038000_TILE_MODE(V_038000_ARRAY_2D_TILED_THIN1); | 1297 | if (tiling_flags & RADEON_TILING_MACRO) |
1296 | else if (tiling_flags & RADEON_TILING_MICRO) | 1298 | word0 |= S_038000_TILE_MODE(V_038000_ARRAY_2D_TILED_THIN1); |
1297 | word0 |= S_038000_TILE_MODE(V_038000_ARRAY_1D_TILED_THIN1); | 1299 | else if (tiling_flags & RADEON_TILING_MICRO) |
1300 | word0 |= S_038000_TILE_MODE(V_038000_ARRAY_1D_TILED_THIN1); | ||
1301 | } | ||
1298 | word1 = radeon_get_ib_value(p, idx + 1); | 1302 | word1 = radeon_get_ib_value(p, idx + 1); |
1299 | w0 = G_038000_TEX_WIDTH(word0) + 1; | 1303 | w0 = G_038000_TEX_WIDTH(word0) + 1; |
1300 | h0 = G_038004_TEX_HEIGHT(word1) + 1; | 1304 | h0 = G_038004_TEX_HEIGHT(word1) + 1; |
@@ -1621,10 +1625,12 @@ static int r600_packet3_check(struct radeon_cs_parser *p, | |||
1621 | return -EINVAL; | 1625 | return -EINVAL; |
1622 | } | 1626 | } |
1623 | base_offset = (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); | 1627 | base_offset = (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); |
1624 | if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) | 1628 | if (!p->keep_tiling_flags) { |
1625 | ib[idx+1+(i*7)+0] |= S_038000_TILE_MODE(V_038000_ARRAY_2D_TILED_THIN1); | 1629 | if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) |
1626 | else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) | 1630 | ib[idx+1+(i*7)+0] |= S_038000_TILE_MODE(V_038000_ARRAY_2D_TILED_THIN1); |
1627 | ib[idx+1+(i*7)+0] |= S_038000_TILE_MODE(V_038000_ARRAY_1D_TILED_THIN1); | 1631 | else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) |
1632 | ib[idx+1+(i*7)+0] |= S_038000_TILE_MODE(V_038000_ARRAY_1D_TILED_THIN1); | ||
1633 | } | ||
1628 | texture = reloc->robj; | 1634 | texture = reloc->robj; |
1629 | /* tex mip base */ | 1635 | /* tex mip base */ |
1630 | r = r600_cs_packet_next_reloc(p, &reloc); | 1636 | r = r600_cs_packet_next_reloc(p, &reloc); |
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index b316b301152f..8227e76b5c70 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h | |||
@@ -611,7 +611,8 @@ struct radeon_cs_parser { | |||
611 | struct radeon_ib *ib; | 611 | struct radeon_ib *ib; |
612 | void *track; | 612 | void *track; |
613 | unsigned family; | 613 | unsigned family; |
614 | int parser_error; | 614 | int parser_error; |
615 | bool keep_tiling_flags; | ||
615 | }; | 616 | }; |
616 | 617 | ||
617 | extern int radeon_cs_update_pages(struct radeon_cs_parser *p, int pg_idx); | 618 | extern int radeon_cs_update_pages(struct radeon_cs_parser *p, int pg_idx); |
@@ -784,8 +785,7 @@ struct radeon_pm_clock_info { | |||
784 | 785 | ||
785 | struct radeon_power_state { | 786 | struct radeon_power_state { |
786 | enum radeon_pm_state_type type; | 787 | enum radeon_pm_state_type type; |
787 | /* XXX: use a define for num clock modes */ | 788 | struct radeon_pm_clock_info *clock_info; |
788 | struct radeon_pm_clock_info clock_info[8]; | ||
789 | /* number of valid clock modes in this power state */ | 789 | /* number of valid clock modes in this power state */ |
790 | int num_clock_modes; | 790 | int num_clock_modes; |
791 | struct radeon_pm_clock_info *default_clock_mode; | 791 | struct radeon_pm_clock_info *default_clock_mode; |
@@ -855,6 +855,9 @@ struct radeon_pm { | |||
855 | struct device *int_hwmon_dev; | 855 | struct device *int_hwmon_dev; |
856 | }; | 856 | }; |
857 | 857 | ||
858 | int radeon_pm_get_type_index(struct radeon_device *rdev, | ||
859 | enum radeon_pm_state_type ps_type, | ||
860 | int instance); | ||
858 | 861 | ||
859 | /* | 862 | /* |
860 | * Benchmarking | 863 | * Benchmarking |
@@ -1142,6 +1145,48 @@ struct r600_vram_scratch { | |||
1142 | u64 gpu_addr; | 1145 | u64 gpu_addr; |
1143 | }; | 1146 | }; |
1144 | 1147 | ||
1148 | |||
1149 | /* | ||
1150 | * Mutex which allows recursive locking from the same process. | ||
1151 | */ | ||
1152 | struct radeon_mutex { | ||
1153 | struct mutex mutex; | ||
1154 | struct task_struct *owner; | ||
1155 | int level; | ||
1156 | }; | ||
1157 | |||
1158 | static inline void radeon_mutex_init(struct radeon_mutex *mutex) | ||
1159 | { | ||
1160 | mutex_init(&mutex->mutex); | ||
1161 | mutex->owner = NULL; | ||
1162 | mutex->level = 0; | ||
1163 | } | ||
1164 | |||
1165 | static inline void radeon_mutex_lock(struct radeon_mutex *mutex) | ||
1166 | { | ||
1167 | if (mutex_trylock(&mutex->mutex)) { | ||
1168 | /* The mutex was unlocked before, so it's ours now */ | ||
1169 | mutex->owner = current; | ||
1170 | } else if (mutex->owner != current) { | ||
1171 | /* Another process locked the mutex, take it */ | ||
1172 | mutex_lock(&mutex->mutex); | ||
1173 | mutex->owner = current; | ||
1174 | } | ||
1175 | /* Otherwise the mutex was already locked by this process */ | ||
1176 | |||
1177 | mutex->level++; | ||
1178 | } | ||
1179 | |||
1180 | static inline void radeon_mutex_unlock(struct radeon_mutex *mutex) | ||
1181 | { | ||
1182 | if (--mutex->level > 0) | ||
1183 | return; | ||
1184 | |||
1185 | mutex->owner = NULL; | ||
1186 | mutex_unlock(&mutex->mutex); | ||
1187 | } | ||
1188 | |||
1189 | |||
1145 | /* | 1190 | /* |
1146 | * Core structure, functions and helpers. | 1191 | * Core structure, functions and helpers. |
1147 | */ | 1192 | */ |
@@ -1197,7 +1242,7 @@ struct radeon_device { | |||
1197 | struct radeon_gem gem; | 1242 | struct radeon_gem gem; |
1198 | struct radeon_pm pm; | 1243 | struct radeon_pm pm; |
1199 | uint32_t bios_scratch[RADEON_BIOS_NUM_SCRATCH]; | 1244 | uint32_t bios_scratch[RADEON_BIOS_NUM_SCRATCH]; |
1200 | struct mutex cs_mutex; | 1245 | struct radeon_mutex cs_mutex; |
1201 | struct radeon_wb wb; | 1246 | struct radeon_wb wb; |
1202 | struct radeon_dummy_page dummy_page; | 1247 | struct radeon_dummy_page dummy_page; |
1203 | bool gpu_lockup; | 1248 | bool gpu_lockup; |
diff --git a/drivers/gpu/drm/radeon/radeon_asic.c b/drivers/gpu/drm/radeon/radeon_asic.c index e2944566ffea..a2e1eae114ef 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.c +++ b/drivers/gpu/drm/radeon/radeon_asic.c | |||
@@ -834,7 +834,7 @@ static struct radeon_asic sumo_asic = { | |||
834 | .pm_misc = &evergreen_pm_misc, | 834 | .pm_misc = &evergreen_pm_misc, |
835 | .pm_prepare = &evergreen_pm_prepare, | 835 | .pm_prepare = &evergreen_pm_prepare, |
836 | .pm_finish = &evergreen_pm_finish, | 836 | .pm_finish = &evergreen_pm_finish, |
837 | .pm_init_profile = &rs780_pm_init_profile, | 837 | .pm_init_profile = &sumo_pm_init_profile, |
838 | .pm_get_dynpm_state = &r600_pm_get_dynpm_state, | 838 | .pm_get_dynpm_state = &r600_pm_get_dynpm_state, |
839 | .pre_page_flip = &evergreen_pre_page_flip, | 839 | .pre_page_flip = &evergreen_pre_page_flip, |
840 | .page_flip = &evergreen_page_flip, | 840 | .page_flip = &evergreen_page_flip, |
diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h index 85f14f0337e4..59914842a729 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.h +++ b/drivers/gpu/drm/radeon/radeon_asic.h | |||
@@ -413,6 +413,7 @@ extern int evergreen_cs_parse(struct radeon_cs_parser *p); | |||
413 | extern void evergreen_pm_misc(struct radeon_device *rdev); | 413 | extern void evergreen_pm_misc(struct radeon_device *rdev); |
414 | extern void evergreen_pm_prepare(struct radeon_device *rdev); | 414 | extern void evergreen_pm_prepare(struct radeon_device *rdev); |
415 | extern void evergreen_pm_finish(struct radeon_device *rdev); | 415 | extern void evergreen_pm_finish(struct radeon_device *rdev); |
416 | extern void sumo_pm_init_profile(struct radeon_device *rdev); | ||
416 | extern void evergreen_pre_page_flip(struct radeon_device *rdev, int crtc); | 417 | extern void evergreen_pre_page_flip(struct radeon_device *rdev, int crtc); |
417 | extern u32 evergreen_page_flip(struct radeon_device *rdev, int crtc, u64 crtc_base); | 418 | extern u32 evergreen_page_flip(struct radeon_device *rdev, int crtc, u64 crtc_base); |
418 | extern void evergreen_post_page_flip(struct radeon_device *rdev, int crtc); | 419 | extern void evergreen_post_page_flip(struct radeon_device *rdev, int crtc); |
diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c index 08d0b94332e6..d24baf30efcb 100644 --- a/drivers/gpu/drm/radeon/radeon_atombios.c +++ b/drivers/gpu/drm/radeon/radeon_atombios.c | |||
@@ -62,6 +62,87 @@ union atom_supported_devices { | |||
62 | struct _ATOM_SUPPORTED_DEVICES_INFO_2d1 info_2d1; | 62 | struct _ATOM_SUPPORTED_DEVICES_INFO_2d1 info_2d1; |
63 | }; | 63 | }; |
64 | 64 | ||
65 | static void radeon_lookup_i2c_gpio_quirks(struct radeon_device *rdev, | ||
66 | ATOM_GPIO_I2C_ASSIGMENT *gpio, | ||
67 | u8 index) | ||
68 | { | ||
69 | /* r4xx mask is technically not used by the hw, so patch in the legacy mask bits */ | ||
70 | if ((rdev->family == CHIP_R420) || | ||
71 | (rdev->family == CHIP_R423) || | ||
72 | (rdev->family == CHIP_RV410)) { | ||
73 | if ((le16_to_cpu(gpio->usClkMaskRegisterIndex) == 0x0018) || | ||
74 | (le16_to_cpu(gpio->usClkMaskRegisterIndex) == 0x0019) || | ||
75 | (le16_to_cpu(gpio->usClkMaskRegisterIndex) == 0x001a)) { | ||
76 | gpio->ucClkMaskShift = 0x19; | ||
77 | gpio->ucDataMaskShift = 0x18; | ||
78 | } | ||
79 | } | ||
80 | |||
81 | /* some evergreen boards have bad data for this entry */ | ||
82 | if (ASIC_IS_DCE4(rdev)) { | ||
83 | if ((index == 7) && | ||
84 | (le16_to_cpu(gpio->usClkMaskRegisterIndex) == 0x1936) && | ||
85 | (gpio->sucI2cId.ucAccess == 0)) { | ||
86 | gpio->sucI2cId.ucAccess = 0x97; | ||
87 | gpio->ucDataMaskShift = 8; | ||
88 | gpio->ucDataEnShift = 8; | ||
89 | gpio->ucDataY_Shift = 8; | ||
90 | gpio->ucDataA_Shift = 8; | ||
91 | } | ||
92 | } | ||
93 | |||
94 | /* some DCE3 boards have bad data for this entry */ | ||
95 | if (ASIC_IS_DCE3(rdev)) { | ||
96 | if ((index == 4) && | ||
97 | (le16_to_cpu(gpio->usClkMaskRegisterIndex) == 0x1fda) && | ||
98 | (gpio->sucI2cId.ucAccess == 0x94)) | ||
99 | gpio->sucI2cId.ucAccess = 0x14; | ||
100 | } | ||
101 | } | ||
102 | |||
103 | static struct radeon_i2c_bus_rec radeon_get_bus_rec_for_i2c_gpio(ATOM_GPIO_I2C_ASSIGMENT *gpio) | ||
104 | { | ||
105 | struct radeon_i2c_bus_rec i2c; | ||
106 | |||
107 | memset(&i2c, 0, sizeof(struct radeon_i2c_bus_rec)); | ||
108 | |||
109 | i2c.mask_clk_reg = le16_to_cpu(gpio->usClkMaskRegisterIndex) * 4; | ||
110 | i2c.mask_data_reg = le16_to_cpu(gpio->usDataMaskRegisterIndex) * 4; | ||
111 | i2c.en_clk_reg = le16_to_cpu(gpio->usClkEnRegisterIndex) * 4; | ||
112 | i2c.en_data_reg = le16_to_cpu(gpio->usDataEnRegisterIndex) * 4; | ||
113 | i2c.y_clk_reg = le16_to_cpu(gpio->usClkY_RegisterIndex) * 4; | ||
114 | i2c.y_data_reg = le16_to_cpu(gpio->usDataY_RegisterIndex) * 4; | ||
115 | i2c.a_clk_reg = le16_to_cpu(gpio->usClkA_RegisterIndex) * 4; | ||
116 | i2c.a_data_reg = le16_to_cpu(gpio->usDataA_RegisterIndex) * 4; | ||
117 | i2c.mask_clk_mask = (1 << gpio->ucClkMaskShift); | ||
118 | i2c.mask_data_mask = (1 << gpio->ucDataMaskShift); | ||
119 | i2c.en_clk_mask = (1 << gpio->ucClkEnShift); | ||
120 | i2c.en_data_mask = (1 << gpio->ucDataEnShift); | ||
121 | i2c.y_clk_mask = (1 << gpio->ucClkY_Shift); | ||
122 | i2c.y_data_mask = (1 << gpio->ucDataY_Shift); | ||
123 | i2c.a_clk_mask = (1 << gpio->ucClkA_Shift); | ||
124 | i2c.a_data_mask = (1 << gpio->ucDataA_Shift); | ||
125 | |||
126 | if (gpio->sucI2cId.sbfAccess.bfHW_Capable) | ||
127 | i2c.hw_capable = true; | ||
128 | else | ||
129 | i2c.hw_capable = false; | ||
130 | |||
131 | if (gpio->sucI2cId.ucAccess == 0xa0) | ||
132 | i2c.mm_i2c = true; | ||
133 | else | ||
134 | i2c.mm_i2c = false; | ||
135 | |||
136 | i2c.i2c_id = gpio->sucI2cId.ucAccess; | ||
137 | |||
138 | if (i2c.mask_clk_reg) | ||
139 | i2c.valid = true; | ||
140 | else | ||
141 | i2c.valid = false; | ||
142 | |||
143 | return i2c; | ||
144 | } | ||
145 | |||
65 | static struct radeon_i2c_bus_rec radeon_lookup_i2c_gpio(struct radeon_device *rdev, | 146 | static struct radeon_i2c_bus_rec radeon_lookup_i2c_gpio(struct radeon_device *rdev, |
66 | uint8_t id) | 147 | uint8_t id) |
67 | { | 148 | { |
@@ -85,59 +166,10 @@ static struct radeon_i2c_bus_rec radeon_lookup_i2c_gpio(struct radeon_device *rd | |||
85 | for (i = 0; i < num_indices; i++) { | 166 | for (i = 0; i < num_indices; i++) { |
86 | gpio = &i2c_info->asGPIO_Info[i]; | 167 | gpio = &i2c_info->asGPIO_Info[i]; |
87 | 168 | ||
88 | /* some evergreen boards have bad data for this entry */ | 169 | radeon_lookup_i2c_gpio_quirks(rdev, gpio, i); |
89 | if (ASIC_IS_DCE4(rdev)) { | ||
90 | if ((i == 7) && | ||
91 | (le16_to_cpu(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 | |||
101 | /* some DCE3 boards have bad data for this entry */ | ||
102 | if (ASIC_IS_DCE3(rdev)) { | ||
103 | if ((i == 4) && | ||
104 | (le16_to_cpu(gpio->usClkMaskRegisterIndex) == 0x1fda) && | ||
105 | (gpio->sucI2cId.ucAccess == 0x94)) | ||
106 | gpio->sucI2cId.ucAccess = 0x14; | ||
107 | } | ||
108 | 170 | ||
109 | if (gpio->sucI2cId.ucAccess == id) { | 171 | if (gpio->sucI2cId.ucAccess == id) { |
110 | i2c.mask_clk_reg = le16_to_cpu(gpio->usClkMaskRegisterIndex) * 4; | 172 | i2c = radeon_get_bus_rec_for_i2c_gpio(gpio); |
111 | i2c.mask_data_reg = le16_to_cpu(gpio->usDataMaskRegisterIndex) * 4; | ||
112 | i2c.en_clk_reg = le16_to_cpu(gpio->usClkEnRegisterIndex) * 4; | ||
113 | i2c.en_data_reg = le16_to_cpu(gpio->usDataEnRegisterIndex) * 4; | ||
114 | i2c.y_clk_reg = le16_to_cpu(gpio->usClkY_RegisterIndex) * 4; | ||
115 | i2c.y_data_reg = le16_to_cpu(gpio->usDataY_RegisterIndex) * 4; | ||
116 | i2c.a_clk_reg = le16_to_cpu(gpio->usClkA_RegisterIndex) * 4; | ||
117 | i2c.a_data_reg = le16_to_cpu(gpio->usDataA_RegisterIndex) * 4; | ||
118 | i2c.mask_clk_mask = (1 << gpio->ucClkMaskShift); | ||
119 | i2c.mask_data_mask = (1 << gpio->ucDataMaskShift); | ||
120 | i2c.en_clk_mask = (1 << gpio->ucClkEnShift); | ||
121 | i2c.en_data_mask = (1 << gpio->ucDataEnShift); | ||
122 | i2c.y_clk_mask = (1 << gpio->ucClkY_Shift); | ||
123 | i2c.y_data_mask = (1 << gpio->ucDataY_Shift); | ||
124 | i2c.a_clk_mask = (1 << gpio->ucClkA_Shift); | ||
125 | i2c.a_data_mask = (1 << gpio->ucDataA_Shift); | ||
126 | |||
127 | if (gpio->sucI2cId.sbfAccess.bfHW_Capable) | ||
128 | i2c.hw_capable = true; | ||
129 | else | ||
130 | i2c.hw_capable = false; | ||
131 | |||
132 | if (gpio->sucI2cId.ucAccess == 0xa0) | ||
133 | i2c.mm_i2c = true; | ||
134 | else | ||
135 | i2c.mm_i2c = false; | ||
136 | |||
137 | i2c.i2c_id = gpio->sucI2cId.ucAccess; | ||
138 | |||
139 | if (i2c.mask_clk_reg) | ||
140 | i2c.valid = true; | ||
141 | break; | 173 | break; |
142 | } | 174 | } |
143 | } | 175 | } |
@@ -157,8 +189,6 @@ void radeon_atombios_i2c_init(struct radeon_device *rdev) | |||
157 | int i, num_indices; | 189 | int i, num_indices; |
158 | char stmp[32]; | 190 | char stmp[32]; |
159 | 191 | ||
160 | memset(&i2c, 0, sizeof(struct radeon_i2c_bus_rec)); | ||
161 | |||
162 | if (atom_parse_data_header(ctx, index, &size, NULL, NULL, &data_offset)) { | 192 | if (atom_parse_data_header(ctx, index, &size, NULL, NULL, &data_offset)) { |
163 | i2c_info = (struct _ATOM_GPIO_I2C_INFO *)(ctx->bios + data_offset); | 193 | i2c_info = (struct _ATOM_GPIO_I2C_INFO *)(ctx->bios + data_offset); |
164 | 194 | ||
@@ -167,60 +197,12 @@ void radeon_atombios_i2c_init(struct radeon_device *rdev) | |||
167 | 197 | ||
168 | for (i = 0; i < num_indices; i++) { | 198 | for (i = 0; i < num_indices; i++) { |
169 | gpio = &i2c_info->asGPIO_Info[i]; | 199 | gpio = &i2c_info->asGPIO_Info[i]; |
170 | i2c.valid = false; | ||
171 | |||
172 | /* some evergreen boards have bad data for this entry */ | ||
173 | if (ASIC_IS_DCE4(rdev)) { | ||
174 | if ((i == 7) && | ||
175 | (le16_to_cpu(gpio->usClkMaskRegisterIndex) == 0x1936) && | ||
176 | (gpio->sucI2cId.ucAccess == 0)) { | ||
177 | gpio->sucI2cId.ucAccess = 0x97; | ||
178 | gpio->ucDataMaskShift = 8; | ||
179 | gpio->ucDataEnShift = 8; | ||
180 | gpio->ucDataY_Shift = 8; | ||
181 | gpio->ucDataA_Shift = 8; | ||
182 | } | ||
183 | } | ||
184 | 200 | ||
185 | /* some DCE3 boards have bad data for this entry */ | 201 | radeon_lookup_i2c_gpio_quirks(rdev, gpio, i); |
186 | if (ASIC_IS_DCE3(rdev)) { | ||
187 | if ((i == 4) && | ||
188 | (le16_to_cpu(gpio->usClkMaskRegisterIndex) == 0x1fda) && | ||
189 | (gpio->sucI2cId.ucAccess == 0x94)) | ||
190 | gpio->sucI2cId.ucAccess = 0x14; | ||
191 | } | ||
192 | 202 | ||
193 | i2c.mask_clk_reg = le16_to_cpu(gpio->usClkMaskRegisterIndex) * 4; | 203 | i2c = radeon_get_bus_rec_for_i2c_gpio(gpio); |
194 | i2c.mask_data_reg = le16_to_cpu(gpio->usDataMaskRegisterIndex) * 4; | ||
195 | i2c.en_clk_reg = le16_to_cpu(gpio->usClkEnRegisterIndex) * 4; | ||
196 | i2c.en_data_reg = le16_to_cpu(gpio->usDataEnRegisterIndex) * 4; | ||
197 | i2c.y_clk_reg = le16_to_cpu(gpio->usClkY_RegisterIndex) * 4; | ||
198 | i2c.y_data_reg = le16_to_cpu(gpio->usDataY_RegisterIndex) * 4; | ||
199 | i2c.a_clk_reg = le16_to_cpu(gpio->usClkA_RegisterIndex) * 4; | ||
200 | i2c.a_data_reg = le16_to_cpu(gpio->usDataA_RegisterIndex) * 4; | ||
201 | i2c.mask_clk_mask = (1 << gpio->ucClkMaskShift); | ||
202 | i2c.mask_data_mask = (1 << gpio->ucDataMaskShift); | ||
203 | i2c.en_clk_mask = (1 << gpio->ucClkEnShift); | ||
204 | i2c.en_data_mask = (1 << gpio->ucDataEnShift); | ||
205 | i2c.y_clk_mask = (1 << gpio->ucClkY_Shift); | ||
206 | i2c.y_data_mask = (1 << gpio->ucDataY_Shift); | ||
207 | i2c.a_clk_mask = (1 << gpio->ucClkA_Shift); | ||
208 | i2c.a_data_mask = (1 << gpio->ucDataA_Shift); | ||
209 | |||
210 | if (gpio->sucI2cId.sbfAccess.bfHW_Capable) | ||
211 | i2c.hw_capable = true; | ||
212 | else | ||
213 | i2c.hw_capable = false; | ||
214 | |||
215 | if (gpio->sucI2cId.ucAccess == 0xa0) | ||
216 | i2c.mm_i2c = true; | ||
217 | else | ||
218 | i2c.mm_i2c = false; | ||
219 | 204 | ||
220 | i2c.i2c_id = gpio->sucI2cId.ucAccess; | 205 | if (i2c.valid) { |
221 | |||
222 | if (i2c.mask_clk_reg) { | ||
223 | i2c.valid = true; | ||
224 | sprintf(stmp, "0x%x", i2c.i2c_id); | 206 | sprintf(stmp, "0x%x", i2c.i2c_id); |
225 | rdev->i2c_bus[i] = radeon_i2c_create(rdev->ddev, &i2c, stmp); | 207 | rdev->i2c_bus[i] = radeon_i2c_create(rdev->ddev, &i2c, stmp); |
226 | } | 208 | } |
@@ -1996,10 +1978,14 @@ static int radeon_atombios_parse_power_table_1_3(struct radeon_device *rdev) | |||
1996 | return state_index; | 1978 | return state_index; |
1997 | /* last mode is usually default, array is low to high */ | 1979 | /* last mode is usually default, array is low to high */ |
1998 | for (i = 0; i < num_modes; i++) { | 1980 | for (i = 0; i < num_modes; i++) { |
1981 | rdev->pm.power_state[state_index].clock_info = | ||
1982 | kzalloc(sizeof(struct radeon_pm_clock_info) * 1, GFP_KERNEL); | ||
1983 | if (!rdev->pm.power_state[state_index].clock_info) | ||
1984 | return state_index; | ||
1985 | rdev->pm.power_state[state_index].num_clock_modes = 1; | ||
1999 | rdev->pm.power_state[state_index].clock_info[0].voltage.type = VOLTAGE_NONE; | 1986 | rdev->pm.power_state[state_index].clock_info[0].voltage.type = VOLTAGE_NONE; |
2000 | switch (frev) { | 1987 | switch (frev) { |
2001 | case 1: | 1988 | case 1: |
2002 | rdev->pm.power_state[state_index].num_clock_modes = 1; | ||
2003 | rdev->pm.power_state[state_index].clock_info[0].mclk = | 1989 | rdev->pm.power_state[state_index].clock_info[0].mclk = |
2004 | le16_to_cpu(power_info->info.asPowerPlayInfo[i].usMemoryClock); | 1990 | le16_to_cpu(power_info->info.asPowerPlayInfo[i].usMemoryClock); |
2005 | rdev->pm.power_state[state_index].clock_info[0].sclk = | 1991 | rdev->pm.power_state[state_index].clock_info[0].sclk = |
@@ -2035,7 +2021,6 @@ static int radeon_atombios_parse_power_table_1_3(struct radeon_device *rdev) | |||
2035 | state_index++; | 2021 | state_index++; |
2036 | break; | 2022 | break; |
2037 | case 2: | 2023 | case 2: |
2038 | rdev->pm.power_state[state_index].num_clock_modes = 1; | ||
2039 | rdev->pm.power_state[state_index].clock_info[0].mclk = | 2024 | rdev->pm.power_state[state_index].clock_info[0].mclk = |
2040 | le32_to_cpu(power_info->info_2.asPowerPlayInfo[i].ulMemoryClock); | 2025 | le32_to_cpu(power_info->info_2.asPowerPlayInfo[i].ulMemoryClock); |
2041 | rdev->pm.power_state[state_index].clock_info[0].sclk = | 2026 | rdev->pm.power_state[state_index].clock_info[0].sclk = |
@@ -2072,7 +2057,6 @@ static int radeon_atombios_parse_power_table_1_3(struct radeon_device *rdev) | |||
2072 | state_index++; | 2057 | state_index++; |
2073 | break; | 2058 | break; |
2074 | case 3: | 2059 | case 3: |
2075 | rdev->pm.power_state[state_index].num_clock_modes = 1; | ||
2076 | rdev->pm.power_state[state_index].clock_info[0].mclk = | 2060 | rdev->pm.power_state[state_index].clock_info[0].mclk = |
2077 | le32_to_cpu(power_info->info_3.asPowerPlayInfo[i].ulMemoryClock); | 2061 | le32_to_cpu(power_info->info_3.asPowerPlayInfo[i].ulMemoryClock); |
2078 | rdev->pm.power_state[state_index].clock_info[0].sclk = | 2062 | rdev->pm.power_state[state_index].clock_info[0].sclk = |
@@ -2257,7 +2241,7 @@ static void radeon_atombios_parse_pplib_non_clock_info(struct radeon_device *rde | |||
2257 | rdev->pm.default_power_state_index = state_index; | 2241 | rdev->pm.default_power_state_index = state_index; |
2258 | rdev->pm.power_state[state_index].default_clock_mode = | 2242 | rdev->pm.power_state[state_index].default_clock_mode = |
2259 | &rdev->pm.power_state[state_index].clock_info[mode_index - 1]; | 2243 | &rdev->pm.power_state[state_index].clock_info[mode_index - 1]; |
2260 | if (ASIC_IS_DCE5(rdev)) { | 2244 | if (ASIC_IS_DCE5(rdev) && !(rdev->flags & RADEON_IS_IGP)) { |
2261 | /* NI chips post without MC ucode, so default clocks are strobe mode only */ | 2245 | /* NI chips post without MC ucode, so default clocks are strobe mode only */ |
2262 | rdev->pm.default_sclk = rdev->pm.power_state[state_index].clock_info[0].sclk; | 2246 | rdev->pm.default_sclk = rdev->pm.power_state[state_index].clock_info[0].sclk; |
2263 | rdev->pm.default_mclk = rdev->pm.power_state[state_index].clock_info[0].mclk; | 2247 | rdev->pm.default_mclk = rdev->pm.power_state[state_index].clock_info[0].mclk; |
@@ -2377,17 +2361,31 @@ static int radeon_atombios_parse_power_table_4_5(struct radeon_device *rdev) | |||
2377 | le16_to_cpu(power_info->pplib.usNonClockInfoArrayOffset) + | 2361 | le16_to_cpu(power_info->pplib.usNonClockInfoArrayOffset) + |
2378 | (power_state->v1.ucNonClockStateIndex * | 2362 | (power_state->v1.ucNonClockStateIndex * |
2379 | power_info->pplib.ucNonClockSize)); | 2363 | power_info->pplib.ucNonClockSize)); |
2380 | for (j = 0; j < (power_info->pplib.ucStateEntrySize - 1); j++) { | 2364 | rdev->pm.power_state[i].clock_info = kzalloc(sizeof(struct radeon_pm_clock_info) * |
2381 | clock_info = (union pplib_clock_info *) | 2365 | ((power_info->pplib.ucStateEntrySize - 1) ? |
2382 | (mode_info->atom_context->bios + data_offset + | 2366 | (power_info->pplib.ucStateEntrySize - 1) : 1), |
2383 | le16_to_cpu(power_info->pplib.usClockInfoArrayOffset) + | 2367 | GFP_KERNEL); |
2384 | (power_state->v1.ucClockStateIndices[j] * | 2368 | if (!rdev->pm.power_state[i].clock_info) |
2385 | power_info->pplib.ucClockInfoSize)); | 2369 | return state_index; |
2386 | valid = radeon_atombios_parse_pplib_clock_info(rdev, | 2370 | if (power_info->pplib.ucStateEntrySize - 1) { |
2387 | state_index, mode_index, | 2371 | for (j = 0; j < (power_info->pplib.ucStateEntrySize - 1); j++) { |
2388 | clock_info); | 2372 | clock_info = (union pplib_clock_info *) |
2389 | if (valid) | 2373 | (mode_info->atom_context->bios + data_offset + |
2390 | mode_index++; | 2374 | le16_to_cpu(power_info->pplib.usClockInfoArrayOffset) + |
2375 | (power_state->v1.ucClockStateIndices[j] * | ||
2376 | power_info->pplib.ucClockInfoSize)); | ||
2377 | valid = radeon_atombios_parse_pplib_clock_info(rdev, | ||
2378 | state_index, mode_index, | ||
2379 | clock_info); | ||
2380 | if (valid) | ||
2381 | mode_index++; | ||
2382 | } | ||
2383 | } else { | ||
2384 | rdev->pm.power_state[state_index].clock_info[0].mclk = | ||
2385 | rdev->clock.default_mclk; | ||
2386 | rdev->pm.power_state[state_index].clock_info[0].sclk = | ||
2387 | rdev->clock.default_sclk; | ||
2388 | mode_index++; | ||
2391 | } | 2389 | } |
2392 | rdev->pm.power_state[state_index].num_clock_modes = mode_index; | 2390 | rdev->pm.power_state[state_index].num_clock_modes = mode_index; |
2393 | if (mode_index) { | 2391 | if (mode_index) { |
@@ -2456,18 +2454,32 @@ static int radeon_atombios_parse_power_table_6(struct radeon_device *rdev) | |||
2456 | non_clock_array_index = i; /* power_state->v2.nonClockInfoIndex */ | 2454 | non_clock_array_index = i; /* power_state->v2.nonClockInfoIndex */ |
2457 | non_clock_info = (struct _ATOM_PPLIB_NONCLOCK_INFO *) | 2455 | non_clock_info = (struct _ATOM_PPLIB_NONCLOCK_INFO *) |
2458 | &non_clock_info_array->nonClockInfo[non_clock_array_index]; | 2456 | &non_clock_info_array->nonClockInfo[non_clock_array_index]; |
2459 | for (j = 0; j < power_state->v2.ucNumDPMLevels; j++) { | 2457 | rdev->pm.power_state[i].clock_info = kzalloc(sizeof(struct radeon_pm_clock_info) * |
2460 | clock_array_index = power_state->v2.clockInfoIndex[j]; | 2458 | (power_state->v2.ucNumDPMLevels ? |
2461 | /* XXX this might be an inagua bug... */ | 2459 | power_state->v2.ucNumDPMLevels : 1), |
2462 | if (clock_array_index >= clock_info_array->ucNumEntries) | 2460 | GFP_KERNEL); |
2463 | continue; | 2461 | if (!rdev->pm.power_state[i].clock_info) |
2464 | clock_info = (union pplib_clock_info *) | 2462 | return state_index; |
2465 | &clock_info_array->clockInfo[clock_array_index]; | 2463 | if (power_state->v2.ucNumDPMLevels) { |
2466 | valid = radeon_atombios_parse_pplib_clock_info(rdev, | 2464 | for (j = 0; j < power_state->v2.ucNumDPMLevels; j++) { |
2467 | state_index, mode_index, | 2465 | clock_array_index = power_state->v2.clockInfoIndex[j]; |
2468 | clock_info); | 2466 | /* XXX this might be an inagua bug... */ |
2469 | if (valid) | 2467 | if (clock_array_index >= clock_info_array->ucNumEntries) |
2470 | mode_index++; | 2468 | continue; |
2469 | clock_info = (union pplib_clock_info *) | ||
2470 | &clock_info_array->clockInfo[clock_array_index]; | ||
2471 | valid = radeon_atombios_parse_pplib_clock_info(rdev, | ||
2472 | state_index, mode_index, | ||
2473 | clock_info); | ||
2474 | if (valid) | ||
2475 | mode_index++; | ||
2476 | } | ||
2477 | } else { | ||
2478 | rdev->pm.power_state[state_index].clock_info[0].mclk = | ||
2479 | rdev->clock.default_mclk; | ||
2480 | rdev->pm.power_state[state_index].clock_info[0].sclk = | ||
2481 | rdev->clock.default_sclk; | ||
2482 | mode_index++; | ||
2471 | } | 2483 | } |
2472 | rdev->pm.power_state[state_index].num_clock_modes = mode_index; | 2484 | rdev->pm.power_state[state_index].num_clock_modes = mode_index; |
2473 | if (mode_index) { | 2485 | if (mode_index) { |
@@ -2524,19 +2536,23 @@ void radeon_atombios_get_power_modes(struct radeon_device *rdev) | |||
2524 | } else { | 2536 | } else { |
2525 | rdev->pm.power_state = kzalloc(sizeof(struct radeon_power_state), GFP_KERNEL); | 2537 | rdev->pm.power_state = kzalloc(sizeof(struct radeon_power_state), GFP_KERNEL); |
2526 | if (rdev->pm.power_state) { | 2538 | if (rdev->pm.power_state) { |
2527 | /* add the default mode */ | 2539 | rdev->pm.power_state[0].clock_info = |
2528 | rdev->pm.power_state[state_index].type = | 2540 | kzalloc(sizeof(struct radeon_pm_clock_info) * 1, GFP_KERNEL); |
2529 | POWER_STATE_TYPE_DEFAULT; | 2541 | if (rdev->pm.power_state[0].clock_info) { |
2530 | rdev->pm.power_state[state_index].num_clock_modes = 1; | 2542 | /* add the default mode */ |
2531 | rdev->pm.power_state[state_index].clock_info[0].mclk = rdev->clock.default_mclk; | 2543 | rdev->pm.power_state[state_index].type = |
2532 | rdev->pm.power_state[state_index].clock_info[0].sclk = rdev->clock.default_sclk; | 2544 | POWER_STATE_TYPE_DEFAULT; |
2533 | rdev->pm.power_state[state_index].default_clock_mode = | 2545 | rdev->pm.power_state[state_index].num_clock_modes = 1; |
2534 | &rdev->pm.power_state[state_index].clock_info[0]; | 2546 | rdev->pm.power_state[state_index].clock_info[0].mclk = rdev->clock.default_mclk; |
2535 | rdev->pm.power_state[state_index].clock_info[0].voltage.type = VOLTAGE_NONE; | 2547 | rdev->pm.power_state[state_index].clock_info[0].sclk = rdev->clock.default_sclk; |
2536 | rdev->pm.power_state[state_index].pcie_lanes = 16; | 2548 | rdev->pm.power_state[state_index].default_clock_mode = |
2537 | rdev->pm.default_power_state_index = state_index; | 2549 | &rdev->pm.power_state[state_index].clock_info[0]; |
2538 | rdev->pm.power_state[state_index].flags = 0; | 2550 | rdev->pm.power_state[state_index].clock_info[0].voltage.type = VOLTAGE_NONE; |
2539 | state_index++; | 2551 | rdev->pm.power_state[state_index].pcie_lanes = 16; |
2552 | rdev->pm.default_power_state_index = state_index; | ||
2553 | rdev->pm.power_state[state_index].flags = 0; | ||
2554 | state_index++; | ||
2555 | } | ||
2540 | } | 2556 | } |
2541 | } | 2557 | } |
2542 | 2558 | ||
diff --git a/drivers/gpu/drm/radeon/radeon_benchmark.c b/drivers/gpu/drm/radeon/radeon_benchmark.c index 5cafc90de7f8..17e1a9b2d8fb 100644 --- a/drivers/gpu/drm/radeon/radeon_benchmark.c +++ b/drivers/gpu/drm/radeon/radeon_benchmark.c | |||
@@ -98,7 +98,7 @@ static void radeon_benchmark_move(struct radeon_device *rdev, unsigned size, | |||
98 | struct radeon_bo *sobj = NULL; | 98 | struct radeon_bo *sobj = NULL; |
99 | uint64_t saddr, daddr; | 99 | uint64_t saddr, daddr; |
100 | int r, n; | 100 | int r, n; |
101 | unsigned int time; | 101 | int time; |
102 | 102 | ||
103 | n = RADEON_BENCHMARK_ITERATIONS; | 103 | n = RADEON_BENCHMARK_ITERATIONS; |
104 | r = radeon_bo_create(rdev, size, PAGE_SIZE, true, sdomain, &sobj); | 104 | r = radeon_bo_create(rdev, size, PAGE_SIZE, true, sdomain, &sobj); |
diff --git a/drivers/gpu/drm/radeon/radeon_combios.c b/drivers/gpu/drm/radeon/radeon_combios.c index 8bf83c4b4147..81fc100be7e1 100644 --- a/drivers/gpu/drm/radeon/radeon_combios.c +++ b/drivers/gpu/drm/radeon/radeon_combios.c | |||
@@ -2563,14 +2563,17 @@ void radeon_combios_get_power_modes(struct radeon_device *rdev) | |||
2563 | 2563 | ||
2564 | /* allocate 2 power states */ | 2564 | /* allocate 2 power states */ |
2565 | rdev->pm.power_state = kzalloc(sizeof(struct radeon_power_state) * 2, GFP_KERNEL); | 2565 | rdev->pm.power_state = kzalloc(sizeof(struct radeon_power_state) * 2, GFP_KERNEL); |
2566 | if (!rdev->pm.power_state) { | 2566 | if (rdev->pm.power_state) { |
2567 | rdev->pm.default_power_state_index = state_index; | 2567 | /* allocate 1 clock mode per state */ |
2568 | rdev->pm.num_power_states = 0; | 2568 | rdev->pm.power_state[0].clock_info = |
2569 | 2569 | kzalloc(sizeof(struct radeon_pm_clock_info) * 1, GFP_KERNEL); | |
2570 | rdev->pm.current_power_state_index = rdev->pm.default_power_state_index; | 2570 | rdev->pm.power_state[1].clock_info = |
2571 | rdev->pm.current_clock_mode_index = 0; | 2571 | kzalloc(sizeof(struct radeon_pm_clock_info) * 1, GFP_KERNEL); |
2572 | return; | 2572 | if (!rdev->pm.power_state[0].clock_info || |
2573 | } | 2573 | !rdev->pm.power_state[1].clock_info) |
2574 | goto pm_failed; | ||
2575 | } else | ||
2576 | goto pm_failed; | ||
2574 | 2577 | ||
2575 | /* check for a thermal chip */ | 2578 | /* check for a thermal chip */ |
2576 | offset = combios_get_table_offset(dev, COMBIOS_OVERDRIVE_INFO_TABLE); | 2579 | offset = combios_get_table_offset(dev, COMBIOS_OVERDRIVE_INFO_TABLE); |
@@ -2735,6 +2738,14 @@ default_mode: | |||
2735 | 2738 | ||
2736 | rdev->pm.current_power_state_index = rdev->pm.default_power_state_index; | 2739 | rdev->pm.current_power_state_index = rdev->pm.default_power_state_index; |
2737 | rdev->pm.current_clock_mode_index = 0; | 2740 | rdev->pm.current_clock_mode_index = 0; |
2741 | return; | ||
2742 | |||
2743 | pm_failed: | ||
2744 | rdev->pm.default_power_state_index = state_index; | ||
2745 | rdev->pm.num_power_states = 0; | ||
2746 | |||
2747 | rdev->pm.current_power_state_index = rdev->pm.default_power_state_index; | ||
2748 | rdev->pm.current_clock_mode_index = 0; | ||
2738 | } | 2749 | } |
2739 | 2750 | ||
2740 | void radeon_external_tmds_setup(struct drm_encoder *encoder) | 2751 | void radeon_external_tmds_setup(struct drm_encoder *encoder) |
diff --git a/drivers/gpu/drm/radeon/radeon_cs.c b/drivers/gpu/drm/radeon/radeon_cs.c index fae00c0d75aa..29afd71e0840 100644 --- a/drivers/gpu/drm/radeon/radeon_cs.c +++ b/drivers/gpu/drm/radeon/radeon_cs.c | |||
@@ -93,7 +93,7 @@ int radeon_cs_parser_init(struct radeon_cs_parser *p, void *data) | |||
93 | { | 93 | { |
94 | struct drm_radeon_cs *cs = data; | 94 | struct drm_radeon_cs *cs = data; |
95 | uint64_t *chunk_array_ptr; | 95 | uint64_t *chunk_array_ptr; |
96 | unsigned size, i; | 96 | unsigned size, i, flags = 0; |
97 | 97 | ||
98 | if (!cs->num_chunks) { | 98 | if (!cs->num_chunks) { |
99 | return 0; | 99 | return 0; |
@@ -140,6 +140,10 @@ int radeon_cs_parser_init(struct radeon_cs_parser *p, void *data) | |||
140 | if (p->chunks[i].length_dw == 0) | 140 | if (p->chunks[i].length_dw == 0) |
141 | return -EINVAL; | 141 | return -EINVAL; |
142 | } | 142 | } |
143 | if (p->chunks[i].chunk_id == RADEON_CHUNK_ID_FLAGS && | ||
144 | !p->chunks[i].length_dw) { | ||
145 | return -EINVAL; | ||
146 | } | ||
143 | 147 | ||
144 | p->chunks[i].length_dw = user_chunk.length_dw; | 148 | p->chunks[i].length_dw = user_chunk.length_dw; |
145 | p->chunks[i].user_ptr = (void __user *)(unsigned long)user_chunk.chunk_data; | 149 | p->chunks[i].user_ptr = (void __user *)(unsigned long)user_chunk.chunk_data; |
@@ -155,6 +159,9 @@ int radeon_cs_parser_init(struct radeon_cs_parser *p, void *data) | |||
155 | p->chunks[i].user_ptr, size)) { | 159 | p->chunks[i].user_ptr, size)) { |
156 | return -EFAULT; | 160 | return -EFAULT; |
157 | } | 161 | } |
162 | if (p->chunks[i].chunk_id == RADEON_CHUNK_ID_FLAGS) { | ||
163 | flags = p->chunks[i].kdata[0]; | ||
164 | } | ||
158 | } else { | 165 | } else { |
159 | p->chunks[i].kpage[0] = kmalloc(PAGE_SIZE, GFP_KERNEL); | 166 | p->chunks[i].kpage[0] = kmalloc(PAGE_SIZE, GFP_KERNEL); |
160 | p->chunks[i].kpage[1] = kmalloc(PAGE_SIZE, GFP_KERNEL); | 167 | p->chunks[i].kpage[1] = kmalloc(PAGE_SIZE, GFP_KERNEL); |
@@ -174,6 +181,8 @@ int radeon_cs_parser_init(struct radeon_cs_parser *p, void *data) | |||
174 | p->chunks[p->chunk_ib_idx].length_dw); | 181 | p->chunks[p->chunk_ib_idx].length_dw); |
175 | return -EINVAL; | 182 | return -EINVAL; |
176 | } | 183 | } |
184 | |||
185 | p->keep_tiling_flags = (flags & RADEON_CS_KEEP_TILING_FLAGS) != 0; | ||
177 | return 0; | 186 | return 0; |
178 | } | 187 | } |
179 | 188 | ||
@@ -222,7 +231,7 @@ int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) | |||
222 | struct radeon_cs_chunk *ib_chunk; | 231 | struct radeon_cs_chunk *ib_chunk; |
223 | int r; | 232 | int r; |
224 | 233 | ||
225 | mutex_lock(&rdev->cs_mutex); | 234 | radeon_mutex_lock(&rdev->cs_mutex); |
226 | /* initialize parser */ | 235 | /* initialize parser */ |
227 | memset(&parser, 0, sizeof(struct radeon_cs_parser)); | 236 | memset(&parser, 0, sizeof(struct radeon_cs_parser)); |
228 | parser.filp = filp; | 237 | parser.filp = filp; |
@@ -233,14 +242,14 @@ int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) | |||
233 | if (r) { | 242 | if (r) { |
234 | DRM_ERROR("Failed to initialize parser !\n"); | 243 | DRM_ERROR("Failed to initialize parser !\n"); |
235 | radeon_cs_parser_fini(&parser, r); | 244 | radeon_cs_parser_fini(&parser, r); |
236 | mutex_unlock(&rdev->cs_mutex); | 245 | radeon_mutex_unlock(&rdev->cs_mutex); |
237 | return r; | 246 | return r; |
238 | } | 247 | } |
239 | r = radeon_ib_get(rdev, &parser.ib); | 248 | r = radeon_ib_get(rdev, &parser.ib); |
240 | if (r) { | 249 | if (r) { |
241 | DRM_ERROR("Failed to get ib !\n"); | 250 | DRM_ERROR("Failed to get ib !\n"); |
242 | radeon_cs_parser_fini(&parser, r); | 251 | radeon_cs_parser_fini(&parser, r); |
243 | mutex_unlock(&rdev->cs_mutex); | 252 | radeon_mutex_unlock(&rdev->cs_mutex); |
244 | return r; | 253 | return r; |
245 | } | 254 | } |
246 | r = radeon_cs_parser_relocs(&parser); | 255 | r = radeon_cs_parser_relocs(&parser); |
@@ -248,7 +257,7 @@ int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) | |||
248 | if (r != -ERESTARTSYS) | 257 | if (r != -ERESTARTSYS) |
249 | DRM_ERROR("Failed to parse relocation %d!\n", r); | 258 | DRM_ERROR("Failed to parse relocation %d!\n", r); |
250 | radeon_cs_parser_fini(&parser, r); | 259 | radeon_cs_parser_fini(&parser, r); |
251 | mutex_unlock(&rdev->cs_mutex); | 260 | radeon_mutex_unlock(&rdev->cs_mutex); |
252 | return r; | 261 | return r; |
253 | } | 262 | } |
254 | /* Copy the packet into the IB, the parser will read from the | 263 | /* Copy the packet into the IB, the parser will read from the |
@@ -260,14 +269,14 @@ int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) | |||
260 | if (r || parser.parser_error) { | 269 | if (r || parser.parser_error) { |
261 | DRM_ERROR("Invalid command stream !\n"); | 270 | DRM_ERROR("Invalid command stream !\n"); |
262 | radeon_cs_parser_fini(&parser, r); | 271 | radeon_cs_parser_fini(&parser, r); |
263 | mutex_unlock(&rdev->cs_mutex); | 272 | radeon_mutex_unlock(&rdev->cs_mutex); |
264 | return r; | 273 | return r; |
265 | } | 274 | } |
266 | r = radeon_cs_finish_pages(&parser); | 275 | r = radeon_cs_finish_pages(&parser); |
267 | if (r) { | 276 | if (r) { |
268 | DRM_ERROR("Invalid command stream !\n"); | 277 | DRM_ERROR("Invalid command stream !\n"); |
269 | radeon_cs_parser_fini(&parser, r); | 278 | radeon_cs_parser_fini(&parser, r); |
270 | mutex_unlock(&rdev->cs_mutex); | 279 | radeon_mutex_unlock(&rdev->cs_mutex); |
271 | return r; | 280 | return r; |
272 | } | 281 | } |
273 | r = radeon_ib_schedule(rdev, parser.ib); | 282 | r = radeon_ib_schedule(rdev, parser.ib); |
@@ -275,7 +284,7 @@ int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) | |||
275 | DRM_ERROR("Failed to schedule IB !\n"); | 284 | DRM_ERROR("Failed to schedule IB !\n"); |
276 | } | 285 | } |
277 | radeon_cs_parser_fini(&parser, r); | 286 | radeon_cs_parser_fini(&parser, r); |
278 | mutex_unlock(&rdev->cs_mutex); | 287 | radeon_mutex_unlock(&rdev->cs_mutex); |
279 | return r; | 288 | return r; |
280 | } | 289 | } |
281 | 290 | ||
diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index c33bc914d93d..c4d00a171411 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c | |||
@@ -716,7 +716,7 @@ int radeon_device_init(struct radeon_device *rdev, | |||
716 | 716 | ||
717 | /* mutex initialization are all done here so we | 717 | /* mutex initialization are all done here so we |
718 | * can recall function without having locking issues */ | 718 | * can recall function without having locking issues */ |
719 | mutex_init(&rdev->cs_mutex); | 719 | radeon_mutex_init(&rdev->cs_mutex); |
720 | mutex_init(&rdev->ib_pool.mutex); | 720 | mutex_init(&rdev->ib_pool.mutex); |
721 | mutex_init(&rdev->cp.mutex); | 721 | mutex_init(&rdev->cp.mutex); |
722 | mutex_init(&rdev->dc_hw_i2c_mutex); | 722 | mutex_init(&rdev->dc_hw_i2c_mutex); |
@@ -955,6 +955,9 @@ int radeon_gpu_reset(struct radeon_device *rdev) | |||
955 | int r; | 955 | int r; |
956 | int resched; | 956 | int resched; |
957 | 957 | ||
958 | /* Prevent CS ioctl from interfering */ | ||
959 | radeon_mutex_lock(&rdev->cs_mutex); | ||
960 | |||
958 | radeon_save_bios_scratch_regs(rdev); | 961 | radeon_save_bios_scratch_regs(rdev); |
959 | /* block TTM */ | 962 | /* block TTM */ |
960 | resched = ttm_bo_lock_delayed_workqueue(&rdev->mman.bdev); | 963 | resched = ttm_bo_lock_delayed_workqueue(&rdev->mman.bdev); |
@@ -967,10 +970,15 @@ int radeon_gpu_reset(struct radeon_device *rdev) | |||
967 | radeon_restore_bios_scratch_regs(rdev); | 970 | radeon_restore_bios_scratch_regs(rdev); |
968 | drm_helper_resume_force_mode(rdev->ddev); | 971 | drm_helper_resume_force_mode(rdev->ddev); |
969 | ttm_bo_unlock_delayed_workqueue(&rdev->mman.bdev, resched); | 972 | ttm_bo_unlock_delayed_workqueue(&rdev->mman.bdev, resched); |
970 | return 0; | ||
971 | } | 973 | } |
972 | /* bad news, how to tell it to userspace ? */ | 974 | |
973 | dev_info(rdev->dev, "GPU reset failed\n"); | 975 | radeon_mutex_unlock(&rdev->cs_mutex); |
976 | |||
977 | if (r) { | ||
978 | /* bad news, how to tell it to userspace ? */ | ||
979 | dev_info(rdev->dev, "GPU reset failed\n"); | ||
980 | } | ||
981 | |||
974 | return r; | 982 | return r; |
975 | } | 983 | } |
976 | 984 | ||
diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c index a0b35e909489..71499fc3daf5 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.c +++ b/drivers/gpu/drm/radeon/radeon_drv.c | |||
@@ -53,9 +53,10 @@ | |||
53 | * 2.9.0 - r600 tiling (s3tc,rgtc) working, SET_PREDICATION packet 3 on r600 + eg, backend query | 53 | * 2.9.0 - r600 tiling (s3tc,rgtc) working, SET_PREDICATION packet 3 on r600 + eg, backend query |
54 | * 2.10.0 - fusion 2D tiling | 54 | * 2.10.0 - fusion 2D tiling |
55 | * 2.11.0 - backend map, initial compute support for the CS checker | 55 | * 2.11.0 - backend map, initial compute support for the CS checker |
56 | * 2.12.0 - RADEON_CS_KEEP_TILING_FLAGS | ||
56 | */ | 57 | */ |
57 | #define KMS_DRIVER_MAJOR 2 | 58 | #define KMS_DRIVER_MAJOR 2 |
58 | #define KMS_DRIVER_MINOR 11 | 59 | #define KMS_DRIVER_MINOR 12 |
59 | #define KMS_DRIVER_PATCHLEVEL 0 | 60 | #define KMS_DRIVER_PATCHLEVEL 0 |
60 | int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags); | 61 | int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags); |
61 | int radeon_driver_unload_kms(struct drm_device *dev); | 62 | int radeon_driver_unload_kms(struct drm_device *dev); |
diff --git a/drivers/gpu/drm/radeon/radeon_legacy_crtc.c b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c index 41a5d48e657b..daadf2111040 100644 --- a/drivers/gpu/drm/radeon/radeon_legacy_crtc.c +++ b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c | |||
@@ -991,12 +991,6 @@ static bool radeon_crtc_mode_fixup(struct drm_crtc *crtc, | |||
991 | struct drm_display_mode *mode, | 991 | struct drm_display_mode *mode, |
992 | struct drm_display_mode *adjusted_mode) | 992 | struct drm_display_mode *adjusted_mode) |
993 | { | 993 | { |
994 | struct drm_device *dev = crtc->dev; | ||
995 | struct radeon_device *rdev = dev->dev_private; | ||
996 | |||
997 | /* adjust pm to upcoming mode change */ | ||
998 | radeon_pm_compute_clocks(rdev); | ||
999 | |||
1000 | if (!radeon_crtc_scaling_mode_fixup(crtc, mode, adjusted_mode)) | 994 | if (!radeon_crtc_scaling_mode_fixup(crtc, mode, adjusted_mode)) |
1001 | return false; | 995 | return false; |
1002 | return true; | 996 | return true; |
diff --git a/drivers/gpu/drm/radeon/radeon_pm.c b/drivers/gpu/drm/radeon/radeon_pm.c index 6fabe89fa6a1..78a665bd9519 100644 --- a/drivers/gpu/drm/radeon/radeon_pm.c +++ b/drivers/gpu/drm/radeon/radeon_pm.c | |||
@@ -53,6 +53,24 @@ static void radeon_pm_set_clocks(struct radeon_device *rdev); | |||
53 | 53 | ||
54 | #define ACPI_AC_CLASS "ac_adapter" | 54 | #define ACPI_AC_CLASS "ac_adapter" |
55 | 55 | ||
56 | int radeon_pm_get_type_index(struct radeon_device *rdev, | ||
57 | enum radeon_pm_state_type ps_type, | ||
58 | int instance) | ||
59 | { | ||
60 | int i; | ||
61 | int found_instance = -1; | ||
62 | |||
63 | for (i = 0; i < rdev->pm.num_power_states; i++) { | ||
64 | if (rdev->pm.power_state[i].type == ps_type) { | ||
65 | found_instance++; | ||
66 | if (found_instance == instance) | ||
67 | return i; | ||
68 | } | ||
69 | } | ||
70 | /* return default if no match */ | ||
71 | return rdev->pm.default_power_state_index; | ||
72 | } | ||
73 | |||
56 | #ifdef CONFIG_ACPI | 74 | #ifdef CONFIG_ACPI |
57 | static int radeon_acpi_event(struct notifier_block *nb, | 75 | static int radeon_acpi_event(struct notifier_block *nb, |
58 | unsigned long val, | 76 | unsigned long val, |
diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c index 617b64678fc6..0bb0f5f713e6 100644 --- a/drivers/gpu/drm/ttm/ttm_bo.c +++ b/drivers/gpu/drm/ttm/ttm_bo.c | |||
@@ -574,10 +574,16 @@ retry: | |||
574 | return ret; | 574 | return ret; |
575 | 575 | ||
576 | spin_lock(&glob->lru_lock); | 576 | spin_lock(&glob->lru_lock); |
577 | |||
578 | if (unlikely(list_empty(&bo->ddestroy))) { | ||
579 | spin_unlock(&glob->lru_lock); | ||
580 | return 0; | ||
581 | } | ||
582 | |||
577 | ret = ttm_bo_reserve_locked(bo, interruptible, | 583 | ret = ttm_bo_reserve_locked(bo, interruptible, |
578 | no_wait_reserve, false, 0); | 584 | no_wait_reserve, false, 0); |
579 | 585 | ||
580 | if (unlikely(ret != 0) || list_empty(&bo->ddestroy)) { | 586 | if (unlikely(ret != 0)) { |
581 | spin_unlock(&glob->lru_lock); | 587 | spin_unlock(&glob->lru_lock); |
582 | return ret; | 588 | return ret; |
583 | } | 589 | } |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c index 03daefa73397..880e285d7578 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | |||
@@ -105,6 +105,10 @@ int vmw_du_crtc_cursor_set(struct drm_crtc *crtc, struct drm_file *file_priv, | |||
105 | struct vmw_dma_buffer *dmabuf = NULL; | 105 | struct vmw_dma_buffer *dmabuf = NULL; |
106 | int ret; | 106 | int ret; |
107 | 107 | ||
108 | /* A lot of the code assumes this */ | ||
109 | if (handle && (width != 64 || height != 64)) | ||
110 | return -EINVAL; | ||
111 | |||
108 | if (handle) { | 112 | if (handle) { |
109 | ret = vmw_user_surface_lookup_handle(dev_priv, tfile, | 113 | ret = vmw_user_surface_lookup_handle(dev_priv, tfile, |
110 | handle, &surface); | 114 | handle, &surface); |
@@ -410,8 +414,9 @@ static int do_surface_dirty_sou(struct vmw_private *dev_priv, | |||
410 | top = clips->y1; | 414 | top = clips->y1; |
411 | bottom = clips->y2; | 415 | bottom = clips->y2; |
412 | 416 | ||
413 | clips_ptr = clips; | 417 | /* skip the first clip rect */ |
414 | for (i = 1; i < num_clips; i++, clips_ptr += inc) { | 418 | for (i = 1, clips_ptr = clips + inc; |
419 | i < num_clips; i++, clips_ptr += inc) { | ||
415 | left = min_t(int, left, (int)clips_ptr->x1); | 420 | left = min_t(int, left, (int)clips_ptr->x1); |
416 | right = max_t(int, right, (int)clips_ptr->x2); | 421 | right = max_t(int, right, (int)clips_ptr->x2); |
417 | top = min_t(int, top, (int)clips_ptr->y1); | 422 | top = min_t(int, top, (int)clips_ptr->y1); |
@@ -1323,7 +1328,10 @@ int vmw_kms_close(struct vmw_private *dev_priv) | |||
1323 | * drm_encoder_cleanup which takes the lock we deadlock. | 1328 | * drm_encoder_cleanup which takes the lock we deadlock. |
1324 | */ | 1329 | */ |
1325 | drm_mode_config_cleanup(dev_priv->dev); | 1330 | drm_mode_config_cleanup(dev_priv->dev); |
1326 | vmw_kms_close_legacy_display_system(dev_priv); | 1331 | if (dev_priv->sou_priv) |
1332 | vmw_kms_close_screen_object_display(dev_priv); | ||
1333 | else | ||
1334 | vmw_kms_close_legacy_display_system(dev_priv); | ||
1327 | return 0; | 1335 | return 0; |
1328 | } | 1336 | } |
1329 | 1337 | ||