diff options
author | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2013-05-26 21:40:19 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2013-05-26 21:40:19 -0400 |
commit | f35c69b736e4f910d7447346980145212c283570 (patch) | |
tree | 824b90cd870e6de07bbba19d761c1c74cf1fb4a7 /drivers/gpu | |
parent | cd4373984a5903276f52777a6003425e023eaa7e (diff) | |
parent | e4aa937ec75df0eea0bee03bffa3303ad36c986b (diff) |
Merge 3.10-rc3 into char-misc-next
We want the changes in here.
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/gpu')
44 files changed, 654 insertions, 323 deletions
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index 3a8f7e6db295..e7e92429d10f 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c | |||
@@ -78,6 +78,10 @@ void drm_warn_on_modeset_not_all_locked(struct drm_device *dev) | |||
78 | { | 78 | { |
79 | struct drm_crtc *crtc; | 79 | struct drm_crtc *crtc; |
80 | 80 | ||
81 | /* Locking is currently fubar in the panic handler. */ | ||
82 | if (oops_in_progress) | ||
83 | return; | ||
84 | |||
81 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) | 85 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) |
82 | WARN_ON(!mutex_is_locked(&crtc->mutex)); | 86 | WARN_ON(!mutex_is_locked(&crtc->mutex)); |
83 | 87 | ||
@@ -246,6 +250,7 @@ char *drm_get_connector_status_name(enum drm_connector_status status) | |||
246 | else | 250 | else |
247 | return "unknown"; | 251 | return "unknown"; |
248 | } | 252 | } |
253 | EXPORT_SYMBOL(drm_get_connector_status_name); | ||
249 | 254 | ||
250 | /** | 255 | /** |
251 | * drm_mode_object_get - allocate a new modeset identifier | 256 | * drm_mode_object_get - allocate a new modeset identifier |
diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c index e974f9309b72..ed1334e27c33 100644 --- a/drivers/gpu/drm/drm_crtc_helper.c +++ b/drivers/gpu/drm/drm_crtc_helper.c | |||
@@ -121,6 +121,7 @@ int drm_helper_probe_single_connector_modes(struct drm_connector *connector, | |||
121 | connector->helper_private; | 121 | connector->helper_private; |
122 | int count = 0; | 122 | int count = 0; |
123 | int mode_flags = 0; | 123 | int mode_flags = 0; |
124 | bool verbose_prune = true; | ||
124 | 125 | ||
125 | DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", connector->base.id, | 126 | DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", connector->base.id, |
126 | drm_get_connector_name(connector)); | 127 | drm_get_connector_name(connector)); |
@@ -149,6 +150,7 @@ int drm_helper_probe_single_connector_modes(struct drm_connector *connector, | |||
149 | DRM_DEBUG_KMS("[CONNECTOR:%d:%s] disconnected\n", | 150 | DRM_DEBUG_KMS("[CONNECTOR:%d:%s] disconnected\n", |
150 | connector->base.id, drm_get_connector_name(connector)); | 151 | connector->base.id, drm_get_connector_name(connector)); |
151 | drm_mode_connector_update_edid_property(connector, NULL); | 152 | drm_mode_connector_update_edid_property(connector, NULL); |
153 | verbose_prune = false; | ||
152 | goto prune; | 154 | goto prune; |
153 | } | 155 | } |
154 | 156 | ||
@@ -182,7 +184,7 @@ int drm_helper_probe_single_connector_modes(struct drm_connector *connector, | |||
182 | } | 184 | } |
183 | 185 | ||
184 | prune: | 186 | prune: |
185 | drm_mode_prune_invalid(dev, &connector->modes, true); | 187 | drm_mode_prune_invalid(dev, &connector->modes, verbose_prune); |
186 | 188 | ||
187 | if (list_empty(&connector->modes)) | 189 | if (list_empty(&connector->modes)) |
188 | return 0; | 190 | return 0; |
@@ -1005,12 +1007,20 @@ static void output_poll_execute(struct work_struct *work) | |||
1005 | continue; | 1007 | continue; |
1006 | 1008 | ||
1007 | connector->status = connector->funcs->detect(connector, false); | 1009 | connector->status = connector->funcs->detect(connector, false); |
1008 | DRM_DEBUG_KMS("[CONNECTOR:%d:%s] status updated from %d to %d\n", | 1010 | if (old_status != connector->status) { |
1009 | connector->base.id, | 1011 | const char *old, *new; |
1010 | drm_get_connector_name(connector), | 1012 | |
1011 | old_status, connector->status); | 1013 | old = drm_get_connector_status_name(old_status); |
1012 | if (old_status != connector->status) | 1014 | new = drm_get_connector_status_name(connector->status); |
1015 | |||
1016 | DRM_DEBUG_KMS("[CONNECTOR:%d:%s] " | ||
1017 | "status updated from %s to %s\n", | ||
1018 | connector->base.id, | ||
1019 | drm_get_connector_name(connector), | ||
1020 | old, new); | ||
1021 | |||
1013 | changed = true; | 1022 | changed = true; |
1023 | } | ||
1014 | } | 1024 | } |
1015 | 1025 | ||
1016 | mutex_unlock(&dev->mode_config.mutex); | 1026 | mutex_unlock(&dev->mode_config.mutex); |
@@ -1083,10 +1093,11 @@ void drm_helper_hpd_irq_event(struct drm_device *dev) | |||
1083 | old_status = connector->status; | 1093 | old_status = connector->status; |
1084 | 1094 | ||
1085 | connector->status = connector->funcs->detect(connector, false); | 1095 | connector->status = connector->funcs->detect(connector, false); |
1086 | DRM_DEBUG_KMS("[CONNECTOR:%d:%s] status updated from %d to %d\n", | 1096 | DRM_DEBUG_KMS("[CONNECTOR:%d:%s] status updated from %s to %s\n", |
1087 | connector->base.id, | 1097 | connector->base.id, |
1088 | drm_get_connector_name(connector), | 1098 | drm_get_connector_name(connector), |
1089 | old_status, connector->status); | 1099 | drm_get_connector_status_name(old_status), |
1100 | drm_get_connector_status_name(connector->status)); | ||
1090 | if (old_status != connector->status) | 1101 | if (old_status != connector->status) |
1091 | changed = true; | 1102 | changed = true; |
1092 | } | 1103 | } |
diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c index 8d4f29075af5..9cc247f55502 100644 --- a/drivers/gpu/drm/drm_drv.c +++ b/drivers/gpu/drm/drm_drv.c | |||
@@ -57,7 +57,7 @@ static int drm_version(struct drm_device *dev, void *data, | |||
57 | struct drm_file *file_priv); | 57 | struct drm_file *file_priv); |
58 | 58 | ||
59 | #define DRM_IOCTL_DEF(ioctl, _func, _flags) \ | 59 | #define DRM_IOCTL_DEF(ioctl, _func, _flags) \ |
60 | [DRM_IOCTL_NR(ioctl)] = {.cmd = ioctl, .func = _func, .flags = _flags, .cmd_drv = 0} | 60 | [DRM_IOCTL_NR(ioctl)] = {.cmd = ioctl, .func = _func, .flags = _flags, .cmd_drv = 0, .name = #ioctl} |
61 | 61 | ||
62 | /** Ioctl table */ | 62 | /** Ioctl table */ |
63 | static const struct drm_ioctl_desc drm_ioctls[] = { | 63 | static const struct drm_ioctl_desc drm_ioctls[] = { |
@@ -375,7 +375,7 @@ long drm_ioctl(struct file *filp, | |||
375 | { | 375 | { |
376 | struct drm_file *file_priv = filp->private_data; | 376 | struct drm_file *file_priv = filp->private_data; |
377 | struct drm_device *dev; | 377 | struct drm_device *dev; |
378 | const struct drm_ioctl_desc *ioctl; | 378 | const struct drm_ioctl_desc *ioctl = NULL; |
379 | drm_ioctl_t *func; | 379 | drm_ioctl_t *func; |
380 | unsigned int nr = DRM_IOCTL_NR(cmd); | 380 | unsigned int nr = DRM_IOCTL_NR(cmd); |
381 | int retcode = -EINVAL; | 381 | int retcode = -EINVAL; |
@@ -392,11 +392,6 @@ long drm_ioctl(struct file *filp, | |||
392 | atomic_inc(&dev->counts[_DRM_STAT_IOCTLS]); | 392 | atomic_inc(&dev->counts[_DRM_STAT_IOCTLS]); |
393 | ++file_priv->ioctl_count; | 393 | ++file_priv->ioctl_count; |
394 | 394 | ||
395 | DRM_DEBUG("pid=%d, cmd=0x%02x, nr=0x%02x, dev 0x%lx, auth=%d\n", | ||
396 | task_pid_nr(current), cmd, nr, | ||
397 | (long)old_encode_dev(file_priv->minor->device), | ||
398 | file_priv->authenticated); | ||
399 | |||
400 | if ((nr >= DRM_CORE_IOCTL_COUNT) && | 395 | if ((nr >= DRM_CORE_IOCTL_COUNT) && |
401 | ((nr < DRM_COMMAND_BASE) || (nr >= DRM_COMMAND_END))) | 396 | ((nr < DRM_COMMAND_BASE) || (nr >= DRM_COMMAND_END))) |
402 | goto err_i1; | 397 | goto err_i1; |
@@ -417,6 +412,11 @@ long drm_ioctl(struct file *filp, | |||
417 | } else | 412 | } else |
418 | goto err_i1; | 413 | goto err_i1; |
419 | 414 | ||
415 | DRM_DEBUG("pid=%d, dev=0x%lx, auth=%d, %s\n", | ||
416 | task_pid_nr(current), | ||
417 | (long)old_encode_dev(file_priv->minor->device), | ||
418 | file_priv->authenticated, ioctl->name); | ||
419 | |||
420 | /* Do not trust userspace, use our own definition */ | 420 | /* Do not trust userspace, use our own definition */ |
421 | func = ioctl->func; | 421 | func = ioctl->func; |
422 | /* is there a local override? */ | 422 | /* is there a local override? */ |
@@ -471,6 +471,12 @@ long drm_ioctl(struct file *filp, | |||
471 | } | 471 | } |
472 | 472 | ||
473 | err_i1: | 473 | err_i1: |
474 | if (!ioctl) | ||
475 | DRM_DEBUG("invalid iotcl: pid=%d, dev=0x%lx, auth=%d, cmd=0x%02x, nr=0x%02x\n", | ||
476 | task_pid_nr(current), | ||
477 | (long)old_encode_dev(file_priv->minor->device), | ||
478 | file_priv->authenticated, cmd, nr); | ||
479 | |||
474 | if (kdata != stack_kdata) | 480 | if (kdata != stack_kdata) |
475 | kfree(kdata); | 481 | kfree(kdata); |
476 | atomic_dec(&dev->ioctl_count); | 482 | atomic_dec(&dev->ioctl_count); |
diff --git a/drivers/gpu/drm/drm_encoder_slave.c b/drivers/gpu/drm/drm_encoder_slave.c index 48c52f7df4e6..0cfb60f54766 100644 --- a/drivers/gpu/drm/drm_encoder_slave.c +++ b/drivers/gpu/drm/drm_encoder_slave.c | |||
@@ -54,16 +54,12 @@ int drm_i2c_encoder_init(struct drm_device *dev, | |||
54 | struct i2c_adapter *adap, | 54 | struct i2c_adapter *adap, |
55 | const struct i2c_board_info *info) | 55 | const struct i2c_board_info *info) |
56 | { | 56 | { |
57 | char modalias[sizeof(I2C_MODULE_PREFIX) | ||
58 | + I2C_NAME_SIZE]; | ||
59 | struct module *module = NULL; | 57 | struct module *module = NULL; |
60 | struct i2c_client *client; | 58 | struct i2c_client *client; |
61 | struct drm_i2c_encoder_driver *encoder_drv; | 59 | struct drm_i2c_encoder_driver *encoder_drv; |
62 | int err = 0; | 60 | int err = 0; |
63 | 61 | ||
64 | snprintf(modalias, sizeof(modalias), | 62 | request_module("%s%s", I2C_MODULE_PREFIX, info->type); |
65 | "%s%s", I2C_MODULE_PREFIX, info->type); | ||
66 | request_module(modalias); | ||
67 | 63 | ||
68 | client = i2c_new_device(adap, info); | 64 | client = i2c_new_device(adap, info); |
69 | if (!client) { | 65 | if (!client) { |
diff --git a/drivers/gpu/drm/drm_mm.c b/drivers/gpu/drm/drm_mm.c index db1e2d6f90d7..07cf99cc8862 100644 --- a/drivers/gpu/drm/drm_mm.c +++ b/drivers/gpu/drm/drm_mm.c | |||
@@ -755,33 +755,35 @@ void drm_mm_debug_table(struct drm_mm *mm, const char *prefix) | |||
755 | EXPORT_SYMBOL(drm_mm_debug_table); | 755 | EXPORT_SYMBOL(drm_mm_debug_table); |
756 | 756 | ||
757 | #if defined(CONFIG_DEBUG_FS) | 757 | #if defined(CONFIG_DEBUG_FS) |
758 | int drm_mm_dump_table(struct seq_file *m, struct drm_mm *mm) | 758 | static unsigned long drm_mm_dump_hole(struct seq_file *m, struct drm_mm_node *entry) |
759 | { | 759 | { |
760 | struct drm_mm_node *entry; | ||
761 | unsigned long total_used = 0, total_free = 0, total = 0; | ||
762 | unsigned long hole_start, hole_end, hole_size; | 760 | unsigned long hole_start, hole_end, hole_size; |
763 | 761 | ||
764 | hole_start = drm_mm_hole_node_start(&mm->head_node); | 762 | if (entry->hole_follows) { |
765 | hole_end = drm_mm_hole_node_end(&mm->head_node); | 763 | hole_start = drm_mm_hole_node_start(entry); |
766 | hole_size = hole_end - hole_start; | 764 | hole_end = drm_mm_hole_node_end(entry); |
767 | if (hole_size) | 765 | hole_size = hole_end - hole_start; |
768 | seq_printf(m, "0x%08lx-0x%08lx: 0x%08lx: free\n", | 766 | seq_printf(m, "0x%08lx-0x%08lx: 0x%08lx: free\n", |
769 | hole_start, hole_end, hole_size); | 767 | hole_start, hole_end, hole_size); |
770 | total_free += hole_size; | 768 | return hole_size; |
769 | } | ||
770 | |||
771 | return 0; | ||
772 | } | ||
773 | |||
774 | int drm_mm_dump_table(struct seq_file *m, struct drm_mm *mm) | ||
775 | { | ||
776 | struct drm_mm_node *entry; | ||
777 | unsigned long total_used = 0, total_free = 0, total = 0; | ||
778 | |||
779 | total_free += drm_mm_dump_hole(m, &mm->head_node); | ||
771 | 780 | ||
772 | drm_mm_for_each_node(entry, mm) { | 781 | drm_mm_for_each_node(entry, mm) { |
773 | seq_printf(m, "0x%08lx-0x%08lx: 0x%08lx: used\n", | 782 | seq_printf(m, "0x%08lx-0x%08lx: 0x%08lx: used\n", |
774 | entry->start, entry->start + entry->size, | 783 | entry->start, entry->start + entry->size, |
775 | entry->size); | 784 | entry->size); |
776 | total_used += entry->size; | 785 | total_used += entry->size; |
777 | if (entry->hole_follows) { | 786 | total_free += drm_mm_dump_hole(m, entry); |
778 | hole_start = drm_mm_hole_node_start(entry); | ||
779 | hole_end = drm_mm_hole_node_end(entry); | ||
780 | hole_size = hole_end - hole_start; | ||
781 | seq_printf(m, "0x%08lx-0x%08lx: 0x%08lx: free\n", | ||
782 | hole_start, hole_end, hole_size); | ||
783 | total_free += hole_size; | ||
784 | } | ||
785 | } | 787 | } |
786 | total = total_free + total_used; | 788 | total = total_free + total_used; |
787 | 789 | ||
diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c index faa79df02648..a371ff865a88 100644 --- a/drivers/gpu/drm/drm_modes.c +++ b/drivers/gpu/drm/drm_modes.c | |||
@@ -1143,6 +1143,7 @@ bool drm_mode_parse_command_line_for_connector(const char *mode_option, | |||
1143 | was_digit = false; | 1143 | was_digit = false; |
1144 | } else | 1144 | } else |
1145 | goto done; | 1145 | goto done; |
1146 | break; | ||
1146 | case '0' ... '9': | 1147 | case '0' ... '9': |
1147 | was_digit = true; | 1148 | was_digit = true; |
1148 | break; | 1149 | break; |
diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c b/drivers/gpu/drm/exynos/exynos_hdmi.c index bbfc3840080c..6652597586a1 100644 --- a/drivers/gpu/drm/exynos/exynos_hdmi.c +++ b/drivers/gpu/drm/exynos/exynos_hdmi.c | |||
@@ -2005,11 +2005,6 @@ static int hdmi_probe(struct platform_device *pdev) | |||
2005 | } | 2005 | } |
2006 | 2006 | ||
2007 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 2007 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
2008 | if (!res) { | ||
2009 | DRM_ERROR("failed to find registers\n"); | ||
2010 | return -ENOENT; | ||
2011 | } | ||
2012 | |||
2013 | hdata->regs = devm_ioremap_resource(&pdev->dev, res); | 2008 | hdata->regs = devm_ioremap_resource(&pdev->dev, res); |
2014 | if (IS_ERR(hdata->regs)) | 2009 | if (IS_ERR(hdata->regs)) |
2015 | return PTR_ERR(hdata->regs); | 2010 | return PTR_ERR(hdata->regs); |
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 6be940effefd..6165535d15f0 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c | |||
@@ -1045,6 +1045,8 @@ static int __wait_seqno(struct intel_ring_buffer *ring, u32 seqno, | |||
1045 | if (timeout) { | 1045 | if (timeout) { |
1046 | struct timespec sleep_time = timespec_sub(now, before); | 1046 | struct timespec sleep_time = timespec_sub(now, before); |
1047 | *timeout = timespec_sub(*timeout, sleep_time); | 1047 | *timeout = timespec_sub(*timeout, sleep_time); |
1048 | if (!timespec_valid(timeout)) /* i.e. negative time remains */ | ||
1049 | set_normalized_timespec(timeout, 0, 0); | ||
1048 | } | 1050 | } |
1049 | 1051 | ||
1050 | switch (end) { | 1052 | switch (end) { |
@@ -1053,8 +1055,6 @@ static int __wait_seqno(struct intel_ring_buffer *ring, u32 seqno, | |||
1053 | case -ERESTARTSYS: /* Signal */ | 1055 | case -ERESTARTSYS: /* Signal */ |
1054 | return (int)end; | 1056 | return (int)end; |
1055 | case 0: /* Timeout */ | 1057 | case 0: /* Timeout */ |
1056 | if (timeout) | ||
1057 | set_normalized_timespec(timeout, 0, 0); | ||
1058 | return -ETIME; | 1058 | return -ETIME; |
1059 | default: /* Completed */ | 1059 | default: /* Completed */ |
1060 | WARN_ON(end < 0); /* We're not aware of other errors */ | 1060 | WARN_ON(end < 0); /* We're not aware of other errors */ |
@@ -2377,10 +2377,8 @@ i915_gem_wait_ioctl(struct drm_device *dev, void *data, struct drm_file *file) | |||
2377 | mutex_unlock(&dev->struct_mutex); | 2377 | mutex_unlock(&dev->struct_mutex); |
2378 | 2378 | ||
2379 | ret = __wait_seqno(ring, seqno, reset_counter, true, timeout); | 2379 | ret = __wait_seqno(ring, seqno, reset_counter, true, timeout); |
2380 | if (timeout) { | 2380 | if (timeout) |
2381 | WARN_ON(!timespec_valid(timeout)); | ||
2382 | args->timeout_ns = timespec_to_ns(timeout); | 2381 | args->timeout_ns = timespec_to_ns(timeout); |
2383 | } | ||
2384 | return ret; | 2382 | return ret; |
2385 | 2383 | ||
2386 | out: | 2384 | out: |
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index dca614de71b6..bdb0d7717bc7 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c | |||
@@ -709,15 +709,6 @@ static inline size_t gen6_get_stolen_size(u16 snb_gmch_ctl) | |||
709 | return snb_gmch_ctl << 25; /* 32 MB units */ | 709 | return snb_gmch_ctl << 25; /* 32 MB units */ |
710 | } | 710 | } |
711 | 711 | ||
712 | static inline size_t gen7_get_stolen_size(u16 snb_gmch_ctl) | ||
713 | { | ||
714 | static const int stolen_decoder[] = { | ||
715 | 0, 0, 0, 0, 0, 32, 48, 64, 128, 256, 96, 160, 224, 352}; | ||
716 | snb_gmch_ctl >>= IVB_GMCH_GMS_SHIFT; | ||
717 | snb_gmch_ctl &= IVB_GMCH_GMS_MASK; | ||
718 | return stolen_decoder[snb_gmch_ctl] << 20; | ||
719 | } | ||
720 | |||
721 | static int gen6_gmch_probe(struct drm_device *dev, | 712 | static int gen6_gmch_probe(struct drm_device *dev, |
722 | size_t *gtt_total, | 713 | size_t *gtt_total, |
723 | size_t *stolen, | 714 | size_t *stolen, |
@@ -747,11 +738,7 @@ static int gen6_gmch_probe(struct drm_device *dev, | |||
747 | pci_read_config_word(dev->pdev, SNB_GMCH_CTRL, &snb_gmch_ctl); | 738 | pci_read_config_word(dev->pdev, SNB_GMCH_CTRL, &snb_gmch_ctl); |
748 | gtt_size = gen6_get_total_gtt_size(snb_gmch_ctl); | 739 | gtt_size = gen6_get_total_gtt_size(snb_gmch_ctl); |
749 | 740 | ||
750 | if (IS_GEN7(dev) && !IS_VALLEYVIEW(dev)) | 741 | *stolen = gen6_get_stolen_size(snb_gmch_ctl); |
751 | *stolen = gen7_get_stolen_size(snb_gmch_ctl); | ||
752 | else | ||
753 | *stolen = gen6_get_stolen_size(snb_gmch_ctl); | ||
754 | |||
755 | *gtt_total = (gtt_size / sizeof(gen6_gtt_pte_t)) << PAGE_SHIFT; | 742 | *gtt_total = (gtt_size / sizeof(gen6_gtt_pte_t)) << PAGE_SHIFT; |
756 | 743 | ||
757 | /* For Modern GENs the PTEs and register space are split in the BAR */ | 744 | /* For Modern GENs the PTEs and register space are split in the BAR */ |
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 83f9c26e1adb..2d6b62e42daf 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h | |||
@@ -46,8 +46,6 @@ | |||
46 | #define SNB_GMCH_GGMS_MASK 0x3 | 46 | #define SNB_GMCH_GGMS_MASK 0x3 |
47 | #define SNB_GMCH_GMS_SHIFT 3 /* Graphics Mode Select */ | 47 | #define SNB_GMCH_GMS_SHIFT 3 /* Graphics Mode Select */ |
48 | #define SNB_GMCH_GMS_MASK 0x1f | 48 | #define SNB_GMCH_GMS_MASK 0x1f |
49 | #define IVB_GMCH_GMS_SHIFT 4 | ||
50 | #define IVB_GMCH_GMS_MASK 0xf | ||
51 | 49 | ||
52 | 50 | ||
53 | /* PCI config space */ | 51 | /* PCI config space */ |
diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index 26a0a570f92e..fb961bb81903 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c | |||
@@ -1265,6 +1265,8 @@ static void intel_ddi_pre_enable(struct intel_encoder *intel_encoder) | |||
1265 | intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON); | 1265 | intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON); |
1266 | intel_dp_start_link_train(intel_dp); | 1266 | intel_dp_start_link_train(intel_dp); |
1267 | intel_dp_complete_link_train(intel_dp); | 1267 | intel_dp_complete_link_train(intel_dp); |
1268 | if (port != PORT_A) | ||
1269 | intel_dp_stop_link_train(intel_dp); | ||
1268 | } | 1270 | } |
1269 | } | 1271 | } |
1270 | 1272 | ||
@@ -1326,6 +1328,9 @@ static void intel_enable_ddi(struct intel_encoder *intel_encoder) | |||
1326 | } else if (type == INTEL_OUTPUT_EDP) { | 1328 | } else if (type == INTEL_OUTPUT_EDP) { |
1327 | struct intel_dp *intel_dp = enc_to_intel_dp(encoder); | 1329 | struct intel_dp *intel_dp = enc_to_intel_dp(encoder); |
1328 | 1330 | ||
1331 | if (port == PORT_A) | ||
1332 | intel_dp_stop_link_train(intel_dp); | ||
1333 | |||
1329 | ironlake_edp_backlight_on(intel_dp); | 1334 | ironlake_edp_backlight_on(intel_dp); |
1330 | } | 1335 | } |
1331 | 1336 | ||
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index fb2fbc1e08b9..3d704b706a8d 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c | |||
@@ -702,6 +702,9 @@ intel_dp_compute_config(struct intel_encoder *encoder, | |||
702 | /* Walk through all bpp values. Luckily they're all nicely spaced with 2 | 702 | /* Walk through all bpp values. Luckily they're all nicely spaced with 2 |
703 | * bpc in between. */ | 703 | * bpc in between. */ |
704 | bpp = min_t(int, 8*3, pipe_config->pipe_bpp); | 704 | bpp = min_t(int, 8*3, pipe_config->pipe_bpp); |
705 | if (is_edp(intel_dp) && dev_priv->edp.bpp) | ||
706 | bpp = min_t(int, bpp, dev_priv->edp.bpp); | ||
707 | |||
705 | for (; bpp >= 6*3; bpp -= 2*3) { | 708 | for (; bpp >= 6*3; bpp -= 2*3) { |
706 | mode_rate = intel_dp_link_required(target_clock, bpp); | 709 | mode_rate = intel_dp_link_required(target_clock, bpp); |
707 | 710 | ||
@@ -739,6 +742,7 @@ found: | |||
739 | intel_dp->link_bw = bws[clock]; | 742 | intel_dp->link_bw = bws[clock]; |
740 | intel_dp->lane_count = lane_count; | 743 | intel_dp->lane_count = lane_count; |
741 | adjusted_mode->clock = drm_dp_bw_code_to_link_rate(intel_dp->link_bw); | 744 | adjusted_mode->clock = drm_dp_bw_code_to_link_rate(intel_dp->link_bw); |
745 | pipe_config->pipe_bpp = bpp; | ||
742 | pipe_config->pixel_target_clock = target_clock; | 746 | pipe_config->pixel_target_clock = target_clock; |
743 | 747 | ||
744 | DRM_DEBUG_KMS("DP link bw %02x lane count %d clock %d bpp %d\n", | 748 | DRM_DEBUG_KMS("DP link bw %02x lane count %d clock %d bpp %d\n", |
@@ -751,20 +755,6 @@ found: | |||
751 | target_clock, adjusted_mode->clock, | 755 | target_clock, adjusted_mode->clock, |
752 | &pipe_config->dp_m_n); | 756 | &pipe_config->dp_m_n); |
753 | 757 | ||
754 | /* | ||
755 | * XXX: We have a strange regression where using the vbt edp bpp value | ||
756 | * for the link bw computation results in black screens, the panel only | ||
757 | * works when we do the computation at the usual 24bpp (but still | ||
758 | * requires us to use 18bpp). Until that's fully debugged, stay | ||
759 | * bug-for-bug compatible with the old code. | ||
760 | */ | ||
761 | if (is_edp(intel_dp) && dev_priv->edp.bpp) { | ||
762 | DRM_DEBUG_KMS("clamping display bpc (was %d) to eDP (%d)\n", | ||
763 | bpp, dev_priv->edp.bpp); | ||
764 | bpp = min_t(int, bpp, dev_priv->edp.bpp); | ||
765 | } | ||
766 | pipe_config->pipe_bpp = bpp; | ||
767 | |||
768 | return true; | 758 | return true; |
769 | } | 759 | } |
770 | 760 | ||
@@ -1389,6 +1379,7 @@ static void intel_enable_dp(struct intel_encoder *encoder) | |||
1389 | ironlake_edp_panel_on(intel_dp); | 1379 | ironlake_edp_panel_on(intel_dp); |
1390 | ironlake_edp_panel_vdd_off(intel_dp, true); | 1380 | ironlake_edp_panel_vdd_off(intel_dp, true); |
1391 | intel_dp_complete_link_train(intel_dp); | 1381 | intel_dp_complete_link_train(intel_dp); |
1382 | intel_dp_stop_link_train(intel_dp); | ||
1392 | ironlake_edp_backlight_on(intel_dp); | 1383 | ironlake_edp_backlight_on(intel_dp); |
1393 | } | 1384 | } |
1394 | 1385 | ||
@@ -1711,10 +1702,9 @@ intel_dp_set_link_train(struct intel_dp *intel_dp, | |||
1711 | struct drm_i915_private *dev_priv = dev->dev_private; | 1702 | struct drm_i915_private *dev_priv = dev->dev_private; |
1712 | enum port port = intel_dig_port->port; | 1703 | enum port port = intel_dig_port->port; |
1713 | int ret; | 1704 | int ret; |
1714 | uint32_t temp; | ||
1715 | 1705 | ||
1716 | if (HAS_DDI(dev)) { | 1706 | if (HAS_DDI(dev)) { |
1717 | temp = I915_READ(DP_TP_CTL(port)); | 1707 | uint32_t temp = I915_READ(DP_TP_CTL(port)); |
1718 | 1708 | ||
1719 | if (dp_train_pat & DP_LINK_SCRAMBLING_DISABLE) | 1709 | if (dp_train_pat & DP_LINK_SCRAMBLING_DISABLE) |
1720 | temp |= DP_TP_CTL_SCRAMBLE_DISABLE; | 1710 | temp |= DP_TP_CTL_SCRAMBLE_DISABLE; |
@@ -1724,18 +1714,6 @@ intel_dp_set_link_train(struct intel_dp *intel_dp, | |||
1724 | temp &= ~DP_TP_CTL_LINK_TRAIN_MASK; | 1714 | temp &= ~DP_TP_CTL_LINK_TRAIN_MASK; |
1725 | switch (dp_train_pat & DP_TRAINING_PATTERN_MASK) { | 1715 | switch (dp_train_pat & DP_TRAINING_PATTERN_MASK) { |
1726 | case DP_TRAINING_PATTERN_DISABLE: | 1716 | case DP_TRAINING_PATTERN_DISABLE: |
1727 | |||
1728 | if (port != PORT_A) { | ||
1729 | temp |= DP_TP_CTL_LINK_TRAIN_IDLE; | ||
1730 | I915_WRITE(DP_TP_CTL(port), temp); | ||
1731 | |||
1732 | if (wait_for((I915_READ(DP_TP_STATUS(port)) & | ||
1733 | DP_TP_STATUS_IDLE_DONE), 1)) | ||
1734 | DRM_ERROR("Timed out waiting for DP idle patterns\n"); | ||
1735 | |||
1736 | temp &= ~DP_TP_CTL_LINK_TRAIN_MASK; | ||
1737 | } | ||
1738 | |||
1739 | temp |= DP_TP_CTL_LINK_TRAIN_NORMAL; | 1717 | temp |= DP_TP_CTL_LINK_TRAIN_NORMAL; |
1740 | 1718 | ||
1741 | break; | 1719 | break; |
@@ -1811,6 +1789,37 @@ intel_dp_set_link_train(struct intel_dp *intel_dp, | |||
1811 | return true; | 1789 | return true; |
1812 | } | 1790 | } |
1813 | 1791 | ||
1792 | static void intel_dp_set_idle_link_train(struct intel_dp *intel_dp) | ||
1793 | { | ||
1794 | struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); | ||
1795 | struct drm_device *dev = intel_dig_port->base.base.dev; | ||
1796 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
1797 | enum port port = intel_dig_port->port; | ||
1798 | uint32_t val; | ||
1799 | |||
1800 | if (!HAS_DDI(dev)) | ||
1801 | return; | ||
1802 | |||
1803 | val = I915_READ(DP_TP_CTL(port)); | ||
1804 | val &= ~DP_TP_CTL_LINK_TRAIN_MASK; | ||
1805 | val |= DP_TP_CTL_LINK_TRAIN_IDLE; | ||
1806 | I915_WRITE(DP_TP_CTL(port), val); | ||
1807 | |||
1808 | /* | ||
1809 | * On PORT_A we can have only eDP in SST mode. There the only reason | ||
1810 | * we need to set idle transmission mode is to work around a HW issue | ||
1811 | * where we enable the pipe while not in idle link-training mode. | ||
1812 | * In this case there is requirement to wait for a minimum number of | ||
1813 | * idle patterns to be sent. | ||
1814 | */ | ||
1815 | if (port == PORT_A) | ||
1816 | return; | ||
1817 | |||
1818 | if (wait_for((I915_READ(DP_TP_STATUS(port)) & DP_TP_STATUS_IDLE_DONE), | ||
1819 | 1)) | ||
1820 | DRM_ERROR("Timed out waiting for DP idle patterns\n"); | ||
1821 | } | ||
1822 | |||
1814 | /* Enable corresponding port and start training pattern 1 */ | 1823 | /* Enable corresponding port and start training pattern 1 */ |
1815 | void | 1824 | void |
1816 | intel_dp_start_link_train(struct intel_dp *intel_dp) | 1825 | intel_dp_start_link_train(struct intel_dp *intel_dp) |
@@ -1953,10 +1962,19 @@ intel_dp_complete_link_train(struct intel_dp *intel_dp) | |||
1953 | ++tries; | 1962 | ++tries; |
1954 | } | 1963 | } |
1955 | 1964 | ||
1965 | intel_dp_set_idle_link_train(intel_dp); | ||
1966 | |||
1967 | intel_dp->DP = DP; | ||
1968 | |||
1956 | if (channel_eq) | 1969 | if (channel_eq) |
1957 | DRM_DEBUG_KMS("Channel EQ done. DP Training successful\n"); | 1970 | DRM_DEBUG_KMS("Channel EQ done. DP Training successful\n"); |
1958 | 1971 | ||
1959 | intel_dp_set_link_train(intel_dp, DP, DP_TRAINING_PATTERN_DISABLE); | 1972 | } |
1973 | |||
1974 | void intel_dp_stop_link_train(struct intel_dp *intel_dp) | ||
1975 | { | ||
1976 | intel_dp_set_link_train(intel_dp, intel_dp->DP, | ||
1977 | DP_TRAINING_PATTERN_DISABLE); | ||
1960 | } | 1978 | } |
1961 | 1979 | ||
1962 | static void | 1980 | static void |
@@ -2164,6 +2182,7 @@ intel_dp_check_link_status(struct intel_dp *intel_dp) | |||
2164 | drm_get_encoder_name(&intel_encoder->base)); | 2182 | drm_get_encoder_name(&intel_encoder->base)); |
2165 | intel_dp_start_link_train(intel_dp); | 2183 | intel_dp_start_link_train(intel_dp); |
2166 | intel_dp_complete_link_train(intel_dp); | 2184 | intel_dp_complete_link_train(intel_dp); |
2185 | intel_dp_stop_link_train(intel_dp); | ||
2167 | } | 2186 | } |
2168 | } | 2187 | } |
2169 | 2188 | ||
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index b5b6d19e6dd3..624a9e6b8d71 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h | |||
@@ -499,6 +499,7 @@ extern void intel_dp_init_connector(struct intel_digital_port *intel_dig_port, | |||
499 | extern void intel_dp_init_link_config(struct intel_dp *intel_dp); | 499 | extern void intel_dp_init_link_config(struct intel_dp *intel_dp); |
500 | extern void intel_dp_start_link_train(struct intel_dp *intel_dp); | 500 | extern void intel_dp_start_link_train(struct intel_dp *intel_dp); |
501 | extern void intel_dp_complete_link_train(struct intel_dp *intel_dp); | 501 | extern void intel_dp_complete_link_train(struct intel_dp *intel_dp); |
502 | extern void intel_dp_stop_link_train(struct intel_dp *intel_dp); | ||
502 | extern void intel_dp_sink_dpms(struct intel_dp *intel_dp, int mode); | 503 | extern void intel_dp_sink_dpms(struct intel_dp *intel_dp, int mode); |
503 | extern void intel_dp_encoder_destroy(struct drm_encoder *encoder); | 504 | extern void intel_dp_encoder_destroy(struct drm_encoder *encoder); |
504 | extern void intel_dp_check_link_status(struct intel_dp *intel_dp); | 505 | extern void intel_dp_check_link_status(struct intel_dp *intel_dp); |
diff --git a/drivers/gpu/drm/i915/intel_fb.c b/drivers/gpu/drm/i915/intel_fb.c index 0e19e575a1b4..6b7c3ca2c035 100644 --- a/drivers/gpu/drm/i915/intel_fb.c +++ b/drivers/gpu/drm/i915/intel_fb.c | |||
@@ -262,10 +262,22 @@ void intel_fbdev_fini(struct drm_device *dev) | |||
262 | void intel_fbdev_set_suspend(struct drm_device *dev, int state) | 262 | void intel_fbdev_set_suspend(struct drm_device *dev, int state) |
263 | { | 263 | { |
264 | drm_i915_private_t *dev_priv = dev->dev_private; | 264 | drm_i915_private_t *dev_priv = dev->dev_private; |
265 | if (!dev_priv->fbdev) | 265 | struct intel_fbdev *ifbdev = dev_priv->fbdev; |
266 | struct fb_info *info; | ||
267 | |||
268 | if (!ifbdev) | ||
266 | return; | 269 | return; |
267 | 270 | ||
268 | fb_set_suspend(dev_priv->fbdev->helper.fbdev, state); | 271 | info = ifbdev->helper.fbdev; |
272 | |||
273 | /* On resume from hibernation: If the object is shmemfs backed, it has | ||
274 | * been restored from swap. If the object is stolen however, it will be | ||
275 | * full of whatever garbage was left in there. | ||
276 | */ | ||
277 | if (!state && ifbdev->ifb.obj->stolen) | ||
278 | memset_io(info->screen_base, 0, info->screen_size); | ||
279 | |||
280 | fb_set_suspend(info, state); | ||
269 | } | 281 | } |
270 | 282 | ||
271 | MODULE_LICENSE("GPL and additional rights"); | 283 | MODULE_LICENSE("GPL and additional rights"); |
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index de3b0dc5658b..aa01128ff192 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c | |||
@@ -1301,17 +1301,17 @@ static void valleyview_update_wm(struct drm_device *dev) | |||
1301 | 1301 | ||
1302 | vlv_update_drain_latency(dev); | 1302 | vlv_update_drain_latency(dev); |
1303 | 1303 | ||
1304 | if (g4x_compute_wm0(dev, 0, | 1304 | if (g4x_compute_wm0(dev, PIPE_A, |
1305 | &valleyview_wm_info, latency_ns, | 1305 | &valleyview_wm_info, latency_ns, |
1306 | &valleyview_cursor_wm_info, latency_ns, | 1306 | &valleyview_cursor_wm_info, latency_ns, |
1307 | &planea_wm, &cursora_wm)) | 1307 | &planea_wm, &cursora_wm)) |
1308 | enabled |= 1; | 1308 | enabled |= 1 << PIPE_A; |
1309 | 1309 | ||
1310 | if (g4x_compute_wm0(dev, 1, | 1310 | if (g4x_compute_wm0(dev, PIPE_B, |
1311 | &valleyview_wm_info, latency_ns, | 1311 | &valleyview_wm_info, latency_ns, |
1312 | &valleyview_cursor_wm_info, latency_ns, | 1312 | &valleyview_cursor_wm_info, latency_ns, |
1313 | &planeb_wm, &cursorb_wm)) | 1313 | &planeb_wm, &cursorb_wm)) |
1314 | enabled |= 2; | 1314 | enabled |= 1 << PIPE_B; |
1315 | 1315 | ||
1316 | if (single_plane_enabled(enabled) && | 1316 | if (single_plane_enabled(enabled) && |
1317 | g4x_compute_srwm(dev, ffs(enabled) - 1, | 1317 | g4x_compute_srwm(dev, ffs(enabled) - 1, |
@@ -1357,17 +1357,17 @@ static void g4x_update_wm(struct drm_device *dev) | |||
1357 | int plane_sr, cursor_sr; | 1357 | int plane_sr, cursor_sr; |
1358 | unsigned int enabled = 0; | 1358 | unsigned int enabled = 0; |
1359 | 1359 | ||
1360 | if (g4x_compute_wm0(dev, 0, | 1360 | if (g4x_compute_wm0(dev, PIPE_A, |
1361 | &g4x_wm_info, latency_ns, | 1361 | &g4x_wm_info, latency_ns, |
1362 | &g4x_cursor_wm_info, latency_ns, | 1362 | &g4x_cursor_wm_info, latency_ns, |
1363 | &planea_wm, &cursora_wm)) | 1363 | &planea_wm, &cursora_wm)) |
1364 | enabled |= 1; | 1364 | enabled |= 1 << PIPE_A; |
1365 | 1365 | ||
1366 | if (g4x_compute_wm0(dev, 1, | 1366 | if (g4x_compute_wm0(dev, PIPE_B, |
1367 | &g4x_wm_info, latency_ns, | 1367 | &g4x_wm_info, latency_ns, |
1368 | &g4x_cursor_wm_info, latency_ns, | 1368 | &g4x_cursor_wm_info, latency_ns, |
1369 | &planeb_wm, &cursorb_wm)) | 1369 | &planeb_wm, &cursorb_wm)) |
1370 | enabled |= 2; | 1370 | enabled |= 1 << PIPE_B; |
1371 | 1371 | ||
1372 | if (single_plane_enabled(enabled) && | 1372 | if (single_plane_enabled(enabled) && |
1373 | g4x_compute_srwm(dev, ffs(enabled) - 1, | 1373 | g4x_compute_srwm(dev, ffs(enabled) - 1, |
@@ -1716,7 +1716,7 @@ static void ironlake_update_wm(struct drm_device *dev) | |||
1716 | unsigned int enabled; | 1716 | unsigned int enabled; |
1717 | 1717 | ||
1718 | enabled = 0; | 1718 | enabled = 0; |
1719 | if (g4x_compute_wm0(dev, 0, | 1719 | if (g4x_compute_wm0(dev, PIPE_A, |
1720 | &ironlake_display_wm_info, | 1720 | &ironlake_display_wm_info, |
1721 | ILK_LP0_PLANE_LATENCY, | 1721 | ILK_LP0_PLANE_LATENCY, |
1722 | &ironlake_cursor_wm_info, | 1722 | &ironlake_cursor_wm_info, |
@@ -1727,10 +1727,10 @@ static void ironlake_update_wm(struct drm_device *dev) | |||
1727 | DRM_DEBUG_KMS("FIFO watermarks For pipe A -" | 1727 | DRM_DEBUG_KMS("FIFO watermarks For pipe A -" |
1728 | " plane %d, " "cursor: %d\n", | 1728 | " plane %d, " "cursor: %d\n", |
1729 | plane_wm, cursor_wm); | 1729 | plane_wm, cursor_wm); |
1730 | enabled |= 1; | 1730 | enabled |= 1 << PIPE_A; |
1731 | } | 1731 | } |
1732 | 1732 | ||
1733 | if (g4x_compute_wm0(dev, 1, | 1733 | if (g4x_compute_wm0(dev, PIPE_B, |
1734 | &ironlake_display_wm_info, | 1734 | &ironlake_display_wm_info, |
1735 | ILK_LP0_PLANE_LATENCY, | 1735 | ILK_LP0_PLANE_LATENCY, |
1736 | &ironlake_cursor_wm_info, | 1736 | &ironlake_cursor_wm_info, |
@@ -1741,7 +1741,7 @@ static void ironlake_update_wm(struct drm_device *dev) | |||
1741 | DRM_DEBUG_KMS("FIFO watermarks For pipe B -" | 1741 | DRM_DEBUG_KMS("FIFO watermarks For pipe B -" |
1742 | " plane %d, cursor: %d\n", | 1742 | " plane %d, cursor: %d\n", |
1743 | plane_wm, cursor_wm); | 1743 | plane_wm, cursor_wm); |
1744 | enabled |= 2; | 1744 | enabled |= 1 << PIPE_B; |
1745 | } | 1745 | } |
1746 | 1746 | ||
1747 | /* | 1747 | /* |
@@ -1801,7 +1801,7 @@ static void sandybridge_update_wm(struct drm_device *dev) | |||
1801 | unsigned int enabled; | 1801 | unsigned int enabled; |
1802 | 1802 | ||
1803 | enabled = 0; | 1803 | enabled = 0; |
1804 | if (g4x_compute_wm0(dev, 0, | 1804 | if (g4x_compute_wm0(dev, PIPE_A, |
1805 | &sandybridge_display_wm_info, latency, | 1805 | &sandybridge_display_wm_info, latency, |
1806 | &sandybridge_cursor_wm_info, latency, | 1806 | &sandybridge_cursor_wm_info, latency, |
1807 | &plane_wm, &cursor_wm)) { | 1807 | &plane_wm, &cursor_wm)) { |
@@ -1812,10 +1812,10 @@ static void sandybridge_update_wm(struct drm_device *dev) | |||
1812 | DRM_DEBUG_KMS("FIFO watermarks For pipe A -" | 1812 | DRM_DEBUG_KMS("FIFO watermarks For pipe A -" |
1813 | " plane %d, " "cursor: %d\n", | 1813 | " plane %d, " "cursor: %d\n", |
1814 | plane_wm, cursor_wm); | 1814 | plane_wm, cursor_wm); |
1815 | enabled |= 1; | 1815 | enabled |= 1 << PIPE_A; |
1816 | } | 1816 | } |
1817 | 1817 | ||
1818 | if (g4x_compute_wm0(dev, 1, | 1818 | if (g4x_compute_wm0(dev, PIPE_B, |
1819 | &sandybridge_display_wm_info, latency, | 1819 | &sandybridge_display_wm_info, latency, |
1820 | &sandybridge_cursor_wm_info, latency, | 1820 | &sandybridge_cursor_wm_info, latency, |
1821 | &plane_wm, &cursor_wm)) { | 1821 | &plane_wm, &cursor_wm)) { |
@@ -1826,7 +1826,7 @@ static void sandybridge_update_wm(struct drm_device *dev) | |||
1826 | DRM_DEBUG_KMS("FIFO watermarks For pipe B -" | 1826 | DRM_DEBUG_KMS("FIFO watermarks For pipe B -" |
1827 | " plane %d, cursor: %d\n", | 1827 | " plane %d, cursor: %d\n", |
1828 | plane_wm, cursor_wm); | 1828 | plane_wm, cursor_wm); |
1829 | enabled |= 2; | 1829 | enabled |= 1 << PIPE_B; |
1830 | } | 1830 | } |
1831 | 1831 | ||
1832 | /* | 1832 | /* |
@@ -1904,7 +1904,7 @@ static void ivybridge_update_wm(struct drm_device *dev) | |||
1904 | unsigned int enabled; | 1904 | unsigned int enabled; |
1905 | 1905 | ||
1906 | enabled = 0; | 1906 | enabled = 0; |
1907 | if (g4x_compute_wm0(dev, 0, | 1907 | if (g4x_compute_wm0(dev, PIPE_A, |
1908 | &sandybridge_display_wm_info, latency, | 1908 | &sandybridge_display_wm_info, latency, |
1909 | &sandybridge_cursor_wm_info, latency, | 1909 | &sandybridge_cursor_wm_info, latency, |
1910 | &plane_wm, &cursor_wm)) { | 1910 | &plane_wm, &cursor_wm)) { |
@@ -1915,10 +1915,10 @@ static void ivybridge_update_wm(struct drm_device *dev) | |||
1915 | DRM_DEBUG_KMS("FIFO watermarks For pipe A -" | 1915 | DRM_DEBUG_KMS("FIFO watermarks For pipe A -" |
1916 | " plane %d, " "cursor: %d\n", | 1916 | " plane %d, " "cursor: %d\n", |
1917 | plane_wm, cursor_wm); | 1917 | plane_wm, cursor_wm); |
1918 | enabled |= 1; | 1918 | enabled |= 1 << PIPE_A; |
1919 | } | 1919 | } |
1920 | 1920 | ||
1921 | if (g4x_compute_wm0(dev, 1, | 1921 | if (g4x_compute_wm0(dev, PIPE_B, |
1922 | &sandybridge_display_wm_info, latency, | 1922 | &sandybridge_display_wm_info, latency, |
1923 | &sandybridge_cursor_wm_info, latency, | 1923 | &sandybridge_cursor_wm_info, latency, |
1924 | &plane_wm, &cursor_wm)) { | 1924 | &plane_wm, &cursor_wm)) { |
@@ -1929,10 +1929,10 @@ static void ivybridge_update_wm(struct drm_device *dev) | |||
1929 | DRM_DEBUG_KMS("FIFO watermarks For pipe B -" | 1929 | DRM_DEBUG_KMS("FIFO watermarks For pipe B -" |
1930 | " plane %d, cursor: %d\n", | 1930 | " plane %d, cursor: %d\n", |
1931 | plane_wm, cursor_wm); | 1931 | plane_wm, cursor_wm); |
1932 | enabled |= 2; | 1932 | enabled |= 1 << PIPE_B; |
1933 | } | 1933 | } |
1934 | 1934 | ||
1935 | if (g4x_compute_wm0(dev, 2, | 1935 | if (g4x_compute_wm0(dev, PIPE_C, |
1936 | &sandybridge_display_wm_info, latency, | 1936 | &sandybridge_display_wm_info, latency, |
1937 | &sandybridge_cursor_wm_info, latency, | 1937 | &sandybridge_cursor_wm_info, latency, |
1938 | &plane_wm, &cursor_wm)) { | 1938 | &plane_wm, &cursor_wm)) { |
@@ -1943,7 +1943,7 @@ static void ivybridge_update_wm(struct drm_device *dev) | |||
1943 | DRM_DEBUG_KMS("FIFO watermarks For pipe C -" | 1943 | DRM_DEBUG_KMS("FIFO watermarks For pipe C -" |
1944 | " plane %d, cursor: %d\n", | 1944 | " plane %d, cursor: %d\n", |
1945 | plane_wm, cursor_wm); | 1945 | plane_wm, cursor_wm); |
1946 | enabled |= 3; | 1946 | enabled |= 1 << PIPE_C; |
1947 | } | 1947 | } |
1948 | 1948 | ||
1949 | /* | 1949 | /* |
diff --git a/drivers/gpu/drm/mgag200/mgag200_mode.c b/drivers/gpu/drm/mgag200/mgag200_mode.c index f9889658329b..77b8a45fb10a 100644 --- a/drivers/gpu/drm/mgag200/mgag200_mode.c +++ b/drivers/gpu/drm/mgag200/mgag200_mode.c | |||
@@ -46,29 +46,26 @@ static void mga_crtc_load_lut(struct drm_crtc *crtc) | |||
46 | 46 | ||
47 | static inline void mga_wait_vsync(struct mga_device *mdev) | 47 | static inline void mga_wait_vsync(struct mga_device *mdev) |
48 | { | 48 | { |
49 | unsigned int count = 0; | 49 | unsigned long timeout = jiffies + HZ/10; |
50 | unsigned int status = 0; | 50 | unsigned int status = 0; |
51 | 51 | ||
52 | do { | 52 | do { |
53 | status = RREG32(MGAREG_Status); | 53 | status = RREG32(MGAREG_Status); |
54 | count++; | 54 | } while ((status & 0x08) && time_before(jiffies, timeout)); |
55 | } while ((status & 0x08) && (count < 250000)); | 55 | timeout = jiffies + HZ/10; |
56 | count = 0; | ||
57 | status = 0; | 56 | status = 0; |
58 | do { | 57 | do { |
59 | status = RREG32(MGAREG_Status); | 58 | status = RREG32(MGAREG_Status); |
60 | count++; | 59 | } while (!(status & 0x08) && time_before(jiffies, timeout)); |
61 | } while (!(status & 0x08) && (count < 250000)); | ||
62 | } | 60 | } |
63 | 61 | ||
64 | static inline void mga_wait_busy(struct mga_device *mdev) | 62 | static inline void mga_wait_busy(struct mga_device *mdev) |
65 | { | 63 | { |
66 | unsigned int count = 0; | 64 | unsigned long timeout = jiffies + HZ; |
67 | unsigned int status = 0; | 65 | unsigned int status = 0; |
68 | do { | 66 | do { |
69 | status = RREG8(MGAREG_Status + 2); | 67 | status = RREG8(MGAREG_Status + 2); |
70 | count++; | 68 | } while ((status & 0x01) && time_before(jiffies, timeout)); |
71 | } while ((status & 0x01) && (count < 500000)); | ||
72 | } | 69 | } |
73 | 70 | ||
74 | /* | 71 | /* |
@@ -189,12 +186,12 @@ static int mga_g200wb_set_plls(struct mga_device *mdev, long clock) | |||
189 | WREG8(DAC_INDEX, MGA1064_PIX_CLK_CTL); | 186 | WREG8(DAC_INDEX, MGA1064_PIX_CLK_CTL); |
190 | tmp = RREG8(DAC_DATA); | 187 | tmp = RREG8(DAC_DATA); |
191 | tmp |= MGA1064_PIX_CLK_CTL_CLK_DIS; | 188 | tmp |= MGA1064_PIX_CLK_CTL_CLK_DIS; |
192 | WREG_DAC(MGA1064_PIX_CLK_CTL_CLK_DIS, tmp); | 189 | WREG8(DAC_DATA, tmp); |
193 | 190 | ||
194 | WREG8(DAC_INDEX, MGA1064_REMHEADCTL); | 191 | WREG8(DAC_INDEX, MGA1064_REMHEADCTL); |
195 | tmp = RREG8(DAC_DATA); | 192 | tmp = RREG8(DAC_DATA); |
196 | tmp |= MGA1064_REMHEADCTL_CLKDIS; | 193 | tmp |= MGA1064_REMHEADCTL_CLKDIS; |
197 | WREG_DAC(MGA1064_REMHEADCTL, tmp); | 194 | WREG8(DAC_DATA, tmp); |
198 | 195 | ||
199 | /* select PLL Set C */ | 196 | /* select PLL Set C */ |
200 | tmp = RREG8(MGAREG_MEM_MISC_READ); | 197 | tmp = RREG8(MGAREG_MEM_MISC_READ); |
@@ -204,7 +201,7 @@ static int mga_g200wb_set_plls(struct mga_device *mdev, long clock) | |||
204 | WREG8(DAC_INDEX, MGA1064_PIX_CLK_CTL); | 201 | WREG8(DAC_INDEX, MGA1064_PIX_CLK_CTL); |
205 | tmp = RREG8(DAC_DATA); | 202 | tmp = RREG8(DAC_DATA); |
206 | tmp |= MGA1064_PIX_CLK_CTL_CLK_POW_DOWN | 0x80; | 203 | tmp |= MGA1064_PIX_CLK_CTL_CLK_POW_DOWN | 0x80; |
207 | WREG_DAC(MGA1064_PIX_CLK_CTL, tmp); | 204 | WREG8(DAC_DATA, tmp); |
208 | 205 | ||
209 | udelay(500); | 206 | udelay(500); |
210 | 207 | ||
@@ -212,7 +209,7 @@ static int mga_g200wb_set_plls(struct mga_device *mdev, long clock) | |||
212 | WREG8(DAC_INDEX, MGA1064_VREF_CTL); | 209 | WREG8(DAC_INDEX, MGA1064_VREF_CTL); |
213 | tmp = RREG8(DAC_DATA); | 210 | tmp = RREG8(DAC_DATA); |
214 | tmp &= ~0x04; | 211 | tmp &= ~0x04; |
215 | WREG_DAC(MGA1064_VREF_CTL, tmp); | 212 | WREG8(DAC_DATA, tmp); |
216 | 213 | ||
217 | udelay(50); | 214 | udelay(50); |
218 | 215 | ||
@@ -236,13 +233,13 @@ static int mga_g200wb_set_plls(struct mga_device *mdev, long clock) | |||
236 | tmp = RREG8(DAC_DATA); | 233 | tmp = RREG8(DAC_DATA); |
237 | tmp &= ~MGA1064_PIX_CLK_CTL_SEL_MSK; | 234 | tmp &= ~MGA1064_PIX_CLK_CTL_SEL_MSK; |
238 | tmp |= MGA1064_PIX_CLK_CTL_SEL_PLL; | 235 | tmp |= MGA1064_PIX_CLK_CTL_SEL_PLL; |
239 | WREG_DAC(MGA1064_PIX_CLK_CTL, tmp); | 236 | WREG8(DAC_DATA, tmp); |
240 | 237 | ||
241 | WREG8(DAC_INDEX, MGA1064_REMHEADCTL); | 238 | WREG8(DAC_INDEX, MGA1064_REMHEADCTL); |
242 | tmp = RREG8(DAC_DATA); | 239 | tmp = RREG8(DAC_DATA); |
243 | tmp &= ~MGA1064_REMHEADCTL_CLKSL_MSK; | 240 | tmp &= ~MGA1064_REMHEADCTL_CLKSL_MSK; |
244 | tmp |= MGA1064_REMHEADCTL_CLKSL_PLL; | 241 | tmp |= MGA1064_REMHEADCTL_CLKSL_PLL; |
245 | WREG_DAC(MGA1064_REMHEADCTL, tmp); | 242 | WREG8(DAC_DATA, tmp); |
246 | 243 | ||
247 | /* reset dotclock rate bit */ | 244 | /* reset dotclock rate bit */ |
248 | WREG8(MGAREG_SEQ_INDEX, 1); | 245 | WREG8(MGAREG_SEQ_INDEX, 1); |
@@ -253,7 +250,7 @@ static int mga_g200wb_set_plls(struct mga_device *mdev, long clock) | |||
253 | WREG8(DAC_INDEX, MGA1064_PIX_CLK_CTL); | 250 | WREG8(DAC_INDEX, MGA1064_PIX_CLK_CTL); |
254 | tmp = RREG8(DAC_DATA); | 251 | tmp = RREG8(DAC_DATA); |
255 | tmp &= ~MGA1064_PIX_CLK_CTL_CLK_DIS; | 252 | tmp &= ~MGA1064_PIX_CLK_CTL_CLK_DIS; |
256 | WREG_DAC(MGA1064_PIX_CLK_CTL, tmp); | 253 | WREG8(DAC_DATA, tmp); |
257 | 254 | ||
258 | vcount = RREG8(MGAREG_VCOUNT); | 255 | vcount = RREG8(MGAREG_VCOUNT); |
259 | 256 | ||
@@ -318,7 +315,7 @@ static int mga_g200ev_set_plls(struct mga_device *mdev, long clock) | |||
318 | WREG8(DAC_INDEX, MGA1064_PIX_CLK_CTL); | 315 | WREG8(DAC_INDEX, MGA1064_PIX_CLK_CTL); |
319 | tmp = RREG8(DAC_DATA); | 316 | tmp = RREG8(DAC_DATA); |
320 | tmp |= MGA1064_PIX_CLK_CTL_CLK_DIS; | 317 | tmp |= MGA1064_PIX_CLK_CTL_CLK_DIS; |
321 | WREG_DAC(MGA1064_PIX_CLK_CTL_CLK_DIS, tmp); | 318 | WREG8(DAC_DATA, tmp); |
322 | 319 | ||
323 | tmp = RREG8(MGAREG_MEM_MISC_READ); | 320 | tmp = RREG8(MGAREG_MEM_MISC_READ); |
324 | tmp |= 0x3 << 2; | 321 | tmp |= 0x3 << 2; |
@@ -326,12 +323,12 @@ static int mga_g200ev_set_plls(struct mga_device *mdev, long clock) | |||
326 | 323 | ||
327 | WREG8(DAC_INDEX, MGA1064_PIX_PLL_STAT); | 324 | WREG8(DAC_INDEX, MGA1064_PIX_PLL_STAT); |
328 | tmp = RREG8(DAC_DATA); | 325 | tmp = RREG8(DAC_DATA); |
329 | WREG_DAC(MGA1064_PIX_PLL_STAT, tmp & ~0x40); | 326 | WREG8(DAC_DATA, tmp & ~0x40); |
330 | 327 | ||
331 | WREG8(DAC_INDEX, MGA1064_PIX_CLK_CTL); | 328 | WREG8(DAC_INDEX, MGA1064_PIX_CLK_CTL); |
332 | tmp = RREG8(DAC_DATA); | 329 | tmp = RREG8(DAC_DATA); |
333 | tmp |= MGA1064_PIX_CLK_CTL_CLK_POW_DOWN; | 330 | tmp |= MGA1064_PIX_CLK_CTL_CLK_POW_DOWN; |
334 | WREG_DAC(MGA1064_PIX_CLK_CTL, tmp); | 331 | WREG8(DAC_DATA, tmp); |
335 | 332 | ||
336 | WREG_DAC(MGA1064_EV_PIX_PLLC_M, m); | 333 | WREG_DAC(MGA1064_EV_PIX_PLLC_M, m); |
337 | WREG_DAC(MGA1064_EV_PIX_PLLC_N, n); | 334 | WREG_DAC(MGA1064_EV_PIX_PLLC_N, n); |
@@ -342,7 +339,7 @@ static int mga_g200ev_set_plls(struct mga_device *mdev, long clock) | |||
342 | WREG8(DAC_INDEX, MGA1064_PIX_CLK_CTL); | 339 | WREG8(DAC_INDEX, MGA1064_PIX_CLK_CTL); |
343 | tmp = RREG8(DAC_DATA); | 340 | tmp = RREG8(DAC_DATA); |
344 | tmp &= ~MGA1064_PIX_CLK_CTL_CLK_POW_DOWN; | 341 | tmp &= ~MGA1064_PIX_CLK_CTL_CLK_POW_DOWN; |
345 | WREG_DAC(MGA1064_PIX_CLK_CTL, tmp); | 342 | WREG8(DAC_DATA, tmp); |
346 | 343 | ||
347 | udelay(500); | 344 | udelay(500); |
348 | 345 | ||
@@ -350,11 +347,11 @@ static int mga_g200ev_set_plls(struct mga_device *mdev, long clock) | |||
350 | tmp = RREG8(DAC_DATA); | 347 | tmp = RREG8(DAC_DATA); |
351 | tmp &= ~MGA1064_PIX_CLK_CTL_SEL_MSK; | 348 | tmp &= ~MGA1064_PIX_CLK_CTL_SEL_MSK; |
352 | tmp |= MGA1064_PIX_CLK_CTL_SEL_PLL; | 349 | tmp |= MGA1064_PIX_CLK_CTL_SEL_PLL; |
353 | WREG_DAC(MGA1064_PIX_CLK_CTL, tmp); | 350 | WREG8(DAC_DATA, tmp); |
354 | 351 | ||
355 | WREG8(DAC_INDEX, MGA1064_PIX_PLL_STAT); | 352 | WREG8(DAC_INDEX, MGA1064_PIX_PLL_STAT); |
356 | tmp = RREG8(DAC_DATA); | 353 | tmp = RREG8(DAC_DATA); |
357 | WREG_DAC(MGA1064_PIX_PLL_STAT, tmp | 0x40); | 354 | WREG8(DAC_DATA, tmp | 0x40); |
358 | 355 | ||
359 | tmp = RREG8(MGAREG_MEM_MISC_READ); | 356 | tmp = RREG8(MGAREG_MEM_MISC_READ); |
360 | tmp |= (0x3 << 2); | 357 | tmp |= (0x3 << 2); |
@@ -363,7 +360,7 @@ static int mga_g200ev_set_plls(struct mga_device *mdev, long clock) | |||
363 | WREG8(DAC_INDEX, MGA1064_PIX_CLK_CTL); | 360 | WREG8(DAC_INDEX, MGA1064_PIX_CLK_CTL); |
364 | tmp = RREG8(DAC_DATA); | 361 | tmp = RREG8(DAC_DATA); |
365 | tmp &= ~MGA1064_PIX_CLK_CTL_CLK_DIS; | 362 | tmp &= ~MGA1064_PIX_CLK_CTL_CLK_DIS; |
366 | WREG_DAC(MGA1064_PIX_CLK_CTL, tmp); | 363 | WREG8(DAC_DATA, tmp); |
367 | 364 | ||
368 | return 0; | 365 | return 0; |
369 | } | 366 | } |
@@ -416,7 +413,7 @@ static int mga_g200eh_set_plls(struct mga_device *mdev, long clock) | |||
416 | WREG8(DAC_INDEX, MGA1064_PIX_CLK_CTL); | 413 | WREG8(DAC_INDEX, MGA1064_PIX_CLK_CTL); |
417 | tmp = RREG8(DAC_DATA); | 414 | tmp = RREG8(DAC_DATA); |
418 | tmp |= MGA1064_PIX_CLK_CTL_CLK_DIS; | 415 | tmp |= MGA1064_PIX_CLK_CTL_CLK_DIS; |
419 | WREG_DAC(MGA1064_PIX_CLK_CTL_CLK_DIS, tmp); | 416 | WREG8(DAC_DATA, tmp); |
420 | 417 | ||
421 | tmp = RREG8(MGAREG_MEM_MISC_READ); | 418 | tmp = RREG8(MGAREG_MEM_MISC_READ); |
422 | tmp |= 0x3 << 2; | 419 | tmp |= 0x3 << 2; |
@@ -425,7 +422,7 @@ static int mga_g200eh_set_plls(struct mga_device *mdev, long clock) | |||
425 | WREG8(DAC_INDEX, MGA1064_PIX_CLK_CTL); | 422 | WREG8(DAC_INDEX, MGA1064_PIX_CLK_CTL); |
426 | tmp = RREG8(DAC_DATA); | 423 | tmp = RREG8(DAC_DATA); |
427 | tmp |= MGA1064_PIX_CLK_CTL_CLK_POW_DOWN; | 424 | tmp |= MGA1064_PIX_CLK_CTL_CLK_POW_DOWN; |
428 | WREG_DAC(MGA1064_PIX_CLK_CTL, tmp); | 425 | WREG8(DAC_DATA, tmp); |
429 | 426 | ||
430 | udelay(500); | 427 | udelay(500); |
431 | 428 | ||
@@ -439,13 +436,13 @@ static int mga_g200eh_set_plls(struct mga_device *mdev, long clock) | |||
439 | tmp = RREG8(DAC_DATA); | 436 | tmp = RREG8(DAC_DATA); |
440 | tmp &= ~MGA1064_PIX_CLK_CTL_SEL_MSK; | 437 | tmp &= ~MGA1064_PIX_CLK_CTL_SEL_MSK; |
441 | tmp |= MGA1064_PIX_CLK_CTL_SEL_PLL; | 438 | tmp |= MGA1064_PIX_CLK_CTL_SEL_PLL; |
442 | WREG_DAC(MGA1064_PIX_CLK_CTL, tmp); | 439 | WREG8(DAC_DATA, tmp); |
443 | 440 | ||
444 | WREG8(DAC_INDEX, MGA1064_PIX_CLK_CTL); | 441 | WREG8(DAC_INDEX, MGA1064_PIX_CLK_CTL); |
445 | tmp = RREG8(DAC_DATA); | 442 | tmp = RREG8(DAC_DATA); |
446 | tmp &= ~MGA1064_PIX_CLK_CTL_CLK_DIS; | 443 | tmp &= ~MGA1064_PIX_CLK_CTL_CLK_DIS; |
447 | tmp &= ~MGA1064_PIX_CLK_CTL_CLK_POW_DOWN; | 444 | tmp &= ~MGA1064_PIX_CLK_CTL_CLK_POW_DOWN; |
448 | WREG_DAC(MGA1064_PIX_CLK_CTL, tmp); | 445 | WREG8(DAC_DATA, tmp); |
449 | 446 | ||
450 | vcount = RREG8(MGAREG_VCOUNT); | 447 | vcount = RREG8(MGAREG_VCOUNT); |
451 | 448 | ||
@@ -515,12 +512,12 @@ static int mga_g200er_set_plls(struct mga_device *mdev, long clock) | |||
515 | WREG8(DAC_INDEX, MGA1064_PIX_CLK_CTL); | 512 | WREG8(DAC_INDEX, MGA1064_PIX_CLK_CTL); |
516 | tmp = RREG8(DAC_DATA); | 513 | tmp = RREG8(DAC_DATA); |
517 | tmp |= MGA1064_PIX_CLK_CTL_CLK_DIS; | 514 | tmp |= MGA1064_PIX_CLK_CTL_CLK_DIS; |
518 | WREG_DAC(MGA1064_PIX_CLK_CTL_CLK_DIS, tmp); | 515 | WREG8(DAC_DATA, tmp); |
519 | 516 | ||
520 | WREG8(DAC_INDEX, MGA1064_REMHEADCTL); | 517 | WREG8(DAC_INDEX, MGA1064_REMHEADCTL); |
521 | tmp = RREG8(DAC_DATA); | 518 | tmp = RREG8(DAC_DATA); |
522 | tmp |= MGA1064_REMHEADCTL_CLKDIS; | 519 | tmp |= MGA1064_REMHEADCTL_CLKDIS; |
523 | WREG_DAC(MGA1064_REMHEADCTL, tmp); | 520 | WREG8(DAC_DATA, tmp); |
524 | 521 | ||
525 | tmp = RREG8(MGAREG_MEM_MISC_READ); | 522 | tmp = RREG8(MGAREG_MEM_MISC_READ); |
526 | tmp |= (0x3<<2) | 0xc0; | 523 | tmp |= (0x3<<2) | 0xc0; |
@@ -530,7 +527,7 @@ static int mga_g200er_set_plls(struct mga_device *mdev, long clock) | |||
530 | tmp = RREG8(DAC_DATA); | 527 | tmp = RREG8(DAC_DATA); |
531 | tmp &= ~MGA1064_PIX_CLK_CTL_CLK_DIS; | 528 | tmp &= ~MGA1064_PIX_CLK_CTL_CLK_DIS; |
532 | tmp |= MGA1064_PIX_CLK_CTL_CLK_POW_DOWN; | 529 | tmp |= MGA1064_PIX_CLK_CTL_CLK_POW_DOWN; |
533 | WREG_DAC(MGA1064_PIX_CLK_CTL, tmp); | 530 | WREG8(DAC_DATA, tmp); |
534 | 531 | ||
535 | udelay(500); | 532 | udelay(500); |
536 | 533 | ||
@@ -657,12 +654,26 @@ static void mga_g200wb_commit(struct drm_crtc *crtc) | |||
657 | WREG_DAC(MGA1064_GEN_IO_DATA, tmp); | 654 | WREG_DAC(MGA1064_GEN_IO_DATA, tmp); |
658 | } | 655 | } |
659 | 656 | ||
660 | 657 | /* | |
658 | This is how the framebuffer base address is stored in g200 cards: | ||
659 | * Assume @offset is the gpu_addr variable of the framebuffer object | ||
660 | * Then addr is the number of _pixels_ (not bytes) from the start of | ||
661 | VRAM to the first pixel we want to display. (divided by 2 for 32bit | ||
662 | framebuffers) | ||
663 | * addr is stored in the CRTCEXT0, CRTCC and CRTCD registers | ||
664 | addr<20> -> CRTCEXT0<6> | ||
665 | addr<19-16> -> CRTCEXT0<3-0> | ||
666 | addr<15-8> -> CRTCC<7-0> | ||
667 | addr<7-0> -> CRTCD<7-0> | ||
668 | CRTCEXT0 has to be programmed last to trigger an update and make the | ||
669 | new addr variable take effect. | ||
670 | */ | ||
661 | void mga_set_start_address(struct drm_crtc *crtc, unsigned offset) | 671 | void mga_set_start_address(struct drm_crtc *crtc, unsigned offset) |
662 | { | 672 | { |
663 | struct mga_device *mdev = crtc->dev->dev_private; | 673 | struct mga_device *mdev = crtc->dev->dev_private; |
664 | u32 addr; | 674 | u32 addr; |
665 | int count; | 675 | int count; |
676 | u8 crtcext0; | ||
666 | 677 | ||
667 | while (RREG8(0x1fda) & 0x08); | 678 | while (RREG8(0x1fda) & 0x08); |
668 | while (!(RREG8(0x1fda) & 0x08)); | 679 | while (!(RREG8(0x1fda) & 0x08)); |
@@ -670,10 +681,17 @@ void mga_set_start_address(struct drm_crtc *crtc, unsigned offset) | |||
670 | count = RREG8(MGAREG_VCOUNT) + 2; | 681 | count = RREG8(MGAREG_VCOUNT) + 2; |
671 | while (RREG8(MGAREG_VCOUNT) < count); | 682 | while (RREG8(MGAREG_VCOUNT) < count); |
672 | 683 | ||
673 | addr = offset >> 2; | 684 | WREG8(MGAREG_CRTCEXT_INDEX, 0); |
685 | crtcext0 = RREG8(MGAREG_CRTCEXT_DATA); | ||
686 | crtcext0 &= 0xB0; | ||
687 | addr = offset / 8; | ||
688 | /* Can't store addresses any higher than that... | ||
689 | but we also don't have more than 16MB of memory, so it should be fine. */ | ||
690 | WARN_ON(addr > 0x1fffff); | ||
691 | crtcext0 |= (!!(addr & (1<<20)))<<6; | ||
674 | WREG_CRT(0x0d, (u8)(addr & 0xff)); | 692 | WREG_CRT(0x0d, (u8)(addr & 0xff)); |
675 | WREG_CRT(0x0c, (u8)(addr >> 8) & 0xff); | 693 | WREG_CRT(0x0c, (u8)(addr >> 8) & 0xff); |
676 | WREG_CRT(0xaf, (u8)(addr >> 16) & 0xf); | 694 | WREG_ECRT(0x0, ((u8)(addr >> 16) & 0xf) | crtcext0); |
677 | } | 695 | } |
678 | 696 | ||
679 | 697 | ||
@@ -829,11 +847,7 @@ static int mga_crtc_mode_set(struct drm_crtc *crtc, | |||
829 | 847 | ||
830 | 848 | ||
831 | for (i = 0; i < sizeof(dacvalue); i++) { | 849 | for (i = 0; i < sizeof(dacvalue); i++) { |
832 | if ((i <= 0x03) || | 850 | if ((i <= 0x17) || |
833 | (i == 0x07) || | ||
834 | (i == 0x0b) || | ||
835 | (i == 0x0f) || | ||
836 | ((i >= 0x13) && (i <= 0x17)) || | ||
837 | (i == 0x1b) || | 851 | (i == 0x1b) || |
838 | (i == 0x1c) || | 852 | (i == 0x1c) || |
839 | ((i >= 0x1f) && (i <= 0x29)) || | 853 | ((i >= 0x1f) && (i <= 0x29)) || |
diff --git a/drivers/gpu/drm/nouveau/core/engine/device/nvc0.c b/drivers/gpu/drm/nouveau/core/engine/device/nvc0.c index 955af122c3a6..a36e64e98ef3 100644 --- a/drivers/gpu/drm/nouveau/core/engine/device/nvc0.c +++ b/drivers/gpu/drm/nouveau/core/engine/device/nvc0.c | |||
@@ -138,7 +138,6 @@ nvc0_identify(struct nouveau_device *device) | |||
138 | device->oclass[NVDEV_ENGINE_BSP ] = &nvc0_bsp_oclass; | 138 | device->oclass[NVDEV_ENGINE_BSP ] = &nvc0_bsp_oclass; |
139 | device->oclass[NVDEV_ENGINE_PPP ] = &nvc0_ppp_oclass; | 139 | device->oclass[NVDEV_ENGINE_PPP ] = &nvc0_ppp_oclass; |
140 | device->oclass[NVDEV_ENGINE_COPY0 ] = &nvc0_copy0_oclass; | 140 | device->oclass[NVDEV_ENGINE_COPY0 ] = &nvc0_copy0_oclass; |
141 | device->oclass[NVDEV_ENGINE_COPY1 ] = &nvc0_copy1_oclass; | ||
142 | device->oclass[NVDEV_ENGINE_DISP ] = &nva3_disp_oclass; | 141 | device->oclass[NVDEV_ENGINE_DISP ] = &nva3_disp_oclass; |
143 | break; | 142 | break; |
144 | case 0xce: | 143 | case 0xce: |
@@ -225,7 +224,6 @@ nvc0_identify(struct nouveau_device *device) | |||
225 | device->oclass[NVDEV_ENGINE_BSP ] = &nvc0_bsp_oclass; | 224 | device->oclass[NVDEV_ENGINE_BSP ] = &nvc0_bsp_oclass; |
226 | device->oclass[NVDEV_ENGINE_PPP ] = &nvc0_ppp_oclass; | 225 | device->oclass[NVDEV_ENGINE_PPP ] = &nvc0_ppp_oclass; |
227 | device->oclass[NVDEV_ENGINE_COPY0 ] = &nvc0_copy0_oclass; | 226 | device->oclass[NVDEV_ENGINE_COPY0 ] = &nvc0_copy0_oclass; |
228 | device->oclass[NVDEV_ENGINE_COPY1 ] = &nvc0_copy1_oclass; | ||
229 | device->oclass[NVDEV_ENGINE_DISP ] = &nva3_disp_oclass; | 227 | device->oclass[NVDEV_ENGINE_DISP ] = &nva3_disp_oclass; |
230 | break; | 228 | break; |
231 | case 0xc8: | 229 | case 0xc8: |
diff --git a/drivers/gpu/drm/nouveau/core/engine/fifo/nv50.c b/drivers/gpu/drm/nouveau/core/engine/fifo/nv50.c index ddaeb5572903..89bf459d584b 100644 --- a/drivers/gpu/drm/nouveau/core/engine/fifo/nv50.c +++ b/drivers/gpu/drm/nouveau/core/engine/fifo/nv50.c | |||
@@ -47,6 +47,7 @@ nv50_fifo_playlist_update(struct nv50_fifo_priv *priv) | |||
47 | struct nouveau_gpuobj *cur; | 47 | struct nouveau_gpuobj *cur; |
48 | int i, p; | 48 | int i, p; |
49 | 49 | ||
50 | mutex_lock(&nv_subdev(priv)->mutex); | ||
50 | cur = priv->playlist[priv->cur_playlist]; | 51 | cur = priv->playlist[priv->cur_playlist]; |
51 | priv->cur_playlist = !priv->cur_playlist; | 52 | priv->cur_playlist = !priv->cur_playlist; |
52 | 53 | ||
@@ -60,6 +61,7 @@ nv50_fifo_playlist_update(struct nv50_fifo_priv *priv) | |||
60 | nv_wr32(priv, 0x0032f4, cur->addr >> 12); | 61 | nv_wr32(priv, 0x0032f4, cur->addr >> 12); |
61 | nv_wr32(priv, 0x0032ec, p); | 62 | nv_wr32(priv, 0x0032ec, p); |
62 | nv_wr32(priv, 0x002500, 0x00000101); | 63 | nv_wr32(priv, 0x002500, 0x00000101); |
64 | mutex_unlock(&nv_subdev(priv)->mutex); | ||
63 | } | 65 | } |
64 | 66 | ||
65 | static int | 67 | static int |
diff --git a/drivers/gpu/drm/nouveau/core/engine/fifo/nvc0.c b/drivers/gpu/drm/nouveau/core/engine/fifo/nvc0.c index 4d4a6b905370..46dfa68c47bb 100644 --- a/drivers/gpu/drm/nouveau/core/engine/fifo/nvc0.c +++ b/drivers/gpu/drm/nouveau/core/engine/fifo/nvc0.c | |||
@@ -71,6 +71,7 @@ nvc0_fifo_playlist_update(struct nvc0_fifo_priv *priv) | |||
71 | struct nouveau_gpuobj *cur; | 71 | struct nouveau_gpuobj *cur; |
72 | int i, p; | 72 | int i, p; |
73 | 73 | ||
74 | mutex_lock(&nv_subdev(priv)->mutex); | ||
74 | cur = priv->playlist[priv->cur_playlist]; | 75 | cur = priv->playlist[priv->cur_playlist]; |
75 | priv->cur_playlist = !priv->cur_playlist; | 76 | priv->cur_playlist = !priv->cur_playlist; |
76 | 77 | ||
@@ -87,6 +88,7 @@ nvc0_fifo_playlist_update(struct nvc0_fifo_priv *priv) | |||
87 | nv_wr32(priv, 0x002274, 0x01f00000 | (p >> 3)); | 88 | nv_wr32(priv, 0x002274, 0x01f00000 | (p >> 3)); |
88 | if (!nv_wait(priv, 0x00227c, 0x00100000, 0x00000000)) | 89 | if (!nv_wait(priv, 0x00227c, 0x00100000, 0x00000000)) |
89 | nv_error(priv, "playlist update failed\n"); | 90 | nv_error(priv, "playlist update failed\n"); |
91 | mutex_unlock(&nv_subdev(priv)->mutex); | ||
90 | } | 92 | } |
91 | 93 | ||
92 | static int | 94 | static int |
@@ -248,9 +250,17 @@ nvc0_fifo_chan_fini(struct nouveau_object *object, bool suspend) | |||
248 | struct nvc0_fifo_priv *priv = (void *)object->engine; | 250 | struct nvc0_fifo_priv *priv = (void *)object->engine; |
249 | struct nvc0_fifo_chan *chan = (void *)object; | 251 | struct nvc0_fifo_chan *chan = (void *)object; |
250 | u32 chid = chan->base.chid; | 252 | u32 chid = chan->base.chid; |
253 | u32 mask, engine; | ||
251 | 254 | ||
252 | nv_mask(priv, 0x003004 + (chid * 8), 0x00000001, 0x00000000); | 255 | nv_mask(priv, 0x003004 + (chid * 8), 0x00000001, 0x00000000); |
253 | nvc0_fifo_playlist_update(priv); | 256 | nvc0_fifo_playlist_update(priv); |
257 | mask = nv_rd32(priv, 0x0025a4); | ||
258 | for (engine = 0; mask && engine < 16; engine++) { | ||
259 | if (!(mask & (1 << engine))) | ||
260 | continue; | ||
261 | nv_mask(priv, 0x0025a8 + (engine * 4), 0x00000000, 0x00000000); | ||
262 | mask &= ~(1 << engine); | ||
263 | } | ||
254 | nv_wr32(priv, 0x003000 + (chid * 8), 0x00000000); | 264 | nv_wr32(priv, 0x003000 + (chid * 8), 0x00000000); |
255 | 265 | ||
256 | return nouveau_fifo_channel_fini(&chan->base, suspend); | 266 | return nouveau_fifo_channel_fini(&chan->base, suspend); |
diff --git a/drivers/gpu/drm/nouveau/core/engine/fifo/nve0.c b/drivers/gpu/drm/nouveau/core/engine/fifo/nve0.c index 9151919fb831..56192a7242ae 100644 --- a/drivers/gpu/drm/nouveau/core/engine/fifo/nve0.c +++ b/drivers/gpu/drm/nouveau/core/engine/fifo/nve0.c | |||
@@ -94,11 +94,13 @@ nve0_fifo_playlist_update(struct nve0_fifo_priv *priv, u32 engine) | |||
94 | u32 match = (engine << 16) | 0x00000001; | 94 | u32 match = (engine << 16) | 0x00000001; |
95 | int i, p; | 95 | int i, p; |
96 | 96 | ||
97 | mutex_lock(&nv_subdev(priv)->mutex); | ||
97 | cur = engn->playlist[engn->cur_playlist]; | 98 | cur = engn->playlist[engn->cur_playlist]; |
98 | if (unlikely(cur == NULL)) { | 99 | if (unlikely(cur == NULL)) { |
99 | int ret = nouveau_gpuobj_new(nv_object(priv), NULL, | 100 | int ret = nouveau_gpuobj_new(nv_object(priv), NULL, |
100 | 0x8000, 0x1000, 0, &cur); | 101 | 0x8000, 0x1000, 0, &cur); |
101 | if (ret) { | 102 | if (ret) { |
103 | mutex_unlock(&nv_subdev(priv)->mutex); | ||
102 | nv_error(priv, "playlist alloc failed\n"); | 104 | nv_error(priv, "playlist alloc failed\n"); |
103 | return; | 105 | return; |
104 | } | 106 | } |
@@ -122,6 +124,7 @@ nve0_fifo_playlist_update(struct nve0_fifo_priv *priv, u32 engine) | |||
122 | nv_wr32(priv, 0x002274, (engine << 20) | (p >> 3)); | 124 | nv_wr32(priv, 0x002274, (engine << 20) | (p >> 3)); |
123 | if (!nv_wait(priv, 0x002284 + (engine * 4), 0x00100000, 0x00000000)) | 125 | if (!nv_wait(priv, 0x002284 + (engine * 4), 0x00100000, 0x00000000)) |
124 | nv_error(priv, "playlist %d update timeout\n", engine); | 126 | nv_error(priv, "playlist %d update timeout\n", engine); |
127 | mutex_unlock(&nv_subdev(priv)->mutex); | ||
125 | } | 128 | } |
126 | 129 | ||
127 | static int | 130 | static int |
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/init.c b/drivers/gpu/drm/nouveau/core/subdev/bios/init.c index c300b5e7b670..c434d398d16f 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/bios/init.c +++ b/drivers/gpu/drm/nouveau/core/subdev/bios/init.c | |||
@@ -1940,8 +1940,8 @@ init_zm_mask_add(struct nvbios_init *init) | |||
1940 | trace("ZM_MASK_ADD\tR[0x%06x] &= 0x%08x += 0x%08x\n", addr, mask, add); | 1940 | trace("ZM_MASK_ADD\tR[0x%06x] &= 0x%08x += 0x%08x\n", addr, mask, add); |
1941 | init->offset += 13; | 1941 | init->offset += 13; |
1942 | 1942 | ||
1943 | data = init_rd32(init, addr) & mask; | 1943 | data = init_rd32(init, addr); |
1944 | data |= ((data + add) & ~mask); | 1944 | data = (data & mask) | ((data + add) & ~mask); |
1945 | init_wr32(init, addr, data); | 1945 | init_wr32(init, addr, data); |
1946 | } | 1946 | } |
1947 | 1947 | ||
diff --git a/drivers/gpu/drm/nouveau/core/subdev/ltcg/nvc0.c b/drivers/gpu/drm/nouveau/core/subdev/ltcg/nvc0.c index e4940fb166e8..fb794e997fbc 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/ltcg/nvc0.c +++ b/drivers/gpu/drm/nouveau/core/subdev/ltcg/nvc0.c | |||
@@ -29,7 +29,6 @@ | |||
29 | struct nvc0_ltcg_priv { | 29 | struct nvc0_ltcg_priv { |
30 | struct nouveau_ltcg base; | 30 | struct nouveau_ltcg base; |
31 | u32 part_nr; | 31 | u32 part_nr; |
32 | u32 part_mask; | ||
33 | u32 subp_nr; | 32 | u32 subp_nr; |
34 | struct nouveau_mm tags; | 33 | struct nouveau_mm tags; |
35 | u32 num_tags; | 34 | u32 num_tags; |
@@ -105,8 +104,6 @@ nvc0_ltcg_tags_clear(struct nouveau_ltcg *ltcg, u32 first, u32 count) | |||
105 | 104 | ||
106 | /* wait until it's finished with clearing */ | 105 | /* wait until it's finished with clearing */ |
107 | for (p = 0; p < priv->part_nr; ++p) { | 106 | for (p = 0; p < priv->part_nr; ++p) { |
108 | if (!(priv->part_mask & (1 << p))) | ||
109 | continue; | ||
110 | for (i = 0; i < priv->subp_nr; ++i) | 107 | for (i = 0; i < priv->subp_nr; ++i) |
111 | nv_wait(priv, 0x1410c8 + p * 0x2000 + i * 0x400, ~0, 0); | 108 | nv_wait(priv, 0x1410c8 + p * 0x2000 + i * 0x400, ~0, 0); |
112 | } | 109 | } |
@@ -121,6 +118,8 @@ nvc0_ltcg_init_tag_ram(struct nouveau_fb *pfb, struct nvc0_ltcg_priv *priv) | |||
121 | int ret; | 118 | int ret; |
122 | 119 | ||
123 | nv_wr32(priv, 0x17e8d8, priv->part_nr); | 120 | nv_wr32(priv, 0x17e8d8, priv->part_nr); |
121 | if (nv_device(pfb)->card_type >= NV_E0) | ||
122 | nv_wr32(priv, 0x17e000, priv->part_nr); | ||
124 | 123 | ||
125 | /* tags for 1/4 of VRAM should be enough (8192/4 per GiB of VRAM) */ | 124 | /* tags for 1/4 of VRAM should be enough (8192/4 per GiB of VRAM) */ |
126 | priv->num_tags = (pfb->ram.size >> 17) / 4; | 125 | priv->num_tags = (pfb->ram.size >> 17) / 4; |
@@ -167,16 +166,20 @@ nvc0_ltcg_ctor(struct nouveau_object *parent, struct nouveau_object *engine, | |||
167 | { | 166 | { |
168 | struct nvc0_ltcg_priv *priv; | 167 | struct nvc0_ltcg_priv *priv; |
169 | struct nouveau_fb *pfb = nouveau_fb(parent); | 168 | struct nouveau_fb *pfb = nouveau_fb(parent); |
170 | int ret; | 169 | u32 parts, mask; |
170 | int ret, i; | ||
171 | 171 | ||
172 | ret = nouveau_ltcg_create(parent, engine, oclass, &priv); | 172 | ret = nouveau_ltcg_create(parent, engine, oclass, &priv); |
173 | *pobject = nv_object(priv); | 173 | *pobject = nv_object(priv); |
174 | if (ret) | 174 | if (ret) |
175 | return ret; | 175 | return ret; |
176 | 176 | ||
177 | priv->part_nr = nv_rd32(priv, 0x022438); | 177 | parts = nv_rd32(priv, 0x022438); |
178 | priv->part_mask = nv_rd32(priv, 0x022554); | 178 | mask = nv_rd32(priv, 0x022554); |
179 | 179 | for (i = 0; i < parts; i++) { | |
180 | if (!(mask & (1 << i))) | ||
181 | priv->part_nr++; | ||
182 | } | ||
180 | priv->subp_nr = nv_rd32(priv, 0x17e8dc) >> 28; | 183 | priv->subp_nr = nv_rd32(priv, 0x17e8dc) >> 28; |
181 | 184 | ||
182 | nv_mask(priv, 0x17e820, 0x00100000, 0x00000000); /* INTR_EN &= ~0x10 */ | 185 | nv_mask(priv, 0x17e820, 0x00100000, 0x00000000); /* INTR_EN &= ~0x10 */ |
diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c index 46c152ff0a80..383f4e6ea9d1 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drm.c +++ b/drivers/gpu/drm/nouveau/nouveau_drm.c | |||
@@ -453,18 +453,32 @@ nouveau_do_suspend(struct drm_device *dev) | |||
453 | NV_INFO(drm, "evicting buffers...\n"); | 453 | NV_INFO(drm, "evicting buffers...\n"); |
454 | ttm_bo_evict_mm(&drm->ttm.bdev, TTM_PL_VRAM); | 454 | ttm_bo_evict_mm(&drm->ttm.bdev, TTM_PL_VRAM); |
455 | 455 | ||
456 | NV_INFO(drm, "waiting for kernel channels to go idle...\n"); | ||
457 | if (drm->cechan) { | ||
458 | ret = nouveau_channel_idle(drm->cechan); | ||
459 | if (ret) | ||
460 | return ret; | ||
461 | } | ||
462 | |||
463 | if (drm->channel) { | ||
464 | ret = nouveau_channel_idle(drm->channel); | ||
465 | if (ret) | ||
466 | return ret; | ||
467 | } | ||
468 | |||
469 | NV_INFO(drm, "suspending client object trees...\n"); | ||
456 | if (drm->fence && nouveau_fence(drm)->suspend) { | 470 | if (drm->fence && nouveau_fence(drm)->suspend) { |
457 | if (!nouveau_fence(drm)->suspend(drm)) | 471 | if (!nouveau_fence(drm)->suspend(drm)) |
458 | return -ENOMEM; | 472 | return -ENOMEM; |
459 | } | 473 | } |
460 | 474 | ||
461 | NV_INFO(drm, "suspending client object trees...\n"); | ||
462 | list_for_each_entry(cli, &drm->clients, head) { | 475 | list_for_each_entry(cli, &drm->clients, head) { |
463 | ret = nouveau_client_fini(&cli->base, true); | 476 | ret = nouveau_client_fini(&cli->base, true); |
464 | if (ret) | 477 | if (ret) |
465 | goto fail_client; | 478 | goto fail_client; |
466 | } | 479 | } |
467 | 480 | ||
481 | NV_INFO(drm, "suspending kernel object tree...\n"); | ||
468 | ret = nouveau_client_fini(&drm->client.base, true); | 482 | ret = nouveau_client_fini(&drm->client.base, true); |
469 | if (ret) | 483 | if (ret) |
470 | goto fail_client; | 484 | goto fail_client; |
@@ -514,17 +528,18 @@ nouveau_do_resume(struct drm_device *dev) | |||
514 | 528 | ||
515 | nouveau_agp_reset(drm); | 529 | nouveau_agp_reset(drm); |
516 | 530 | ||
517 | NV_INFO(drm, "resuming client object trees...\n"); | 531 | NV_INFO(drm, "resuming kernel object tree...\n"); |
518 | nouveau_client_init(&drm->client.base); | 532 | nouveau_client_init(&drm->client.base); |
519 | nouveau_agp_init(drm); | 533 | nouveau_agp_init(drm); |
520 | 534 | ||
535 | NV_INFO(drm, "resuming client object trees...\n"); | ||
536 | if (drm->fence && nouveau_fence(drm)->resume) | ||
537 | nouveau_fence(drm)->resume(drm); | ||
538 | |||
521 | list_for_each_entry(cli, &drm->clients, head) { | 539 | list_for_each_entry(cli, &drm->clients, head) { |
522 | nouveau_client_init(&cli->base); | 540 | nouveau_client_init(&cli->base); |
523 | } | 541 | } |
524 | 542 | ||
525 | if (drm->fence && nouveau_fence(drm)->resume) | ||
526 | nouveau_fence(drm)->resume(drm); | ||
527 | |||
528 | nouveau_run_vbios_init(dev); | 543 | nouveau_run_vbios_init(dev); |
529 | nouveau_pm_resume(dev); | 544 | nouveau_pm_resume(dev); |
530 | 545 | ||
diff --git a/drivers/gpu/drm/qxl/qxl_cmd.c b/drivers/gpu/drm/qxl/qxl_cmd.c index 08b0823c93d5..f86771481317 100644 --- a/drivers/gpu/drm/qxl/qxl_cmd.c +++ b/drivers/gpu/drm/qxl/qxl_cmd.c | |||
@@ -277,7 +277,7 @@ out_unref: | |||
277 | return 0; | 277 | return 0; |
278 | } | 278 | } |
279 | 279 | ||
280 | static int wait_for_io_cmd_user(struct qxl_device *qdev, uint8_t val, long port) | 280 | static int wait_for_io_cmd_user(struct qxl_device *qdev, uint8_t val, long port, bool intr) |
281 | { | 281 | { |
282 | int irq_num; | 282 | int irq_num; |
283 | long addr = qdev->io_base + port; | 283 | long addr = qdev->io_base + port; |
@@ -285,20 +285,29 @@ static int wait_for_io_cmd_user(struct qxl_device *qdev, uint8_t val, long port) | |||
285 | 285 | ||
286 | mutex_lock(&qdev->async_io_mutex); | 286 | mutex_lock(&qdev->async_io_mutex); |
287 | irq_num = atomic_read(&qdev->irq_received_io_cmd); | 287 | irq_num = atomic_read(&qdev->irq_received_io_cmd); |
288 | |||
289 | |||
290 | if (qdev->last_sent_io_cmd > irq_num) { | 288 | if (qdev->last_sent_io_cmd > irq_num) { |
291 | ret = wait_event_interruptible(qdev->io_cmd_event, | 289 | if (intr) |
292 | atomic_read(&qdev->irq_received_io_cmd) > irq_num); | 290 | ret = wait_event_interruptible_timeout(qdev->io_cmd_event, |
293 | if (ret) | 291 | atomic_read(&qdev->irq_received_io_cmd) > irq_num, 5*HZ); |
292 | else | ||
293 | ret = wait_event_timeout(qdev->io_cmd_event, | ||
294 | atomic_read(&qdev->irq_received_io_cmd) > irq_num, 5*HZ); | ||
295 | /* 0 is timeout, just bail the "hw" has gone away */ | ||
296 | if (ret <= 0) | ||
294 | goto out; | 297 | goto out; |
295 | irq_num = atomic_read(&qdev->irq_received_io_cmd); | 298 | irq_num = atomic_read(&qdev->irq_received_io_cmd); |
296 | } | 299 | } |
297 | outb(val, addr); | 300 | outb(val, addr); |
298 | qdev->last_sent_io_cmd = irq_num + 1; | 301 | qdev->last_sent_io_cmd = irq_num + 1; |
299 | ret = wait_event_interruptible(qdev->io_cmd_event, | 302 | if (intr) |
300 | atomic_read(&qdev->irq_received_io_cmd) > irq_num); | 303 | ret = wait_event_interruptible_timeout(qdev->io_cmd_event, |
304 | atomic_read(&qdev->irq_received_io_cmd) > irq_num, 5*HZ); | ||
305 | else | ||
306 | ret = wait_event_timeout(qdev->io_cmd_event, | ||
307 | atomic_read(&qdev->irq_received_io_cmd) > irq_num, 5*HZ); | ||
301 | out: | 308 | out: |
309 | if (ret > 0) | ||
310 | ret = 0; | ||
302 | mutex_unlock(&qdev->async_io_mutex); | 311 | mutex_unlock(&qdev->async_io_mutex); |
303 | return ret; | 312 | return ret; |
304 | } | 313 | } |
@@ -308,7 +317,7 @@ static void wait_for_io_cmd(struct qxl_device *qdev, uint8_t val, long port) | |||
308 | int ret; | 317 | int ret; |
309 | 318 | ||
310 | restart: | 319 | restart: |
311 | ret = wait_for_io_cmd_user(qdev, val, port); | 320 | ret = wait_for_io_cmd_user(qdev, val, port, false); |
312 | if (ret == -ERESTARTSYS) | 321 | if (ret == -ERESTARTSYS) |
313 | goto restart; | 322 | goto restart; |
314 | } | 323 | } |
@@ -340,7 +349,7 @@ int qxl_io_update_area(struct qxl_device *qdev, struct qxl_bo *surf, | |||
340 | mutex_lock(&qdev->update_area_mutex); | 349 | mutex_lock(&qdev->update_area_mutex); |
341 | qdev->ram_header->update_area = *area; | 350 | qdev->ram_header->update_area = *area; |
342 | qdev->ram_header->update_surface = surface_id; | 351 | qdev->ram_header->update_surface = surface_id; |
343 | ret = wait_for_io_cmd_user(qdev, 0, QXL_IO_UPDATE_AREA_ASYNC); | 352 | ret = wait_for_io_cmd_user(qdev, 0, QXL_IO_UPDATE_AREA_ASYNC, true); |
344 | mutex_unlock(&qdev->update_area_mutex); | 353 | mutex_unlock(&qdev->update_area_mutex); |
345 | return ret; | 354 | return ret; |
346 | } | 355 | } |
diff --git a/drivers/gpu/drm/qxl/qxl_display.c b/drivers/gpu/drm/qxl/qxl_display.c index fcfd4436ceed..823d29e926ec 100644 --- a/drivers/gpu/drm/qxl/qxl_display.c +++ b/drivers/gpu/drm/qxl/qxl_display.c | |||
@@ -428,10 +428,10 @@ static int qxl_framebuffer_surface_dirty(struct drm_framebuffer *fb, | |||
428 | int inc = 1; | 428 | int inc = 1; |
429 | 429 | ||
430 | qobj = gem_to_qxl_bo(qxl_fb->obj); | 430 | qobj = gem_to_qxl_bo(qxl_fb->obj); |
431 | if (qxl_fb != qdev->active_user_framebuffer) { | 431 | /* if we aren't primary surface ignore this */ |
432 | DRM_INFO("%s: qxl_fb 0x%p != qdev->active_user_framebuffer 0x%p\n", | 432 | if (!qobj->is_primary) |
433 | __func__, qxl_fb, qdev->active_user_framebuffer); | 433 | return 0; |
434 | } | 434 | |
435 | if (!num_clips) { | 435 | if (!num_clips) { |
436 | num_clips = 1; | 436 | num_clips = 1; |
437 | clips = &norect; | 437 | clips = &norect; |
@@ -604,7 +604,6 @@ static int qxl_crtc_mode_set(struct drm_crtc *crtc, | |||
604 | mode->hdisplay, | 604 | mode->hdisplay, |
605 | mode->vdisplay); | 605 | mode->vdisplay); |
606 | } | 606 | } |
607 | qdev->mode_set = true; | ||
608 | return 0; | 607 | return 0; |
609 | } | 608 | } |
610 | 609 | ||
@@ -893,7 +892,6 @@ qxl_user_framebuffer_create(struct drm_device *dev, | |||
893 | { | 892 | { |
894 | struct drm_gem_object *obj; | 893 | struct drm_gem_object *obj; |
895 | struct qxl_framebuffer *qxl_fb; | 894 | struct qxl_framebuffer *qxl_fb; |
896 | struct qxl_device *qdev = dev->dev_private; | ||
897 | int ret; | 895 | int ret; |
898 | 896 | ||
899 | obj = drm_gem_object_lookup(dev, file_priv, mode_cmd->handles[0]); | 897 | obj = drm_gem_object_lookup(dev, file_priv, mode_cmd->handles[0]); |
@@ -909,13 +907,6 @@ qxl_user_framebuffer_create(struct drm_device *dev, | |||
909 | return NULL; | 907 | return NULL; |
910 | } | 908 | } |
911 | 909 | ||
912 | if (qdev->active_user_framebuffer) { | ||
913 | DRM_INFO("%s: active_user_framebuffer %p -> %p\n", | ||
914 | __func__, | ||
915 | qdev->active_user_framebuffer, qxl_fb); | ||
916 | } | ||
917 | qdev->active_user_framebuffer = qxl_fb; | ||
918 | |||
919 | return &qxl_fb->base; | 910 | return &qxl_fb->base; |
920 | } | 911 | } |
921 | 912 | ||
diff --git a/drivers/gpu/drm/qxl/qxl_drv.h b/drivers/gpu/drm/qxl/qxl_drv.h index 52b582c211da..43d06ab28a21 100644 --- a/drivers/gpu/drm/qxl/qxl_drv.h +++ b/drivers/gpu/drm/qxl/qxl_drv.h | |||
@@ -255,12 +255,6 @@ struct qxl_device { | |||
255 | struct qxl_gem gem; | 255 | struct qxl_gem gem; |
256 | struct qxl_mode_info mode_info; | 256 | struct qxl_mode_info mode_info; |
257 | 257 | ||
258 | /* | ||
259 | * last created framebuffer with fb_create | ||
260 | * only used by debugfs dumbppm | ||
261 | */ | ||
262 | struct qxl_framebuffer *active_user_framebuffer; | ||
263 | |||
264 | struct fb_info *fbdev_info; | 258 | struct fb_info *fbdev_info; |
265 | struct qxl_framebuffer *fbdev_qfb; | 259 | struct qxl_framebuffer *fbdev_qfb; |
266 | void *ram_physical; | 260 | void *ram_physical; |
@@ -270,7 +264,6 @@ struct qxl_device { | |||
270 | struct qxl_ring *cursor_ring; | 264 | struct qxl_ring *cursor_ring; |
271 | 265 | ||
272 | struct qxl_ram_header *ram_header; | 266 | struct qxl_ram_header *ram_header; |
273 | bool mode_set; | ||
274 | 267 | ||
275 | bool primary_created; | 268 | bool primary_created; |
276 | 269 | ||
diff --git a/drivers/gpu/drm/qxl/qxl_ioctl.c b/drivers/gpu/drm/qxl/qxl_ioctl.c index 04b64f9cbfdb..6db7370373ea 100644 --- a/drivers/gpu/drm/qxl/qxl_ioctl.c +++ b/drivers/gpu/drm/qxl/qxl_ioctl.c | |||
@@ -294,6 +294,7 @@ static int qxl_update_area_ioctl(struct drm_device *dev, void *data, | |||
294 | goto out; | 294 | goto out; |
295 | 295 | ||
296 | if (!qobj->pin_count) { | 296 | if (!qobj->pin_count) { |
297 | qxl_ttm_placement_from_domain(qobj, qobj->type); | ||
297 | ret = ttm_bo_validate(&qobj->tbo, &qobj->placement, | 298 | ret = ttm_bo_validate(&qobj->tbo, &qobj->placement, |
298 | true, false); | 299 | true, false); |
299 | if (unlikely(ret)) | 300 | if (unlikely(ret)) |
diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c index 6d6fdb3ba0d0..d5df8fd10217 100644 --- a/drivers/gpu/drm/radeon/atombios_crtc.c +++ b/drivers/gpu/drm/radeon/atombios_crtc.c | |||
@@ -1811,12 +1811,9 @@ static bool atombios_crtc_mode_fixup(struct drm_crtc *crtc, | |||
1811 | 1811 | ||
1812 | static void atombios_crtc_prepare(struct drm_crtc *crtc) | 1812 | static void atombios_crtc_prepare(struct drm_crtc *crtc) |
1813 | { | 1813 | { |
1814 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); | ||
1815 | struct drm_device *dev = crtc->dev; | 1814 | struct drm_device *dev = crtc->dev; |
1816 | struct radeon_device *rdev = dev->dev_private; | 1815 | struct radeon_device *rdev = dev->dev_private; |
1817 | 1816 | ||
1818 | radeon_crtc->in_mode_set = true; | ||
1819 | |||
1820 | /* disable crtc pair power gating before programming */ | 1817 | /* disable crtc pair power gating before programming */ |
1821 | if (ASIC_IS_DCE6(rdev)) | 1818 | if (ASIC_IS_DCE6(rdev)) |
1822 | atombios_powergate_crtc(crtc, ATOM_DISABLE); | 1819 | atombios_powergate_crtc(crtc, ATOM_DISABLE); |
@@ -1827,11 +1824,8 @@ static void atombios_crtc_prepare(struct drm_crtc *crtc) | |||
1827 | 1824 | ||
1828 | static void atombios_crtc_commit(struct drm_crtc *crtc) | 1825 | static void atombios_crtc_commit(struct drm_crtc *crtc) |
1829 | { | 1826 | { |
1830 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); | ||
1831 | |||
1832 | atombios_crtc_dpms(crtc, DRM_MODE_DPMS_ON); | 1827 | atombios_crtc_dpms(crtc, DRM_MODE_DPMS_ON); |
1833 | atombios_lock_crtc(crtc, ATOM_DISABLE); | 1828 | atombios_lock_crtc(crtc, ATOM_DISABLE); |
1834 | radeon_crtc->in_mode_set = false; | ||
1835 | } | 1829 | } |
1836 | 1830 | ||
1837 | static void atombios_crtc_disable(struct drm_crtc *crtc) | 1831 | static void atombios_crtc_disable(struct drm_crtc *crtc) |
diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index 105bafb6c29d..8f9e2d31b255 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c | |||
@@ -2343,11 +2343,13 @@ void evergreen_mc_stop(struct radeon_device *rdev, struct evergreen_mc_save *sav | |||
2343 | u32 crtc_enabled, tmp, frame_count, blackout; | 2343 | u32 crtc_enabled, tmp, frame_count, blackout; |
2344 | int i, j; | 2344 | int i, j; |
2345 | 2345 | ||
2346 | save->vga_render_control = RREG32(VGA_RENDER_CONTROL); | 2346 | if (!ASIC_IS_NODCE(rdev)) { |
2347 | save->vga_hdp_control = RREG32(VGA_HDP_CONTROL); | 2347 | save->vga_render_control = RREG32(VGA_RENDER_CONTROL); |
2348 | save->vga_hdp_control = RREG32(VGA_HDP_CONTROL); | ||
2348 | 2349 | ||
2349 | /* disable VGA render */ | 2350 | /* disable VGA render */ |
2350 | WREG32(VGA_RENDER_CONTROL, 0); | 2351 | WREG32(VGA_RENDER_CONTROL, 0); |
2352 | } | ||
2351 | /* blank the display controllers */ | 2353 | /* blank the display controllers */ |
2352 | for (i = 0; i < rdev->num_crtc; i++) { | 2354 | for (i = 0; i < rdev->num_crtc; i++) { |
2353 | crtc_enabled = RREG32(EVERGREEN_CRTC_CONTROL + crtc_offsets[i]) & EVERGREEN_CRTC_MASTER_EN; | 2355 | crtc_enabled = RREG32(EVERGREEN_CRTC_CONTROL + crtc_offsets[i]) & EVERGREEN_CRTC_MASTER_EN; |
@@ -2438,8 +2440,11 @@ void evergreen_mc_resume(struct radeon_device *rdev, struct evergreen_mc_save *s | |||
2438 | WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS + crtc_offsets[i], | 2440 | WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS + crtc_offsets[i], |
2439 | (u32)rdev->mc.vram_start); | 2441 | (u32)rdev->mc.vram_start); |
2440 | } | 2442 | } |
2441 | WREG32(EVERGREEN_VGA_MEMORY_BASE_ADDRESS_HIGH, upper_32_bits(rdev->mc.vram_start)); | 2443 | |
2442 | WREG32(EVERGREEN_VGA_MEMORY_BASE_ADDRESS, (u32)rdev->mc.vram_start); | 2444 | if (!ASIC_IS_NODCE(rdev)) { |
2445 | WREG32(EVERGREEN_VGA_MEMORY_BASE_ADDRESS_HIGH, upper_32_bits(rdev->mc.vram_start)); | ||
2446 | WREG32(EVERGREEN_VGA_MEMORY_BASE_ADDRESS, (u32)rdev->mc.vram_start); | ||
2447 | } | ||
2443 | 2448 | ||
2444 | /* unlock regs and wait for update */ | 2449 | /* unlock regs and wait for update */ |
2445 | for (i = 0; i < rdev->num_crtc; i++) { | 2450 | for (i = 0; i < rdev->num_crtc; i++) { |
@@ -2499,10 +2504,12 @@ void evergreen_mc_resume(struct radeon_device *rdev, struct evergreen_mc_save *s | |||
2499 | } | 2504 | } |
2500 | } | 2505 | } |
2501 | } | 2506 | } |
2502 | /* Unlock vga access */ | 2507 | if (!ASIC_IS_NODCE(rdev)) { |
2503 | WREG32(VGA_HDP_CONTROL, save->vga_hdp_control); | 2508 | /* Unlock vga access */ |
2504 | mdelay(1); | 2509 | WREG32(VGA_HDP_CONTROL, save->vga_hdp_control); |
2505 | WREG32(VGA_RENDER_CONTROL, save->vga_render_control); | 2510 | mdelay(1); |
2511 | WREG32(VGA_RENDER_CONTROL, save->vga_render_control); | ||
2512 | } | ||
2506 | } | 2513 | } |
2507 | 2514 | ||
2508 | void evergreen_mc_program(struct radeon_device *rdev) | 2515 | void evergreen_mc_program(struct radeon_device *rdev) |
@@ -3405,8 +3412,8 @@ int evergreen_mc_init(struct radeon_device *rdev) | |||
3405 | rdev->mc.real_vram_size = RREG32(CONFIG_MEMSIZE); | 3412 | rdev->mc.real_vram_size = RREG32(CONFIG_MEMSIZE); |
3406 | } else { | 3413 | } else { |
3407 | /* size in MB on evergreen/cayman/tn */ | 3414 | /* size in MB on evergreen/cayman/tn */ |
3408 | rdev->mc.mc_vram_size = RREG32(CONFIG_MEMSIZE) * 1024 * 1024; | 3415 | rdev->mc.mc_vram_size = RREG32(CONFIG_MEMSIZE) * 1024ULL * 1024ULL; |
3409 | rdev->mc.real_vram_size = RREG32(CONFIG_MEMSIZE) * 1024 * 1024; | 3416 | rdev->mc.real_vram_size = RREG32(CONFIG_MEMSIZE) * 1024ULL * 1024ULL; |
3410 | } | 3417 | } |
3411 | rdev->mc.visible_vram_size = rdev->mc.aper_size; | 3418 | rdev->mc.visible_vram_size = rdev->mc.aper_size; |
3412 | r700_vram_gtt_location(rdev, &rdev->mc); | 3419 | r700_vram_gtt_location(rdev, &rdev->mc); |
diff --git a/drivers/gpu/drm/radeon/evergreen_hdmi.c b/drivers/gpu/drm/radeon/evergreen_hdmi.c index b4ab8ceb1654..ed7c8a768092 100644 --- a/drivers/gpu/drm/radeon/evergreen_hdmi.c +++ b/drivers/gpu/drm/radeon/evergreen_hdmi.c | |||
@@ -154,19 +154,18 @@ static void evergreen_audio_set_dto(struct drm_encoder *encoder, u32 clock) | |||
154 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | 154 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
155 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; | 155 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; |
156 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc); | 156 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc); |
157 | u32 base_rate = 48000; | 157 | u32 base_rate = 24000; |
158 | 158 | ||
159 | if (!dig || !dig->afmt) | 159 | if (!dig || !dig->afmt) |
160 | return; | 160 | return; |
161 | 161 | ||
162 | /* XXX: properly calculate this */ | ||
163 | /* XXX two dtos; generally use dto0 for hdmi */ | 162 | /* XXX two dtos; generally use dto0 for hdmi */ |
164 | /* Express [24MHz / target pixel clock] as an exact rational | 163 | /* Express [24MHz / target pixel clock] as an exact rational |
165 | * number (coefficient of two integer numbers. DCCG_AUDIO_DTOx_PHASE | 164 | * number (coefficient of two integer numbers. DCCG_AUDIO_DTOx_PHASE |
166 | * is the numerator, DCCG_AUDIO_DTOx_MODULE is the denominator | 165 | * is the numerator, DCCG_AUDIO_DTOx_MODULE is the denominator |
167 | */ | 166 | */ |
168 | WREG32(DCCG_AUDIO_DTO0_PHASE, (base_rate*50) & 0xffffff); | 167 | WREG32(DCCG_AUDIO_DTO0_PHASE, base_rate * 100); |
169 | WREG32(DCCG_AUDIO_DTO0_MODULE, (clock*100) & 0xffffff); | 168 | WREG32(DCCG_AUDIO_DTO0_MODULE, clock * 100); |
170 | WREG32(DCCG_AUDIO_DTO_SOURCE, DCCG_AUDIO_DTO0_SOURCE_SEL(radeon_crtc->crtc_id)); | 169 | WREG32(DCCG_AUDIO_DTO_SOURCE, DCCG_AUDIO_DTO0_SOURCE_SEL(radeon_crtc->crtc_id)); |
171 | } | 170 | } |
172 | 171 | ||
diff --git a/drivers/gpu/drm/radeon/r300_cmdbuf.c b/drivers/gpu/drm/radeon/r300_cmdbuf.c index 865e2c9980db..60170ea5e3a2 100644 --- a/drivers/gpu/drm/radeon/r300_cmdbuf.c +++ b/drivers/gpu/drm/radeon/r300_cmdbuf.c | |||
@@ -75,7 +75,7 @@ static int r300_emit_cliprects(drm_radeon_private_t *dev_priv, | |||
75 | OUT_RING(CP_PACKET0(R300_RE_CLIPRECT_TL_0, nr * 2 - 1)); | 75 | OUT_RING(CP_PACKET0(R300_RE_CLIPRECT_TL_0, nr * 2 - 1)); |
76 | 76 | ||
77 | for (i = 0; i < nr; ++i) { | 77 | for (i = 0; i < nr; ++i) { |
78 | if (DRM_COPY_FROM_USER_UNCHECKED | 78 | if (DRM_COPY_FROM_USER |
79 | (&box, &cmdbuf->boxes[n + i], sizeof(box))) { | 79 | (&box, &cmdbuf->boxes[n + i], sizeof(box))) { |
80 | DRM_ERROR("copy cliprect faulted\n"); | 80 | DRM_ERROR("copy cliprect faulted\n"); |
81 | return -EFAULT; | 81 | return -EFAULT; |
diff --git a/drivers/gpu/drm/radeon/r600_hdmi.c b/drivers/gpu/drm/radeon/r600_hdmi.c index 47f180a79352..456750a0daa5 100644 --- a/drivers/gpu/drm/radeon/r600_hdmi.c +++ b/drivers/gpu/drm/radeon/r600_hdmi.c | |||
@@ -232,7 +232,7 @@ void r600_audio_set_dto(struct drm_encoder *encoder, u32 clock) | |||
232 | struct radeon_device *rdev = dev->dev_private; | 232 | struct radeon_device *rdev = dev->dev_private; |
233 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | 233 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
234 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; | 234 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; |
235 | u32 base_rate = 48000; | 235 | u32 base_rate = 24000; |
236 | 236 | ||
237 | if (!dig || !dig->afmt) | 237 | if (!dig || !dig->afmt) |
238 | return; | 238 | return; |
@@ -240,7 +240,6 @@ void r600_audio_set_dto(struct drm_encoder *encoder, u32 clock) | |||
240 | /* there are two DTOs selected by DCCG_AUDIO_DTO_SELECT. | 240 | /* there are two DTOs selected by DCCG_AUDIO_DTO_SELECT. |
241 | * doesn't matter which one you use. Just use the first one. | 241 | * doesn't matter which one you use. Just use the first one. |
242 | */ | 242 | */ |
243 | /* XXX: properly calculate this */ | ||
244 | /* XXX two dtos; generally use dto0 for hdmi */ | 243 | /* XXX two dtos; generally use dto0 for hdmi */ |
245 | /* Express [24MHz / target pixel clock] as an exact rational | 244 | /* Express [24MHz / target pixel clock] as an exact rational |
246 | * number (coefficient of two integer numbers. DCCG_AUDIO_DTOx_PHASE | 245 | * number (coefficient of two integer numbers. DCCG_AUDIO_DTOx_PHASE |
@@ -250,13 +249,13 @@ void r600_audio_set_dto(struct drm_encoder *encoder, u32 clock) | |||
250 | /* according to the reg specs, this should DCE3.2 only, but in | 249 | /* according to the reg specs, this should DCE3.2 only, but in |
251 | * practice it seems to cover DCE3.0 as well. | 250 | * practice it seems to cover DCE3.0 as well. |
252 | */ | 251 | */ |
253 | WREG32(DCCG_AUDIO_DTO0_PHASE, base_rate * 50); | 252 | WREG32(DCCG_AUDIO_DTO0_PHASE, base_rate * 100); |
254 | WREG32(DCCG_AUDIO_DTO0_MODULE, clock * 100); | 253 | WREG32(DCCG_AUDIO_DTO0_MODULE, clock * 100); |
255 | WREG32(DCCG_AUDIO_DTO_SELECT, 0); /* select DTO0 */ | 254 | WREG32(DCCG_AUDIO_DTO_SELECT, 0); /* select DTO0 */ |
256 | } else { | 255 | } else { |
257 | /* according to the reg specs, this should be DCE2.0 and DCE3.0 */ | 256 | /* according to the reg specs, this should be DCE2.0 and DCE3.0 */ |
258 | WREG32(AUDIO_DTO, AUDIO_DTO_PHASE(base_rate * 50) | | 257 | WREG32(AUDIO_DTO, AUDIO_DTO_PHASE(base_rate / 10) | |
259 | AUDIO_DTO_MODULE(clock * 100)); | 258 | AUDIO_DTO_MODULE(clock / 10)); |
260 | } | 259 | } |
261 | } | 260 | } |
262 | 261 | ||
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 1442ce765d48..142ce6cc69f5 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h | |||
@@ -1694,6 +1694,7 @@ struct radeon_device { | |||
1694 | int num_crtc; /* number of crtcs */ | 1694 | int num_crtc; /* number of crtcs */ |
1695 | struct mutex dc_hw_i2c_mutex; /* display controller hw i2c mutex */ | 1695 | struct mutex dc_hw_i2c_mutex; /* display controller hw i2c mutex */ |
1696 | bool audio_enabled; | 1696 | bool audio_enabled; |
1697 | bool has_uvd; | ||
1697 | struct r600_audio audio_status; /* audio stuff */ | 1698 | struct r600_audio audio_status; /* audio stuff */ |
1698 | struct notifier_block acpi_nb; | 1699 | struct notifier_block acpi_nb; |
1699 | /* only one userspace can use Hyperz features or CMASK at a time */ | 1700 | /* only one userspace can use Hyperz features or CMASK at a time */ |
@@ -1838,6 +1839,7 @@ void r100_pll_errata_after_index(struct radeon_device *rdev); | |||
1838 | #define ASIC_IS_DCE61(rdev) ((rdev->family >= CHIP_ARUBA) && \ | 1839 | #define ASIC_IS_DCE61(rdev) ((rdev->family >= CHIP_ARUBA) && \ |
1839 | (rdev->flags & RADEON_IS_IGP)) | 1840 | (rdev->flags & RADEON_IS_IGP)) |
1840 | #define ASIC_IS_DCE64(rdev) ((rdev->family == CHIP_OLAND)) | 1841 | #define ASIC_IS_DCE64(rdev) ((rdev->family == CHIP_OLAND)) |
1842 | #define ASIC_IS_NODCE(rdev) ((rdev->family == CHIP_HAINAN)) | ||
1841 | 1843 | ||
1842 | /* | 1844 | /* |
1843 | * BIOS helpers. | 1845 | * BIOS helpers. |
diff --git a/drivers/gpu/drm/radeon/radeon_asic.c b/drivers/gpu/drm/radeon/radeon_asic.c index 6417132c50cf..06b8c19ab19e 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.c +++ b/drivers/gpu/drm/radeon/radeon_asic.c | |||
@@ -1935,6 +1935,8 @@ int radeon_asic_init(struct radeon_device *rdev) | |||
1935 | else | 1935 | else |
1936 | rdev->num_crtc = 2; | 1936 | rdev->num_crtc = 2; |
1937 | 1937 | ||
1938 | rdev->has_uvd = false; | ||
1939 | |||
1938 | switch (rdev->family) { | 1940 | switch (rdev->family) { |
1939 | case CHIP_R100: | 1941 | case CHIP_R100: |
1940 | case CHIP_RV100: | 1942 | case CHIP_RV100: |
@@ -1999,16 +2001,22 @@ int radeon_asic_init(struct radeon_device *rdev) | |||
1999 | case CHIP_RV635: | 2001 | case CHIP_RV635: |
2000 | case CHIP_RV670: | 2002 | case CHIP_RV670: |
2001 | rdev->asic = &r600_asic; | 2003 | rdev->asic = &r600_asic; |
2004 | if (rdev->family == CHIP_R600) | ||
2005 | rdev->has_uvd = false; | ||
2006 | else | ||
2007 | rdev->has_uvd = true; | ||
2002 | break; | 2008 | break; |
2003 | case CHIP_RS780: | 2009 | case CHIP_RS780: |
2004 | case CHIP_RS880: | 2010 | case CHIP_RS880: |
2005 | rdev->asic = &rs780_asic; | 2011 | rdev->asic = &rs780_asic; |
2012 | rdev->has_uvd = true; | ||
2006 | break; | 2013 | break; |
2007 | case CHIP_RV770: | 2014 | case CHIP_RV770: |
2008 | case CHIP_RV730: | 2015 | case CHIP_RV730: |
2009 | case CHIP_RV710: | 2016 | case CHIP_RV710: |
2010 | case CHIP_RV740: | 2017 | case CHIP_RV740: |
2011 | rdev->asic = &rv770_asic; | 2018 | rdev->asic = &rv770_asic; |
2019 | rdev->has_uvd = true; | ||
2012 | break; | 2020 | break; |
2013 | case CHIP_CEDAR: | 2021 | case CHIP_CEDAR: |
2014 | case CHIP_REDWOOD: | 2022 | case CHIP_REDWOOD: |
@@ -2021,11 +2029,13 @@ int radeon_asic_init(struct radeon_device *rdev) | |||
2021 | else | 2029 | else |
2022 | rdev->num_crtc = 6; | 2030 | rdev->num_crtc = 6; |
2023 | rdev->asic = &evergreen_asic; | 2031 | rdev->asic = &evergreen_asic; |
2032 | rdev->has_uvd = true; | ||
2024 | break; | 2033 | break; |
2025 | case CHIP_PALM: | 2034 | case CHIP_PALM: |
2026 | case CHIP_SUMO: | 2035 | case CHIP_SUMO: |
2027 | case CHIP_SUMO2: | 2036 | case CHIP_SUMO2: |
2028 | rdev->asic = &sumo_asic; | 2037 | rdev->asic = &sumo_asic; |
2038 | rdev->has_uvd = true; | ||
2029 | break; | 2039 | break; |
2030 | case CHIP_BARTS: | 2040 | case CHIP_BARTS: |
2031 | case CHIP_TURKS: | 2041 | case CHIP_TURKS: |
@@ -2036,27 +2046,37 @@ int radeon_asic_init(struct radeon_device *rdev) | |||
2036 | else | 2046 | else |
2037 | rdev->num_crtc = 6; | 2047 | rdev->num_crtc = 6; |
2038 | rdev->asic = &btc_asic; | 2048 | rdev->asic = &btc_asic; |
2049 | rdev->has_uvd = true; | ||
2039 | break; | 2050 | break; |
2040 | case CHIP_CAYMAN: | 2051 | case CHIP_CAYMAN: |
2041 | rdev->asic = &cayman_asic; | 2052 | rdev->asic = &cayman_asic; |
2042 | /* set num crtcs */ | 2053 | /* set num crtcs */ |
2043 | rdev->num_crtc = 6; | 2054 | rdev->num_crtc = 6; |
2055 | rdev->has_uvd = true; | ||
2044 | break; | 2056 | break; |
2045 | case CHIP_ARUBA: | 2057 | case CHIP_ARUBA: |
2046 | rdev->asic = &trinity_asic; | 2058 | rdev->asic = &trinity_asic; |
2047 | /* set num crtcs */ | 2059 | /* set num crtcs */ |
2048 | rdev->num_crtc = 4; | 2060 | rdev->num_crtc = 4; |
2061 | rdev->has_uvd = true; | ||
2049 | break; | 2062 | break; |
2050 | case CHIP_TAHITI: | 2063 | case CHIP_TAHITI: |
2051 | case CHIP_PITCAIRN: | 2064 | case CHIP_PITCAIRN: |
2052 | case CHIP_VERDE: | 2065 | case CHIP_VERDE: |
2053 | case CHIP_OLAND: | 2066 | case CHIP_OLAND: |
2067 | case CHIP_HAINAN: | ||
2054 | rdev->asic = &si_asic; | 2068 | rdev->asic = &si_asic; |
2055 | /* set num crtcs */ | 2069 | /* set num crtcs */ |
2056 | if (rdev->family == CHIP_OLAND) | 2070 | if (rdev->family == CHIP_HAINAN) |
2071 | rdev->num_crtc = 0; | ||
2072 | else if (rdev->family == CHIP_OLAND) | ||
2057 | rdev->num_crtc = 2; | 2073 | rdev->num_crtc = 2; |
2058 | else | 2074 | else |
2059 | rdev->num_crtc = 6; | 2075 | rdev->num_crtc = 6; |
2076 | if (rdev->family == CHIP_HAINAN) | ||
2077 | rdev->has_uvd = false; | ||
2078 | else | ||
2079 | rdev->has_uvd = true; | ||
2060 | break; | 2080 | break; |
2061 | default: | 2081 | default: |
2062 | /* FIXME: not supported yet */ | 2082 | /* FIXME: not supported yet */ |
diff --git a/drivers/gpu/drm/radeon/radeon_bios.c b/drivers/gpu/drm/radeon/radeon_bios.c index fa3c56fba294..061b227dae0c 100644 --- a/drivers/gpu/drm/radeon/radeon_bios.c +++ b/drivers/gpu/drm/radeon/radeon_bios.c | |||
@@ -244,24 +244,28 @@ static bool ni_read_disabled_bios(struct radeon_device *rdev) | |||
244 | 244 | ||
245 | /* enable the rom */ | 245 | /* enable the rom */ |
246 | WREG32(R600_BUS_CNTL, (bus_cntl & ~R600_BIOS_ROM_DIS)); | 246 | WREG32(R600_BUS_CNTL, (bus_cntl & ~R600_BIOS_ROM_DIS)); |
247 | /* Disable VGA mode */ | 247 | if (!ASIC_IS_NODCE(rdev)) { |
248 | WREG32(AVIVO_D1VGA_CONTROL, | 248 | /* Disable VGA mode */ |
249 | (d1vga_control & ~(AVIVO_DVGA_CONTROL_MODE_ENABLE | | 249 | WREG32(AVIVO_D1VGA_CONTROL, |
250 | AVIVO_DVGA_CONTROL_TIMING_SELECT))); | 250 | (d1vga_control & ~(AVIVO_DVGA_CONTROL_MODE_ENABLE | |
251 | WREG32(AVIVO_D2VGA_CONTROL, | 251 | AVIVO_DVGA_CONTROL_TIMING_SELECT))); |
252 | (d2vga_control & ~(AVIVO_DVGA_CONTROL_MODE_ENABLE | | 252 | WREG32(AVIVO_D2VGA_CONTROL, |
253 | AVIVO_DVGA_CONTROL_TIMING_SELECT))); | 253 | (d2vga_control & ~(AVIVO_DVGA_CONTROL_MODE_ENABLE | |
254 | WREG32(AVIVO_VGA_RENDER_CONTROL, | 254 | AVIVO_DVGA_CONTROL_TIMING_SELECT))); |
255 | (vga_render_control & ~AVIVO_VGA_VSTATUS_CNTL_MASK)); | 255 | WREG32(AVIVO_VGA_RENDER_CONTROL, |
256 | (vga_render_control & ~AVIVO_VGA_VSTATUS_CNTL_MASK)); | ||
257 | } | ||
256 | WREG32(R600_ROM_CNTL, rom_cntl | R600_SCK_OVERWRITE); | 258 | WREG32(R600_ROM_CNTL, rom_cntl | R600_SCK_OVERWRITE); |
257 | 259 | ||
258 | r = radeon_read_bios(rdev); | 260 | r = radeon_read_bios(rdev); |
259 | 261 | ||
260 | /* restore regs */ | 262 | /* restore regs */ |
261 | WREG32(R600_BUS_CNTL, bus_cntl); | 263 | WREG32(R600_BUS_CNTL, bus_cntl); |
262 | WREG32(AVIVO_D1VGA_CONTROL, d1vga_control); | 264 | if (!ASIC_IS_NODCE(rdev)) { |
263 | WREG32(AVIVO_D2VGA_CONTROL, d2vga_control); | 265 | WREG32(AVIVO_D1VGA_CONTROL, d1vga_control); |
264 | WREG32(AVIVO_VGA_RENDER_CONTROL, vga_render_control); | 266 | WREG32(AVIVO_D2VGA_CONTROL, d2vga_control); |
267 | WREG32(AVIVO_VGA_RENDER_CONTROL, vga_render_control); | ||
268 | } | ||
265 | WREG32(R600_ROM_CNTL, rom_cntl); | 269 | WREG32(R600_ROM_CNTL, rom_cntl); |
266 | return r; | 270 | return r; |
267 | } | 271 | } |
diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index a8f608903989..c2c59fb1ea01 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c | |||
@@ -94,6 +94,7 @@ static const char radeon_family_name[][16] = { | |||
94 | "PITCAIRN", | 94 | "PITCAIRN", |
95 | "VERDE", | 95 | "VERDE", |
96 | "OLAND", | 96 | "OLAND", |
97 | "HAINAN", | ||
97 | "LAST", | 98 | "LAST", |
98 | }; | 99 | }; |
99 | 100 | ||
diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c index d33f484ace48..094e7e5ea39e 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.c +++ b/drivers/gpu/drm/radeon/radeon_drv.c | |||
@@ -147,7 +147,7 @@ static inline void radeon_unregister_atpx_handler(void) {} | |||
147 | #endif | 147 | #endif |
148 | 148 | ||
149 | int radeon_no_wb; | 149 | int radeon_no_wb; |
150 | int radeon_modeset = 1; | 150 | int radeon_modeset = -1; |
151 | int radeon_dynclks = -1; | 151 | int radeon_dynclks = -1; |
152 | int radeon_r4xx_atom = 0; | 152 | int radeon_r4xx_atom = 0; |
153 | int radeon_agpmode = 0; | 153 | int radeon_agpmode = 0; |
@@ -456,6 +456,16 @@ static struct pci_driver radeon_kms_pci_driver = { | |||
456 | 456 | ||
457 | static int __init radeon_init(void) | 457 | static int __init radeon_init(void) |
458 | { | 458 | { |
459 | #ifdef CONFIG_VGA_CONSOLE | ||
460 | if (vgacon_text_force() && radeon_modeset == -1) { | ||
461 | DRM_INFO("VGACON disable radeon kernel modesetting.\n"); | ||
462 | radeon_modeset = 0; | ||
463 | } | ||
464 | #endif | ||
465 | /* set to modesetting by default if not nomodeset */ | ||
466 | if (radeon_modeset == -1) | ||
467 | radeon_modeset = 1; | ||
468 | |||
459 | if (radeon_modeset == 1) { | 469 | if (radeon_modeset == 1) { |
460 | DRM_INFO("radeon kernel modesetting enabled.\n"); | 470 | DRM_INFO("radeon kernel modesetting enabled.\n"); |
461 | driver = &kms_driver; | 471 | driver = &kms_driver; |
diff --git a/drivers/gpu/drm/radeon/radeon_family.h b/drivers/gpu/drm/radeon/radeon_family.h index 2d91123f2759..36e9803b077d 100644 --- a/drivers/gpu/drm/radeon/radeon_family.h +++ b/drivers/gpu/drm/radeon/radeon_family.h | |||
@@ -92,6 +92,7 @@ enum radeon_family { | |||
92 | CHIP_PITCAIRN, | 92 | CHIP_PITCAIRN, |
93 | CHIP_VERDE, | 93 | CHIP_VERDE, |
94 | CHIP_OLAND, | 94 | CHIP_OLAND, |
95 | CHIP_HAINAN, | ||
95 | CHIP_LAST, | 96 | CHIP_LAST, |
96 | }; | 97 | }; |
97 | 98 | ||
diff --git a/drivers/gpu/drm/radeon/radeon_legacy_crtc.c b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c index 6857cb4efb76..7cb178a34a0f 100644 --- a/drivers/gpu/drm/radeon/radeon_legacy_crtc.c +++ b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c | |||
@@ -1031,11 +1031,9 @@ static int radeon_crtc_mode_set(struct drm_crtc *crtc, | |||
1031 | 1031 | ||
1032 | static void radeon_crtc_prepare(struct drm_crtc *crtc) | 1032 | static void radeon_crtc_prepare(struct drm_crtc *crtc) |
1033 | { | 1033 | { |
1034 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); | ||
1035 | struct drm_device *dev = crtc->dev; | 1034 | struct drm_device *dev = crtc->dev; |
1036 | struct drm_crtc *crtci; | 1035 | struct drm_crtc *crtci; |
1037 | 1036 | ||
1038 | radeon_crtc->in_mode_set = true; | ||
1039 | /* | 1037 | /* |
1040 | * The hardware wedges sometimes if you reconfigure one CRTC | 1038 | * The hardware wedges sometimes if you reconfigure one CRTC |
1041 | * whilst another is running (see fdo bug #24611). | 1039 | * whilst another is running (see fdo bug #24611). |
@@ -1046,7 +1044,6 @@ static void radeon_crtc_prepare(struct drm_crtc *crtc) | |||
1046 | 1044 | ||
1047 | static void radeon_crtc_commit(struct drm_crtc *crtc) | 1045 | static void radeon_crtc_commit(struct drm_crtc *crtc) |
1048 | { | 1046 | { |
1049 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); | ||
1050 | struct drm_device *dev = crtc->dev; | 1047 | struct drm_device *dev = crtc->dev; |
1051 | struct drm_crtc *crtci; | 1048 | struct drm_crtc *crtci; |
1052 | 1049 | ||
@@ -1057,7 +1054,6 @@ static void radeon_crtc_commit(struct drm_crtc *crtc) | |||
1057 | if (crtci->enabled) | 1054 | if (crtci->enabled) |
1058 | radeon_crtc_dpms(crtci, DRM_MODE_DPMS_ON); | 1055 | radeon_crtc_dpms(crtci, DRM_MODE_DPMS_ON); |
1059 | } | 1056 | } |
1060 | radeon_crtc->in_mode_set = false; | ||
1061 | } | 1057 | } |
1062 | 1058 | ||
1063 | static const struct drm_crtc_helper_funcs legacy_helper_funcs = { | 1059 | static const struct drm_crtc_helper_funcs legacy_helper_funcs = { |
diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h index 44e579e75fd0..69ad4fe224c1 100644 --- a/drivers/gpu/drm/radeon/radeon_mode.h +++ b/drivers/gpu/drm/radeon/radeon_mode.h | |||
@@ -302,7 +302,6 @@ struct radeon_crtc { | |||
302 | u16 lut_r[256], lut_g[256], lut_b[256]; | 302 | u16 lut_r[256], lut_g[256], lut_b[256]; |
303 | bool enabled; | 303 | bool enabled; |
304 | bool can_tile; | 304 | bool can_tile; |
305 | bool in_mode_set; | ||
306 | uint32_t crtc_offset; | 305 | uint32_t crtc_offset; |
307 | struct drm_gem_object *cursor_bo; | 306 | struct drm_gem_object *cursor_bo; |
308 | uint64_t cursor_addr; | 307 | uint64_t cursor_addr; |
diff --git a/drivers/gpu/drm/radeon/radeon_ttm.c b/drivers/gpu/drm/radeon/radeon_ttm.c index 93f760e27a92..6c0ce8915fac 100644 --- a/drivers/gpu/drm/radeon/radeon_ttm.c +++ b/drivers/gpu/drm/radeon/radeon_ttm.c | |||
@@ -726,7 +726,7 @@ int radeon_ttm_init(struct radeon_device *rdev) | |||
726 | return r; | 726 | return r; |
727 | } | 727 | } |
728 | DRM_INFO("radeon: %uM of VRAM memory ready\n", | 728 | DRM_INFO("radeon: %uM of VRAM memory ready\n", |
729 | (unsigned)rdev->mc.real_vram_size / (1024 * 1024)); | 729 | (unsigned) (rdev->mc.real_vram_size / (1024 * 1024))); |
730 | r = ttm_bo_init_mm(&rdev->mman.bdev, TTM_PL_TT, | 730 | r = ttm_bo_init_mm(&rdev->mman.bdev, TTM_PL_TT, |
731 | rdev->mc.gtt_size >> PAGE_SHIFT); | 731 | rdev->mc.gtt_size >> PAGE_SHIFT); |
732 | if (r) { | 732 | if (r) { |
diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c index f0b6c2f87c4d..5ffade69af25 100644 --- a/drivers/gpu/drm/radeon/si.c +++ b/drivers/gpu/drm/radeon/si.c | |||
@@ -60,6 +60,11 @@ MODULE_FIRMWARE("radeon/OLAND_me.bin"); | |||
60 | MODULE_FIRMWARE("radeon/OLAND_ce.bin"); | 60 | MODULE_FIRMWARE("radeon/OLAND_ce.bin"); |
61 | MODULE_FIRMWARE("radeon/OLAND_mc.bin"); | 61 | MODULE_FIRMWARE("radeon/OLAND_mc.bin"); |
62 | MODULE_FIRMWARE("radeon/OLAND_rlc.bin"); | 62 | MODULE_FIRMWARE("radeon/OLAND_rlc.bin"); |
63 | MODULE_FIRMWARE("radeon/HAINAN_pfp.bin"); | ||
64 | MODULE_FIRMWARE("radeon/HAINAN_me.bin"); | ||
65 | MODULE_FIRMWARE("radeon/HAINAN_ce.bin"); | ||
66 | MODULE_FIRMWARE("radeon/HAINAN_mc.bin"); | ||
67 | MODULE_FIRMWARE("radeon/HAINAN_rlc.bin"); | ||
63 | 68 | ||
64 | extern int r600_ih_ring_alloc(struct radeon_device *rdev); | 69 | extern int r600_ih_ring_alloc(struct radeon_device *rdev); |
65 | extern void r600_ih_ring_fini(struct radeon_device *rdev); | 70 | extern void r600_ih_ring_fini(struct radeon_device *rdev); |
@@ -265,6 +270,40 @@ static const u32 oland_golden_registers[] = | |||
265 | 0x15c0, 0x000c0fc0, 0x000c0400 | 270 | 0x15c0, 0x000c0fc0, 0x000c0400 |
266 | }; | 271 | }; |
267 | 272 | ||
273 | static const u32 hainan_golden_registers[] = | ||
274 | { | ||
275 | 0x9a10, 0x00010000, 0x00018208, | ||
276 | 0x9830, 0xffffffff, 0x00000000, | ||
277 | 0x9834, 0xf00fffff, 0x00000400, | ||
278 | 0x9838, 0x0002021c, 0x00020200, | ||
279 | 0xd0c0, 0xff000fff, 0x00000100, | ||
280 | 0xd030, 0x000300c0, 0x00800040, | ||
281 | 0xd8c0, 0xff000fff, 0x00000100, | ||
282 | 0xd830, 0x000300c0, 0x00800040, | ||
283 | 0x2ae4, 0x00073ffe, 0x000022a2, | ||
284 | 0x240c, 0x000007ff, 0x00000000, | ||
285 | 0x8a14, 0xf000001f, 0x00000007, | ||
286 | 0x8b24, 0xffffffff, 0x00ffffff, | ||
287 | 0x8b10, 0x0000ff0f, 0x00000000, | ||
288 | 0x28a4c, 0x07ffffff, 0x4e000000, | ||
289 | 0x28350, 0x3f3f3fff, 0x00000000, | ||
290 | 0x30, 0x000000ff, 0x0040, | ||
291 | 0x34, 0x00000040, 0x00004040, | ||
292 | 0x9100, 0x03e00000, 0x03600000, | ||
293 | 0x9060, 0x0000007f, 0x00000020, | ||
294 | 0x9508, 0x00010000, 0x00010000, | ||
295 | 0xac14, 0x000003ff, 0x000000f1, | ||
296 | 0xac10, 0xffffffff, 0x00000000, | ||
297 | 0xac0c, 0xffffffff, 0x00003210, | ||
298 | 0x88d4, 0x0000001f, 0x00000010, | ||
299 | 0x15c0, 0x000c0fc0, 0x000c0400 | ||
300 | }; | ||
301 | |||
302 | static const u32 hainan_golden_registers2[] = | ||
303 | { | ||
304 | 0x98f8, 0xffffffff, 0x02010001 | ||
305 | }; | ||
306 | |||
268 | static const u32 tahiti_mgcg_cgcg_init[] = | 307 | static const u32 tahiti_mgcg_cgcg_init[] = |
269 | { | 308 | { |
270 | 0xc400, 0xffffffff, 0xfffffffc, | 309 | 0xc400, 0xffffffff, 0xfffffffc, |
@@ -673,6 +712,83 @@ static const u32 oland_mgcg_cgcg_init[] = | |||
673 | 0xd8c0, 0xfffffff0, 0x00000100 | 712 | 0xd8c0, 0xfffffff0, 0x00000100 |
674 | }; | 713 | }; |
675 | 714 | ||
715 | static const u32 hainan_mgcg_cgcg_init[] = | ||
716 | { | ||
717 | 0xc400, 0xffffffff, 0xfffffffc, | ||
718 | 0x802c, 0xffffffff, 0xe0000000, | ||
719 | 0x9a60, 0xffffffff, 0x00000100, | ||
720 | 0x92a4, 0xffffffff, 0x00000100, | ||
721 | 0xc164, 0xffffffff, 0x00000100, | ||
722 | 0x9774, 0xffffffff, 0x00000100, | ||
723 | 0x8984, 0xffffffff, 0x06000100, | ||
724 | 0x8a18, 0xffffffff, 0x00000100, | ||
725 | 0x92a0, 0xffffffff, 0x00000100, | ||
726 | 0xc380, 0xffffffff, 0x00000100, | ||
727 | 0x8b28, 0xffffffff, 0x00000100, | ||
728 | 0x9144, 0xffffffff, 0x00000100, | ||
729 | 0x8d88, 0xffffffff, 0x00000100, | ||
730 | 0x8d8c, 0xffffffff, 0x00000100, | ||
731 | 0x9030, 0xffffffff, 0x00000100, | ||
732 | 0x9034, 0xffffffff, 0x00000100, | ||
733 | 0x9038, 0xffffffff, 0x00000100, | ||
734 | 0x903c, 0xffffffff, 0x00000100, | ||
735 | 0xad80, 0xffffffff, 0x00000100, | ||
736 | 0xac54, 0xffffffff, 0x00000100, | ||
737 | 0x897c, 0xffffffff, 0x06000100, | ||
738 | 0x9868, 0xffffffff, 0x00000100, | ||
739 | 0x9510, 0xffffffff, 0x00000100, | ||
740 | 0xaf04, 0xffffffff, 0x00000100, | ||
741 | 0xae04, 0xffffffff, 0x00000100, | ||
742 | 0x949c, 0xffffffff, 0x00000100, | ||
743 | 0x802c, 0xffffffff, 0xe0000000, | ||
744 | 0x9160, 0xffffffff, 0x00010000, | ||
745 | 0x9164, 0xffffffff, 0x00030002, | ||
746 | 0x9168, 0xffffffff, 0x00040007, | ||
747 | 0x916c, 0xffffffff, 0x00060005, | ||
748 | 0x9170, 0xffffffff, 0x00090008, | ||
749 | 0x9174, 0xffffffff, 0x00020001, | ||
750 | 0x9178, 0xffffffff, 0x00040003, | ||
751 | 0x917c, 0xffffffff, 0x00000007, | ||
752 | 0x9180, 0xffffffff, 0x00060005, | ||
753 | 0x9184, 0xffffffff, 0x00090008, | ||
754 | 0x9188, 0xffffffff, 0x00030002, | ||
755 | 0x918c, 0xffffffff, 0x00050004, | ||
756 | 0x9190, 0xffffffff, 0x00000008, | ||
757 | 0x9194, 0xffffffff, 0x00070006, | ||
758 | 0x9198, 0xffffffff, 0x000a0009, | ||
759 | 0x919c, 0xffffffff, 0x00040003, | ||
760 | 0x91a0, 0xffffffff, 0x00060005, | ||
761 | 0x91a4, 0xffffffff, 0x00000009, | ||
762 | 0x91a8, 0xffffffff, 0x00080007, | ||
763 | 0x91ac, 0xffffffff, 0x000b000a, | ||
764 | 0x91b0, 0xffffffff, 0x00050004, | ||
765 | 0x91b4, 0xffffffff, 0x00070006, | ||
766 | 0x91b8, 0xffffffff, 0x0008000b, | ||
767 | 0x91bc, 0xffffffff, 0x000a0009, | ||
768 | 0x91c0, 0xffffffff, 0x000d000c, | ||
769 | 0x91c4, 0xffffffff, 0x00060005, | ||
770 | 0x91c8, 0xffffffff, 0x00080007, | ||
771 | 0x91cc, 0xffffffff, 0x0000000b, | ||
772 | 0x91d0, 0xffffffff, 0x000a0009, | ||
773 | 0x91d4, 0xffffffff, 0x000d000c, | ||
774 | 0x9150, 0xffffffff, 0x96940200, | ||
775 | 0x8708, 0xffffffff, 0x00900100, | ||
776 | 0xc478, 0xffffffff, 0x00000080, | ||
777 | 0xc404, 0xffffffff, 0x0020003f, | ||
778 | 0x30, 0xffffffff, 0x0000001c, | ||
779 | 0x34, 0x000f0000, 0x000f0000, | ||
780 | 0x160c, 0xffffffff, 0x00000100, | ||
781 | 0x1024, 0xffffffff, 0x00000100, | ||
782 | 0x20a8, 0xffffffff, 0x00000104, | ||
783 | 0x264c, 0x000c0000, 0x000c0000, | ||
784 | 0x2648, 0x000c0000, 0x000c0000, | ||
785 | 0x2f50, 0x00000001, 0x00000001, | ||
786 | 0x30cc, 0xc0000fff, 0x00000104, | ||
787 | 0xc1e4, 0x00000001, 0x00000001, | ||
788 | 0xd0c0, 0xfffffff0, 0x00000100, | ||
789 | 0xd8c0, 0xfffffff0, 0x00000100 | ||
790 | }; | ||
791 | |||
676 | static u32 verde_pg_init[] = | 792 | static u32 verde_pg_init[] = |
677 | { | 793 | { |
678 | 0x353c, 0xffffffff, 0x40000, | 794 | 0x353c, 0xffffffff, 0x40000, |
@@ -853,6 +969,17 @@ static void si_init_golden_registers(struct radeon_device *rdev) | |||
853 | oland_mgcg_cgcg_init, | 969 | oland_mgcg_cgcg_init, |
854 | (const u32)ARRAY_SIZE(oland_mgcg_cgcg_init)); | 970 | (const u32)ARRAY_SIZE(oland_mgcg_cgcg_init)); |
855 | break; | 971 | break; |
972 | case CHIP_HAINAN: | ||
973 | radeon_program_register_sequence(rdev, | ||
974 | hainan_golden_registers, | ||
975 | (const u32)ARRAY_SIZE(hainan_golden_registers)); | ||
976 | radeon_program_register_sequence(rdev, | ||
977 | hainan_golden_registers2, | ||
978 | (const u32)ARRAY_SIZE(hainan_golden_registers2)); | ||
979 | radeon_program_register_sequence(rdev, | ||
980 | hainan_mgcg_cgcg_init, | ||
981 | (const u32)ARRAY_SIZE(hainan_mgcg_cgcg_init)); | ||
982 | break; | ||
856 | default: | 983 | default: |
857 | break; | 984 | break; |
858 | } | 985 | } |
@@ -1062,6 +1189,45 @@ static const u32 oland_io_mc_regs[TAHITI_IO_MC_REGS_SIZE][2] = { | |||
1062 | {0x0000009f, 0x00a17730} | 1189 | {0x0000009f, 0x00a17730} |
1063 | }; | 1190 | }; |
1064 | 1191 | ||
1192 | static const u32 hainan_io_mc_regs[TAHITI_IO_MC_REGS_SIZE][2] = { | ||
1193 | {0x0000006f, 0x03044000}, | ||
1194 | {0x00000070, 0x0480c018}, | ||
1195 | {0x00000071, 0x00000040}, | ||
1196 | {0x00000072, 0x01000000}, | ||
1197 | {0x00000074, 0x000000ff}, | ||
1198 | {0x00000075, 0x00143400}, | ||
1199 | {0x00000076, 0x08ec0800}, | ||
1200 | {0x00000077, 0x040000cc}, | ||
1201 | {0x00000079, 0x00000000}, | ||
1202 | {0x0000007a, 0x21000409}, | ||
1203 | {0x0000007c, 0x00000000}, | ||
1204 | {0x0000007d, 0xe8000000}, | ||
1205 | {0x0000007e, 0x044408a8}, | ||
1206 | {0x0000007f, 0x00000003}, | ||
1207 | {0x00000080, 0x00000000}, | ||
1208 | {0x00000081, 0x01000000}, | ||
1209 | {0x00000082, 0x02000000}, | ||
1210 | {0x00000083, 0x00000000}, | ||
1211 | {0x00000084, 0xe3f3e4f4}, | ||
1212 | {0x00000085, 0x00052024}, | ||
1213 | {0x00000087, 0x00000000}, | ||
1214 | {0x00000088, 0x66036603}, | ||
1215 | {0x00000089, 0x01000000}, | ||
1216 | {0x0000008b, 0x1c0a0000}, | ||
1217 | {0x0000008c, 0xff010000}, | ||
1218 | {0x0000008e, 0xffffefff}, | ||
1219 | {0x0000008f, 0xfff3efff}, | ||
1220 | {0x00000090, 0xfff3efbf}, | ||
1221 | {0x00000094, 0x00101101}, | ||
1222 | {0x00000095, 0x00000fff}, | ||
1223 | {0x00000096, 0x00116fff}, | ||
1224 | {0x00000097, 0x60010000}, | ||
1225 | {0x00000098, 0x10010000}, | ||
1226 | {0x00000099, 0x00006000}, | ||
1227 | {0x0000009a, 0x00001000}, | ||
1228 | {0x0000009f, 0x00a07730} | ||
1229 | }; | ||
1230 | |||
1065 | /* ucode loading */ | 1231 | /* ucode loading */ |
1066 | static int si_mc_load_microcode(struct radeon_device *rdev) | 1232 | static int si_mc_load_microcode(struct radeon_device *rdev) |
1067 | { | 1233 | { |
@@ -1095,6 +1261,11 @@ static int si_mc_load_microcode(struct radeon_device *rdev) | |||
1095 | ucode_size = OLAND_MC_UCODE_SIZE; | 1261 | ucode_size = OLAND_MC_UCODE_SIZE; |
1096 | regs_size = TAHITI_IO_MC_REGS_SIZE; | 1262 | regs_size = TAHITI_IO_MC_REGS_SIZE; |
1097 | break; | 1263 | break; |
1264 | case CHIP_HAINAN: | ||
1265 | io_mc_regs = (u32 *)&hainan_io_mc_regs; | ||
1266 | ucode_size = OLAND_MC_UCODE_SIZE; | ||
1267 | regs_size = TAHITI_IO_MC_REGS_SIZE; | ||
1268 | break; | ||
1098 | } | 1269 | } |
1099 | 1270 | ||
1100 | running = RREG32(MC_SEQ_SUP_CNTL) & RUN_MASK; | 1271 | running = RREG32(MC_SEQ_SUP_CNTL) & RUN_MASK; |
@@ -1198,6 +1369,15 @@ static int si_init_microcode(struct radeon_device *rdev) | |||
1198 | rlc_req_size = SI_RLC_UCODE_SIZE * 4; | 1369 | rlc_req_size = SI_RLC_UCODE_SIZE * 4; |
1199 | mc_req_size = OLAND_MC_UCODE_SIZE * 4; | 1370 | mc_req_size = OLAND_MC_UCODE_SIZE * 4; |
1200 | break; | 1371 | break; |
1372 | case CHIP_HAINAN: | ||
1373 | chip_name = "HAINAN"; | ||
1374 | rlc_chip_name = "HAINAN"; | ||
1375 | pfp_req_size = SI_PFP_UCODE_SIZE * 4; | ||
1376 | me_req_size = SI_PM4_UCODE_SIZE * 4; | ||
1377 | ce_req_size = SI_CE_UCODE_SIZE * 4; | ||
1378 | rlc_req_size = SI_RLC_UCODE_SIZE * 4; | ||
1379 | mc_req_size = OLAND_MC_UCODE_SIZE * 4; | ||
1380 | break; | ||
1201 | default: BUG(); | 1381 | default: BUG(); |
1202 | } | 1382 | } |
1203 | 1383 | ||
@@ -2003,7 +2183,8 @@ static void si_tiling_mode_table_init(struct radeon_device *rdev) | |||
2003 | WREG32(GB_TILE_MODE0 + (reg_offset * 4), gb_tile_moden); | 2183 | WREG32(GB_TILE_MODE0 + (reg_offset * 4), gb_tile_moden); |
2004 | } | 2184 | } |
2005 | } else if ((rdev->family == CHIP_VERDE) || | 2185 | } else if ((rdev->family == CHIP_VERDE) || |
2006 | (rdev->family == CHIP_OLAND)) { | 2186 | (rdev->family == CHIP_OLAND) || |
2187 | (rdev->family == CHIP_HAINAN)) { | ||
2007 | for (reg_offset = 0; reg_offset < num_tile_mode_states; reg_offset++) { | 2188 | for (reg_offset = 0; reg_offset < num_tile_mode_states; reg_offset++) { |
2008 | switch (reg_offset) { | 2189 | switch (reg_offset) { |
2009 | case 0: /* non-AA compressed depth or any compressed stencil */ | 2190 | case 0: /* non-AA compressed depth or any compressed stencil */ |
@@ -2466,6 +2647,23 @@ static void si_gpu_init(struct radeon_device *rdev) | |||
2466 | rdev->config.si.sc_earlyz_tile_fifo_size = 0x130; | 2647 | rdev->config.si.sc_earlyz_tile_fifo_size = 0x130; |
2467 | gb_addr_config = VERDE_GB_ADDR_CONFIG_GOLDEN; | 2648 | gb_addr_config = VERDE_GB_ADDR_CONFIG_GOLDEN; |
2468 | break; | 2649 | break; |
2650 | case CHIP_HAINAN: | ||
2651 | rdev->config.si.max_shader_engines = 1; | ||
2652 | rdev->config.si.max_tile_pipes = 4; | ||
2653 | rdev->config.si.max_cu_per_sh = 5; | ||
2654 | rdev->config.si.max_sh_per_se = 1; | ||
2655 | rdev->config.si.max_backends_per_se = 1; | ||
2656 | rdev->config.si.max_texture_channel_caches = 2; | ||
2657 | rdev->config.si.max_gprs = 256; | ||
2658 | rdev->config.si.max_gs_threads = 16; | ||
2659 | rdev->config.si.max_hw_contexts = 8; | ||
2660 | |||
2661 | rdev->config.si.sc_prim_fifo_size_frontend = 0x20; | ||
2662 | rdev->config.si.sc_prim_fifo_size_backend = 0x40; | ||
2663 | rdev->config.si.sc_hiz_tile_fifo_size = 0x30; | ||
2664 | rdev->config.si.sc_earlyz_tile_fifo_size = 0x130; | ||
2665 | gb_addr_config = HAINAN_GB_ADDR_CONFIG_GOLDEN; | ||
2666 | break; | ||
2469 | } | 2667 | } |
2470 | 2668 | ||
2471 | /* Initialize HDP */ | 2669 | /* Initialize HDP */ |
@@ -2559,9 +2757,11 @@ static void si_gpu_init(struct radeon_device *rdev) | |||
2559 | WREG32(HDP_ADDR_CONFIG, gb_addr_config); | 2757 | WREG32(HDP_ADDR_CONFIG, gb_addr_config); |
2560 | WREG32(DMA_TILING_CONFIG + DMA0_REGISTER_OFFSET, gb_addr_config); | 2758 | WREG32(DMA_TILING_CONFIG + DMA0_REGISTER_OFFSET, gb_addr_config); |
2561 | WREG32(DMA_TILING_CONFIG + DMA1_REGISTER_OFFSET, gb_addr_config); | 2759 | WREG32(DMA_TILING_CONFIG + DMA1_REGISTER_OFFSET, gb_addr_config); |
2562 | WREG32(UVD_UDEC_ADDR_CONFIG, gb_addr_config); | 2760 | if (rdev->has_uvd) { |
2563 | WREG32(UVD_UDEC_DB_ADDR_CONFIG, gb_addr_config); | 2761 | WREG32(UVD_UDEC_ADDR_CONFIG, gb_addr_config); |
2564 | WREG32(UVD_UDEC_DBW_ADDR_CONFIG, gb_addr_config); | 2762 | WREG32(UVD_UDEC_DB_ADDR_CONFIG, gb_addr_config); |
2763 | WREG32(UVD_UDEC_DBW_ADDR_CONFIG, gb_addr_config); | ||
2764 | } | ||
2565 | 2765 | ||
2566 | si_tiling_mode_table_init(rdev); | 2766 | si_tiling_mode_table_init(rdev); |
2567 | 2767 | ||
@@ -3304,8 +3504,9 @@ static void si_mc_program(struct radeon_device *rdev) | |||
3304 | if (radeon_mc_wait_for_idle(rdev)) { | 3504 | if (radeon_mc_wait_for_idle(rdev)) { |
3305 | dev_warn(rdev->dev, "Wait for MC idle timedout !\n"); | 3505 | dev_warn(rdev->dev, "Wait for MC idle timedout !\n"); |
3306 | } | 3506 | } |
3307 | /* Lockout access through VGA aperture*/ | 3507 | if (!ASIC_IS_NODCE(rdev)) |
3308 | WREG32(VGA_HDP_CONTROL, VGA_MEMORY_DISABLE); | 3508 | /* Lockout access through VGA aperture*/ |
3509 | WREG32(VGA_HDP_CONTROL, VGA_MEMORY_DISABLE); | ||
3309 | /* Update configuration */ | 3510 | /* Update configuration */ |
3310 | WREG32(MC_VM_SYSTEM_APERTURE_LOW_ADDR, | 3511 | WREG32(MC_VM_SYSTEM_APERTURE_LOW_ADDR, |
3311 | rdev->mc.vram_start >> 12); | 3512 | rdev->mc.vram_start >> 12); |
@@ -3327,9 +3528,11 @@ static void si_mc_program(struct radeon_device *rdev) | |||
3327 | dev_warn(rdev->dev, "Wait for MC idle timedout !\n"); | 3528 | dev_warn(rdev->dev, "Wait for MC idle timedout !\n"); |
3328 | } | 3529 | } |
3329 | evergreen_mc_resume(rdev, &save); | 3530 | evergreen_mc_resume(rdev, &save); |
3330 | /* we need to own VRAM, so turn off the VGA renderer here | 3531 | if (!ASIC_IS_NODCE(rdev)) { |
3331 | * to stop it overwriting our objects */ | 3532 | /* we need to own VRAM, so turn off the VGA renderer here |
3332 | rv515_vga_render_disable(rdev); | 3533 | * to stop it overwriting our objects */ |
3534 | rv515_vga_render_disable(rdev); | ||
3535 | } | ||
3333 | } | 3536 | } |
3334 | 3537 | ||
3335 | static void si_vram_gtt_location(struct radeon_device *rdev, | 3538 | static void si_vram_gtt_location(struct radeon_device *rdev, |
@@ -3397,8 +3600,8 @@ static int si_mc_init(struct radeon_device *rdev) | |||
3397 | rdev->mc.aper_base = pci_resource_start(rdev->pdev, 0); | 3600 | rdev->mc.aper_base = pci_resource_start(rdev->pdev, 0); |
3398 | rdev->mc.aper_size = pci_resource_len(rdev->pdev, 0); | 3601 | rdev->mc.aper_size = pci_resource_len(rdev->pdev, 0); |
3399 | /* size in MB on si */ | 3602 | /* size in MB on si */ |
3400 | rdev->mc.mc_vram_size = RREG32(CONFIG_MEMSIZE) * 1024 * 1024; | 3603 | rdev->mc.mc_vram_size = RREG32(CONFIG_MEMSIZE) * 1024ULL * 1024ULL; |
3401 | rdev->mc.real_vram_size = RREG32(CONFIG_MEMSIZE) * 1024 * 1024; | 3604 | rdev->mc.real_vram_size = RREG32(CONFIG_MEMSIZE) * 1024ULL * 1024ULL; |
3402 | rdev->mc.visible_vram_size = rdev->mc.aper_size; | 3605 | rdev->mc.visible_vram_size = rdev->mc.aper_size; |
3403 | si_vram_gtt_location(rdev, &rdev->mc); | 3606 | si_vram_gtt_location(rdev, &rdev->mc); |
3404 | radeon_update_bandwidth_info(rdev); | 3607 | radeon_update_bandwidth_info(rdev); |
@@ -4251,8 +4454,10 @@ static void si_disable_interrupt_state(struct radeon_device *rdev) | |||
4251 | tmp = RREG32(DMA_CNTL + DMA1_REGISTER_OFFSET) & ~TRAP_ENABLE; | 4454 | tmp = RREG32(DMA_CNTL + DMA1_REGISTER_OFFSET) & ~TRAP_ENABLE; |
4252 | WREG32(DMA_CNTL + DMA1_REGISTER_OFFSET, tmp); | 4455 | WREG32(DMA_CNTL + DMA1_REGISTER_OFFSET, tmp); |
4253 | WREG32(GRBM_INT_CNTL, 0); | 4456 | WREG32(GRBM_INT_CNTL, 0); |
4254 | WREG32(INT_MASK + EVERGREEN_CRTC0_REGISTER_OFFSET, 0); | 4457 | if (rdev->num_crtc >= 2) { |
4255 | WREG32(INT_MASK + EVERGREEN_CRTC1_REGISTER_OFFSET, 0); | 4458 | WREG32(INT_MASK + EVERGREEN_CRTC0_REGISTER_OFFSET, 0); |
4459 | WREG32(INT_MASK + EVERGREEN_CRTC1_REGISTER_OFFSET, 0); | ||
4460 | } | ||
4256 | if (rdev->num_crtc >= 4) { | 4461 | if (rdev->num_crtc >= 4) { |
4257 | WREG32(INT_MASK + EVERGREEN_CRTC2_REGISTER_OFFSET, 0); | 4462 | WREG32(INT_MASK + EVERGREEN_CRTC2_REGISTER_OFFSET, 0); |
4258 | WREG32(INT_MASK + EVERGREEN_CRTC3_REGISTER_OFFSET, 0); | 4463 | WREG32(INT_MASK + EVERGREEN_CRTC3_REGISTER_OFFSET, 0); |
@@ -4262,8 +4467,10 @@ static void si_disable_interrupt_state(struct radeon_device *rdev) | |||
4262 | WREG32(INT_MASK + EVERGREEN_CRTC5_REGISTER_OFFSET, 0); | 4467 | WREG32(INT_MASK + EVERGREEN_CRTC5_REGISTER_OFFSET, 0); |
4263 | } | 4468 | } |
4264 | 4469 | ||
4265 | WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET, 0); | 4470 | if (rdev->num_crtc >= 2) { |
4266 | WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET, 0); | 4471 | WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET, 0); |
4472 | WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET, 0); | ||
4473 | } | ||
4267 | if (rdev->num_crtc >= 4) { | 4474 | if (rdev->num_crtc >= 4) { |
4268 | WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET, 0); | 4475 | WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET, 0); |
4269 | WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET, 0); | 4476 | WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET, 0); |
@@ -4273,21 +4480,22 @@ static void si_disable_interrupt_state(struct radeon_device *rdev) | |||
4273 | WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET, 0); | 4480 | WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET, 0); |
4274 | } | 4481 | } |
4275 | 4482 | ||
4276 | WREG32(DACA_AUTODETECT_INT_CONTROL, 0); | 4483 | if (!ASIC_IS_NODCE(rdev)) { |
4277 | 4484 | WREG32(DACA_AUTODETECT_INT_CONTROL, 0); | |
4278 | tmp = RREG32(DC_HPD1_INT_CONTROL) & DC_HPDx_INT_POLARITY; | ||
4279 | WREG32(DC_HPD1_INT_CONTROL, tmp); | ||
4280 | tmp = RREG32(DC_HPD2_INT_CONTROL) & DC_HPDx_INT_POLARITY; | ||
4281 | WREG32(DC_HPD2_INT_CONTROL, tmp); | ||
4282 | tmp = RREG32(DC_HPD3_INT_CONTROL) & DC_HPDx_INT_POLARITY; | ||
4283 | WREG32(DC_HPD3_INT_CONTROL, tmp); | ||
4284 | tmp = RREG32(DC_HPD4_INT_CONTROL) & DC_HPDx_INT_POLARITY; | ||
4285 | WREG32(DC_HPD4_INT_CONTROL, tmp); | ||
4286 | tmp = RREG32(DC_HPD5_INT_CONTROL) & DC_HPDx_INT_POLARITY; | ||
4287 | WREG32(DC_HPD5_INT_CONTROL, tmp); | ||
4288 | tmp = RREG32(DC_HPD6_INT_CONTROL) & DC_HPDx_INT_POLARITY; | ||
4289 | WREG32(DC_HPD6_INT_CONTROL, tmp); | ||
4290 | 4485 | ||
4486 | tmp = RREG32(DC_HPD1_INT_CONTROL) & DC_HPDx_INT_POLARITY; | ||
4487 | WREG32(DC_HPD1_INT_CONTROL, tmp); | ||
4488 | tmp = RREG32(DC_HPD2_INT_CONTROL) & DC_HPDx_INT_POLARITY; | ||
4489 | WREG32(DC_HPD2_INT_CONTROL, tmp); | ||
4490 | tmp = RREG32(DC_HPD3_INT_CONTROL) & DC_HPDx_INT_POLARITY; | ||
4491 | WREG32(DC_HPD3_INT_CONTROL, tmp); | ||
4492 | tmp = RREG32(DC_HPD4_INT_CONTROL) & DC_HPDx_INT_POLARITY; | ||
4493 | WREG32(DC_HPD4_INT_CONTROL, tmp); | ||
4494 | tmp = RREG32(DC_HPD5_INT_CONTROL) & DC_HPDx_INT_POLARITY; | ||
4495 | WREG32(DC_HPD5_INT_CONTROL, tmp); | ||
4496 | tmp = RREG32(DC_HPD6_INT_CONTROL) & DC_HPDx_INT_POLARITY; | ||
4497 | WREG32(DC_HPD6_INT_CONTROL, tmp); | ||
4498 | } | ||
4291 | } | 4499 | } |
4292 | 4500 | ||
4293 | static int si_irq_init(struct radeon_device *rdev) | 4501 | static int si_irq_init(struct radeon_device *rdev) |
@@ -4366,7 +4574,7 @@ int si_irq_set(struct radeon_device *rdev) | |||
4366 | u32 cp_int_cntl = CNTX_BUSY_INT_ENABLE | CNTX_EMPTY_INT_ENABLE; | 4574 | u32 cp_int_cntl = CNTX_BUSY_INT_ENABLE | CNTX_EMPTY_INT_ENABLE; |
4367 | u32 cp_int_cntl1 = 0, cp_int_cntl2 = 0; | 4575 | u32 cp_int_cntl1 = 0, cp_int_cntl2 = 0; |
4368 | u32 crtc1 = 0, crtc2 = 0, crtc3 = 0, crtc4 = 0, crtc5 = 0, crtc6 = 0; | 4576 | u32 crtc1 = 0, crtc2 = 0, crtc3 = 0, crtc4 = 0, crtc5 = 0, crtc6 = 0; |
4369 | u32 hpd1, hpd2, hpd3, hpd4, hpd5, hpd6; | 4577 | u32 hpd1 = 0, hpd2 = 0, hpd3 = 0, hpd4 = 0, hpd5 = 0, hpd6 = 0; |
4370 | u32 grbm_int_cntl = 0; | 4578 | u32 grbm_int_cntl = 0; |
4371 | u32 grph1 = 0, grph2 = 0, grph3 = 0, grph4 = 0, grph5 = 0, grph6 = 0; | 4579 | u32 grph1 = 0, grph2 = 0, grph3 = 0, grph4 = 0, grph5 = 0, grph6 = 0; |
4372 | u32 dma_cntl, dma_cntl1; | 4580 | u32 dma_cntl, dma_cntl1; |
@@ -4383,12 +4591,14 @@ int si_irq_set(struct radeon_device *rdev) | |||
4383 | return 0; | 4591 | return 0; |
4384 | } | 4592 | } |
4385 | 4593 | ||
4386 | hpd1 = RREG32(DC_HPD1_INT_CONTROL) & ~DC_HPDx_INT_EN; | 4594 | if (!ASIC_IS_NODCE(rdev)) { |
4387 | hpd2 = RREG32(DC_HPD2_INT_CONTROL) & ~DC_HPDx_INT_EN; | 4595 | hpd1 = RREG32(DC_HPD1_INT_CONTROL) & ~DC_HPDx_INT_EN; |
4388 | hpd3 = RREG32(DC_HPD3_INT_CONTROL) & ~DC_HPDx_INT_EN; | 4596 | hpd2 = RREG32(DC_HPD2_INT_CONTROL) & ~DC_HPDx_INT_EN; |
4389 | hpd4 = RREG32(DC_HPD4_INT_CONTROL) & ~DC_HPDx_INT_EN; | 4597 | hpd3 = RREG32(DC_HPD3_INT_CONTROL) & ~DC_HPDx_INT_EN; |
4390 | hpd5 = RREG32(DC_HPD5_INT_CONTROL) & ~DC_HPDx_INT_EN; | 4598 | hpd4 = RREG32(DC_HPD4_INT_CONTROL) & ~DC_HPDx_INT_EN; |
4391 | hpd6 = RREG32(DC_HPD6_INT_CONTROL) & ~DC_HPDx_INT_EN; | 4599 | hpd5 = RREG32(DC_HPD5_INT_CONTROL) & ~DC_HPDx_INT_EN; |
4600 | hpd6 = RREG32(DC_HPD6_INT_CONTROL) & ~DC_HPDx_INT_EN; | ||
4601 | } | ||
4392 | 4602 | ||
4393 | dma_cntl = RREG32(DMA_CNTL + DMA0_REGISTER_OFFSET) & ~TRAP_ENABLE; | 4603 | dma_cntl = RREG32(DMA_CNTL + DMA0_REGISTER_OFFSET) & ~TRAP_ENABLE; |
4394 | dma_cntl1 = RREG32(DMA_CNTL + DMA1_REGISTER_OFFSET) & ~TRAP_ENABLE; | 4604 | dma_cntl1 = RREG32(DMA_CNTL + DMA1_REGISTER_OFFSET) & ~TRAP_ENABLE; |
@@ -4479,8 +4689,10 @@ int si_irq_set(struct radeon_device *rdev) | |||
4479 | 4689 | ||
4480 | WREG32(GRBM_INT_CNTL, grbm_int_cntl); | 4690 | WREG32(GRBM_INT_CNTL, grbm_int_cntl); |
4481 | 4691 | ||
4482 | WREG32(INT_MASK + EVERGREEN_CRTC0_REGISTER_OFFSET, crtc1); | 4692 | if (rdev->num_crtc >= 2) { |
4483 | WREG32(INT_MASK + EVERGREEN_CRTC1_REGISTER_OFFSET, crtc2); | 4693 | WREG32(INT_MASK + EVERGREEN_CRTC0_REGISTER_OFFSET, crtc1); |
4694 | WREG32(INT_MASK + EVERGREEN_CRTC1_REGISTER_OFFSET, crtc2); | ||
4695 | } | ||
4484 | if (rdev->num_crtc >= 4) { | 4696 | if (rdev->num_crtc >= 4) { |
4485 | WREG32(INT_MASK + EVERGREEN_CRTC2_REGISTER_OFFSET, crtc3); | 4697 | WREG32(INT_MASK + EVERGREEN_CRTC2_REGISTER_OFFSET, crtc3); |
4486 | WREG32(INT_MASK + EVERGREEN_CRTC3_REGISTER_OFFSET, crtc4); | 4698 | WREG32(INT_MASK + EVERGREEN_CRTC3_REGISTER_OFFSET, crtc4); |
@@ -4490,8 +4702,10 @@ int si_irq_set(struct radeon_device *rdev) | |||
4490 | WREG32(INT_MASK + EVERGREEN_CRTC5_REGISTER_OFFSET, crtc6); | 4702 | WREG32(INT_MASK + EVERGREEN_CRTC5_REGISTER_OFFSET, crtc6); |
4491 | } | 4703 | } |
4492 | 4704 | ||
4493 | WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET, grph1); | 4705 | if (rdev->num_crtc >= 2) { |
4494 | WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET, grph2); | 4706 | WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET, grph1); |
4707 | WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET, grph2); | ||
4708 | } | ||
4495 | if (rdev->num_crtc >= 4) { | 4709 | if (rdev->num_crtc >= 4) { |
4496 | WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET, grph3); | 4710 | WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET, grph3); |
4497 | WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET, grph4); | 4711 | WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET, grph4); |
@@ -4501,12 +4715,14 @@ int si_irq_set(struct radeon_device *rdev) | |||
4501 | WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET, grph6); | 4715 | WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET, grph6); |
4502 | } | 4716 | } |
4503 | 4717 | ||
4504 | WREG32(DC_HPD1_INT_CONTROL, hpd1); | 4718 | if (!ASIC_IS_NODCE(rdev)) { |
4505 | WREG32(DC_HPD2_INT_CONTROL, hpd2); | 4719 | WREG32(DC_HPD1_INT_CONTROL, hpd1); |
4506 | WREG32(DC_HPD3_INT_CONTROL, hpd3); | 4720 | WREG32(DC_HPD2_INT_CONTROL, hpd2); |
4507 | WREG32(DC_HPD4_INT_CONTROL, hpd4); | 4721 | WREG32(DC_HPD3_INT_CONTROL, hpd3); |
4508 | WREG32(DC_HPD5_INT_CONTROL, hpd5); | 4722 | WREG32(DC_HPD4_INT_CONTROL, hpd4); |
4509 | WREG32(DC_HPD6_INT_CONTROL, hpd6); | 4723 | WREG32(DC_HPD5_INT_CONTROL, hpd5); |
4724 | WREG32(DC_HPD6_INT_CONTROL, hpd6); | ||
4725 | } | ||
4510 | 4726 | ||
4511 | return 0; | 4727 | return 0; |
4512 | } | 4728 | } |
@@ -4515,6 +4731,9 @@ static inline void si_irq_ack(struct radeon_device *rdev) | |||
4515 | { | 4731 | { |
4516 | u32 tmp; | 4732 | u32 tmp; |
4517 | 4733 | ||
4734 | if (ASIC_IS_NODCE(rdev)) | ||
4735 | return; | ||
4736 | |||
4518 | rdev->irq.stat_regs.evergreen.disp_int = RREG32(DISP_INTERRUPT_STATUS); | 4737 | rdev->irq.stat_regs.evergreen.disp_int = RREG32(DISP_INTERRUPT_STATUS); |
4519 | rdev->irq.stat_regs.evergreen.disp_int_cont = RREG32(DISP_INTERRUPT_STATUS_CONTINUE); | 4738 | rdev->irq.stat_regs.evergreen.disp_int_cont = RREG32(DISP_INTERRUPT_STATUS_CONTINUE); |
4520 | rdev->irq.stat_regs.evergreen.disp_int_cont2 = RREG32(DISP_INTERRUPT_STATUS_CONTINUE2); | 4739 | rdev->irq.stat_regs.evergreen.disp_int_cont2 = RREG32(DISP_INTERRUPT_STATUS_CONTINUE2); |
@@ -5118,15 +5337,17 @@ static int si_startup(struct radeon_device *rdev) | |||
5118 | return r; | 5337 | return r; |
5119 | } | 5338 | } |
5120 | 5339 | ||
5121 | r = rv770_uvd_resume(rdev); | 5340 | if (rdev->has_uvd) { |
5122 | if (!r) { | 5341 | r = rv770_uvd_resume(rdev); |
5123 | r = radeon_fence_driver_start_ring(rdev, | 5342 | if (!r) { |
5124 | R600_RING_TYPE_UVD_INDEX); | 5343 | r = radeon_fence_driver_start_ring(rdev, |
5344 | R600_RING_TYPE_UVD_INDEX); | ||
5345 | if (r) | ||
5346 | dev_err(rdev->dev, "UVD fences init error (%d).\n", r); | ||
5347 | } | ||
5125 | if (r) | 5348 | if (r) |
5126 | dev_err(rdev->dev, "UVD fences init error (%d).\n", r); | 5349 | rdev->ring[R600_RING_TYPE_UVD_INDEX].ring_size = 0; |
5127 | } | 5350 | } |
5128 | if (r) | ||
5129 | rdev->ring[R600_RING_TYPE_UVD_INDEX].ring_size = 0; | ||
5130 | 5351 | ||
5131 | /* Enable IRQ */ | 5352 | /* Enable IRQ */ |
5132 | r = si_irq_init(rdev); | 5353 | r = si_irq_init(rdev); |
@@ -5185,16 +5406,18 @@ static int si_startup(struct radeon_device *rdev) | |||
5185 | if (r) | 5406 | if (r) |
5186 | return r; | 5407 | return r; |
5187 | 5408 | ||
5188 | ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX]; | 5409 | if (rdev->has_uvd) { |
5189 | if (ring->ring_size) { | 5410 | ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX]; |
5190 | r = radeon_ring_init(rdev, ring, ring->ring_size, | 5411 | if (ring->ring_size) { |
5191 | R600_WB_UVD_RPTR_OFFSET, | 5412 | r = radeon_ring_init(rdev, ring, ring->ring_size, |
5192 | UVD_RBC_RB_RPTR, UVD_RBC_RB_WPTR, | 5413 | R600_WB_UVD_RPTR_OFFSET, |
5193 | 0, 0xfffff, RADEON_CP_PACKET2); | 5414 | UVD_RBC_RB_RPTR, UVD_RBC_RB_WPTR, |
5194 | if (!r) | 5415 | 0, 0xfffff, RADEON_CP_PACKET2); |
5195 | r = r600_uvd_init(rdev); | 5416 | if (!r) |
5196 | if (r) | 5417 | r = r600_uvd_init(rdev); |
5197 | DRM_ERROR("radeon: failed initializing UVD (%d).\n", r); | 5418 | if (r) |
5419 | DRM_ERROR("radeon: failed initializing UVD (%d).\n", r); | ||
5420 | } | ||
5198 | } | 5421 | } |
5199 | 5422 | ||
5200 | r = radeon_ib_pool_init(rdev); | 5423 | r = radeon_ib_pool_init(rdev); |
@@ -5243,8 +5466,10 @@ int si_suspend(struct radeon_device *rdev) | |||
5243 | radeon_vm_manager_fini(rdev); | 5466 | radeon_vm_manager_fini(rdev); |
5244 | si_cp_enable(rdev, false); | 5467 | si_cp_enable(rdev, false); |
5245 | cayman_dma_stop(rdev); | 5468 | cayman_dma_stop(rdev); |
5246 | r600_uvd_rbc_stop(rdev); | 5469 | if (rdev->has_uvd) { |
5247 | radeon_uvd_suspend(rdev); | 5470 | r600_uvd_rbc_stop(rdev); |
5471 | radeon_uvd_suspend(rdev); | ||
5472 | } | ||
5248 | si_irq_suspend(rdev); | 5473 | si_irq_suspend(rdev); |
5249 | radeon_wb_disable(rdev); | 5474 | radeon_wb_disable(rdev); |
5250 | si_pcie_gart_disable(rdev); | 5475 | si_pcie_gart_disable(rdev); |
@@ -5332,11 +5557,13 @@ int si_init(struct radeon_device *rdev) | |||
5332 | ring->ring_obj = NULL; | 5557 | ring->ring_obj = NULL; |
5333 | r600_ring_init(rdev, ring, 64 * 1024); | 5558 | r600_ring_init(rdev, ring, 64 * 1024); |
5334 | 5559 | ||
5335 | r = radeon_uvd_init(rdev); | 5560 | if (rdev->has_uvd) { |
5336 | if (!r) { | 5561 | r = radeon_uvd_init(rdev); |
5337 | ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX]; | 5562 | if (!r) { |
5338 | ring->ring_obj = NULL; | 5563 | ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX]; |
5339 | r600_ring_init(rdev, ring, 4096); | 5564 | ring->ring_obj = NULL; |
5565 | r600_ring_init(rdev, ring, 4096); | ||
5566 | } | ||
5340 | } | 5567 | } |
5341 | 5568 | ||
5342 | rdev->ih.ring_obj = NULL; | 5569 | rdev->ih.ring_obj = NULL; |
@@ -5384,7 +5611,8 @@ void si_fini(struct radeon_device *rdev) | |||
5384 | radeon_vm_manager_fini(rdev); | 5611 | radeon_vm_manager_fini(rdev); |
5385 | radeon_ib_pool_fini(rdev); | 5612 | radeon_ib_pool_fini(rdev); |
5386 | radeon_irq_kms_fini(rdev); | 5613 | radeon_irq_kms_fini(rdev); |
5387 | radeon_uvd_fini(rdev); | 5614 | if (rdev->has_uvd) |
5615 | radeon_uvd_fini(rdev); | ||
5388 | si_pcie_gart_fini(rdev); | 5616 | si_pcie_gart_fini(rdev); |
5389 | r600_vram_scratch_fini(rdev); | 5617 | r600_vram_scratch_fini(rdev); |
5390 | radeon_gem_fini(rdev); | 5618 | radeon_gem_fini(rdev); |
diff --git a/drivers/gpu/drm/radeon/sid.h b/drivers/gpu/drm/radeon/sid.h index 222877ba6cf5..8f2d7d4f9b28 100644 --- a/drivers/gpu/drm/radeon/sid.h +++ b/drivers/gpu/drm/radeon/sid.h | |||
@@ -28,6 +28,7 @@ | |||
28 | 28 | ||
29 | #define TAHITI_GB_ADDR_CONFIG_GOLDEN 0x12011003 | 29 | #define TAHITI_GB_ADDR_CONFIG_GOLDEN 0x12011003 |
30 | #define VERDE_GB_ADDR_CONFIG_GOLDEN 0x12010002 | 30 | #define VERDE_GB_ADDR_CONFIG_GOLDEN 0x12010002 |
31 | #define HAINAN_GB_ADDR_CONFIG_GOLDEN 0x02010001 | ||
31 | 32 | ||
32 | /* discrete uvd clocks */ | 33 | /* discrete uvd clocks */ |
33 | #define CG_UPLL_FUNC_CNTL 0x634 | 34 | #define CG_UPLL_FUNC_CNTL 0x634 |
diff --git a/drivers/gpu/host1x/drm/dc.c b/drivers/gpu/host1x/drm/dc.c index 1e2060324f02..8c04943f82e3 100644 --- a/drivers/gpu/host1x/drm/dc.c +++ b/drivers/gpu/host1x/drm/dc.c | |||
@@ -1128,11 +1128,6 @@ static int tegra_dc_probe(struct platform_device *pdev) | |||
1128 | return err; | 1128 | return err; |
1129 | 1129 | ||
1130 | regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 1130 | regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
1131 | if (!regs) { | ||
1132 | dev_err(&pdev->dev, "failed to get registers\n"); | ||
1133 | return -ENXIO; | ||
1134 | } | ||
1135 | |||
1136 | dc->regs = devm_ioremap_resource(&pdev->dev, regs); | 1131 | dc->regs = devm_ioremap_resource(&pdev->dev, regs); |
1137 | if (IS_ERR(dc->regs)) | 1132 | if (IS_ERR(dc->regs)) |
1138 | return PTR_ERR(dc->regs); | 1133 | return PTR_ERR(dc->regs); |