diff options
Diffstat (limited to 'drivers/gpu')
69 files changed, 452 insertions, 194 deletions
diff --git a/drivers/gpu/drm/armada/armada_drm.h b/drivers/gpu/drm/armada/armada_drm.h index eef09ec9a5ff..a72cae03b99b 100644 --- a/drivers/gpu/drm/armada/armada_drm.h +++ b/drivers/gpu/drm/armada/armada_drm.h | |||
@@ -103,6 +103,7 @@ void armada_drm_queue_unref_work(struct drm_device *, | |||
103 | extern const struct drm_mode_config_funcs armada_drm_mode_config_funcs; | 103 | extern const struct drm_mode_config_funcs armada_drm_mode_config_funcs; |
104 | 104 | ||
105 | int armada_fbdev_init(struct drm_device *); | 105 | int armada_fbdev_init(struct drm_device *); |
106 | void armada_fbdev_lastclose(struct drm_device *); | ||
106 | void armada_fbdev_fini(struct drm_device *); | 107 | void armada_fbdev_fini(struct drm_device *); |
107 | 108 | ||
108 | int armada_overlay_plane_create(struct drm_device *, unsigned long); | 109 | int armada_overlay_plane_create(struct drm_device *, unsigned long); |
diff --git a/drivers/gpu/drm/armada/armada_drv.c b/drivers/gpu/drm/armada/armada_drv.c index 4f2b28354915..62d0ff3efddf 100644 --- a/drivers/gpu/drm/armada/armada_drv.c +++ b/drivers/gpu/drm/armada/armada_drv.c | |||
@@ -321,6 +321,11 @@ static struct drm_ioctl_desc armada_ioctls[] = { | |||
321 | DRM_UNLOCKED), | 321 | DRM_UNLOCKED), |
322 | }; | 322 | }; |
323 | 323 | ||
324 | static void armada_drm_lastclose(struct drm_device *dev) | ||
325 | { | ||
326 | armada_fbdev_lastclose(dev); | ||
327 | } | ||
328 | |||
324 | static const struct file_operations armada_drm_fops = { | 329 | static const struct file_operations armada_drm_fops = { |
325 | .owner = THIS_MODULE, | 330 | .owner = THIS_MODULE, |
326 | .llseek = no_llseek, | 331 | .llseek = no_llseek, |
@@ -337,7 +342,7 @@ static struct drm_driver armada_drm_driver = { | |||
337 | .open = NULL, | 342 | .open = NULL, |
338 | .preclose = NULL, | 343 | .preclose = NULL, |
339 | .postclose = NULL, | 344 | .postclose = NULL, |
340 | .lastclose = NULL, | 345 | .lastclose = armada_drm_lastclose, |
341 | .unload = armada_drm_unload, | 346 | .unload = armada_drm_unload, |
342 | .get_vblank_counter = drm_vblank_count, | 347 | .get_vblank_counter = drm_vblank_count, |
343 | .enable_vblank = armada_drm_enable_vblank, | 348 | .enable_vblank = armada_drm_enable_vblank, |
diff --git a/drivers/gpu/drm/armada/armada_fbdev.c b/drivers/gpu/drm/armada/armada_fbdev.c index dd5ea77dac96..948cb14c561e 100644 --- a/drivers/gpu/drm/armada/armada_fbdev.c +++ b/drivers/gpu/drm/armada/armada_fbdev.c | |||
@@ -105,9 +105,9 @@ static int armada_fb_create(struct drm_fb_helper *fbh, | |||
105 | drm_fb_helper_fill_fix(info, dfb->fb.pitches[0], dfb->fb.depth); | 105 | drm_fb_helper_fill_fix(info, dfb->fb.pitches[0], dfb->fb.depth); |
106 | drm_fb_helper_fill_var(info, fbh, sizes->fb_width, sizes->fb_height); | 106 | drm_fb_helper_fill_var(info, fbh, sizes->fb_width, sizes->fb_height); |
107 | 107 | ||
108 | DRM_DEBUG_KMS("allocated %dx%d %dbpp fb: 0x%08x\n", | 108 | DRM_DEBUG_KMS("allocated %dx%d %dbpp fb: 0x%08llx\n", |
109 | dfb->fb.width, dfb->fb.height, | 109 | dfb->fb.width, dfb->fb.height, dfb->fb.bits_per_pixel, |
110 | dfb->fb.bits_per_pixel, obj->phys_addr); | 110 | (unsigned long long)obj->phys_addr); |
111 | 111 | ||
112 | return 0; | 112 | return 0; |
113 | 113 | ||
@@ -177,6 +177,16 @@ int armada_fbdev_init(struct drm_device *dev) | |||
177 | return ret; | 177 | return ret; |
178 | } | 178 | } |
179 | 179 | ||
180 | void armada_fbdev_lastclose(struct drm_device *dev) | ||
181 | { | ||
182 | struct armada_private *priv = dev->dev_private; | ||
183 | |||
184 | drm_modeset_lock_all(dev); | ||
185 | if (priv->fbdev) | ||
186 | drm_fb_helper_restore_fbdev_mode(priv->fbdev); | ||
187 | drm_modeset_unlock_all(dev); | ||
188 | } | ||
189 | |||
180 | void armada_fbdev_fini(struct drm_device *dev) | 190 | void armada_fbdev_fini(struct drm_device *dev) |
181 | { | 191 | { |
182 | struct armada_private *priv = dev->dev_private; | 192 | struct armada_private *priv = dev->dev_private; |
@@ -192,11 +202,11 @@ void armada_fbdev_fini(struct drm_device *dev) | |||
192 | framebuffer_release(info); | 202 | framebuffer_release(info); |
193 | } | 203 | } |
194 | 204 | ||
205 | drm_fb_helper_fini(fbh); | ||
206 | |||
195 | if (fbh->fb) | 207 | if (fbh->fb) |
196 | fbh->fb->funcs->destroy(fbh->fb); | 208 | fbh->fb->funcs->destroy(fbh->fb); |
197 | 209 | ||
198 | drm_fb_helper_fini(fbh); | ||
199 | |||
200 | priv->fbdev = NULL; | 210 | priv->fbdev = NULL; |
201 | } | 211 | } |
202 | } | 212 | } |
diff --git a/drivers/gpu/drm/armada/armada_gem.c b/drivers/gpu/drm/armada/armada_gem.c index 9f2356bae7fd..887816f43476 100644 --- a/drivers/gpu/drm/armada/armada_gem.c +++ b/drivers/gpu/drm/armada/armada_gem.c | |||
@@ -172,8 +172,9 @@ armada_gem_linear_back(struct drm_device *dev, struct armada_gem_object *obj) | |||
172 | obj->dev_addr = obj->linear->start; | 172 | obj->dev_addr = obj->linear->start; |
173 | } | 173 | } |
174 | 174 | ||
175 | DRM_DEBUG_DRIVER("obj %p phys %#x dev %#x\n", | 175 | DRM_DEBUG_DRIVER("obj %p phys %#llx dev %#llx\n", obj, |
176 | obj, obj->phys_addr, obj->dev_addr); | 176 | (unsigned long long)obj->phys_addr, |
177 | (unsigned long long)obj->dev_addr); | ||
177 | 178 | ||
178 | return 0; | 179 | return 0; |
179 | } | 180 | } |
@@ -557,7 +558,6 @@ armada_gem_prime_import(struct drm_device *dev, struct dma_buf *buf) | |||
557 | * refcount on the gem object itself. | 558 | * refcount on the gem object itself. |
558 | */ | 559 | */ |
559 | drm_gem_object_reference(obj); | 560 | drm_gem_object_reference(obj); |
560 | dma_buf_put(buf); | ||
561 | return obj; | 561 | return obj; |
562 | } | 562 | } |
563 | } | 563 | } |
@@ -573,6 +573,7 @@ armada_gem_prime_import(struct drm_device *dev, struct dma_buf *buf) | |||
573 | } | 573 | } |
574 | 574 | ||
575 | dobj->obj.import_attach = attach; | 575 | dobj->obj.import_attach = attach; |
576 | get_dma_buf(buf); | ||
576 | 577 | ||
577 | /* | 578 | /* |
578 | * Don't call dma_buf_map_attachment() here - it maps the | 579 | * Don't call dma_buf_map_attachment() here - it maps the |
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index 0a1e4a5f4234..8835dcddfac3 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c | |||
@@ -68,6 +68,8 @@ | |||
68 | #define EDID_QUIRK_DETAILED_SYNC_PP (1 << 6) | 68 | #define EDID_QUIRK_DETAILED_SYNC_PP (1 << 6) |
69 | /* Force reduced-blanking timings for detailed modes */ | 69 | /* Force reduced-blanking timings for detailed modes */ |
70 | #define EDID_QUIRK_FORCE_REDUCED_BLANKING (1 << 7) | 70 | #define EDID_QUIRK_FORCE_REDUCED_BLANKING (1 << 7) |
71 | /* Force 8bpc */ | ||
72 | #define EDID_QUIRK_FORCE_8BPC (1 << 8) | ||
71 | 73 | ||
72 | struct detailed_mode_closure { | 74 | struct detailed_mode_closure { |
73 | struct drm_connector *connector; | 75 | struct drm_connector *connector; |
@@ -128,6 +130,9 @@ static struct edid_quirk { | |||
128 | 130 | ||
129 | /* Medion MD 30217 PG */ | 131 | /* Medion MD 30217 PG */ |
130 | { "MED", 0x7b8, EDID_QUIRK_PREFER_LARGE_75 }, | 132 | { "MED", 0x7b8, EDID_QUIRK_PREFER_LARGE_75 }, |
133 | |||
134 | /* Panel in Samsung NP700G7A-S01PL notebook reports 6bpc */ | ||
135 | { "SEC", 0xd033, EDID_QUIRK_FORCE_8BPC }, | ||
131 | }; | 136 | }; |
132 | 137 | ||
133 | /* | 138 | /* |
@@ -3435,6 +3440,9 @@ int drm_add_edid_modes(struct drm_connector *connector, struct edid *edid) | |||
3435 | 3440 | ||
3436 | drm_add_display_info(edid, &connector->display_info); | 3441 | drm_add_display_info(edid, &connector->display_info); |
3437 | 3442 | ||
3443 | if (quirks & EDID_QUIRK_FORCE_8BPC) | ||
3444 | connector->display_info.bpc = 8; | ||
3445 | |||
3438 | return num_modes; | 3446 | return num_modes; |
3439 | } | 3447 | } |
3440 | EXPORT_SYMBOL(drm_add_edid_modes); | 3448 | EXPORT_SYMBOL(drm_add_edid_modes); |
diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c index 85071a1c4547..b0733153dfd2 100644 --- a/drivers/gpu/drm/drm_modes.c +++ b/drivers/gpu/drm/drm_modes.c | |||
@@ -1041,7 +1041,7 @@ void drm_mode_connector_list_update(struct drm_connector *connector) | |||
1041 | /* if equal delete the probed mode */ | 1041 | /* if equal delete the probed mode */ |
1042 | mode->status = pmode->status; | 1042 | mode->status = pmode->status; |
1043 | /* Merge type bits together */ | 1043 | /* Merge type bits together */ |
1044 | mode->type = pmode->type; | 1044 | mode->type |= pmode->type; |
1045 | list_del(&pmode->head); | 1045 | list_del(&pmode->head); |
1046 | drm_mode_destroy(connector->dev, pmode); | 1046 | drm_mode_destroy(connector->dev, pmode); |
1047 | break; | 1047 | break; |
diff --git a/drivers/gpu/drm/drm_stub.c b/drivers/gpu/drm/drm_stub.c index f53d5246979c..66dd3a001cf1 100644 --- a/drivers/gpu/drm/drm_stub.c +++ b/drivers/gpu/drm/drm_stub.c | |||
@@ -566,11 +566,11 @@ err_unload: | |||
566 | if (dev->driver->unload) | 566 | if (dev->driver->unload) |
567 | dev->driver->unload(dev); | 567 | dev->driver->unload(dev); |
568 | err_primary_node: | 568 | err_primary_node: |
569 | drm_put_minor(dev->primary); | 569 | drm_unplug_minor(dev->primary); |
570 | err_render_node: | 570 | err_render_node: |
571 | drm_put_minor(dev->render); | 571 | drm_unplug_minor(dev->render); |
572 | err_control_node: | 572 | err_control_node: |
573 | drm_put_minor(dev->control); | 573 | drm_unplug_minor(dev->control); |
574 | err_agp: | 574 | err_agp: |
575 | if (dev->driver->bus->agp_destroy) | 575 | if (dev->driver->bus->agp_destroy) |
576 | dev->driver->bus->agp_destroy(dev); | 576 | dev->driver->bus->agp_destroy(dev); |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_crtc.c b/drivers/gpu/drm/exynos/exynos_drm_crtc.c index ebc01503d50e..6f3400f3978a 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_crtc.c +++ b/drivers/gpu/drm/exynos/exynos_drm_crtc.c | |||
@@ -36,9 +36,9 @@ enum exynos_crtc_mode { | |||
36 | * @pipe: a crtc index created at load() with a new crtc object creation | 36 | * @pipe: a crtc index created at load() with a new crtc object creation |
37 | * and the crtc object would be set to private->crtc array | 37 | * and the crtc object would be set to private->crtc array |
38 | * to get a crtc object corresponding to this pipe from private->crtc | 38 | * to get a crtc object corresponding to this pipe from private->crtc |
39 | * array when irq interrupt occured. the reason of using this pipe is that | 39 | * array when irq interrupt occurred. the reason of using this pipe is that |
40 | * drm framework doesn't support multiple irq yet. | 40 | * drm framework doesn't support multiple irq yet. |
41 | * we can refer to the crtc to current hardware interrupt occured through | 41 | * we can refer to the crtc to current hardware interrupt occurred through |
42 | * this pipe value. | 42 | * this pipe value. |
43 | * @dpms: store the crtc dpms value | 43 | * @dpms: store the crtc dpms value |
44 | * @mode: store the crtc mode value | 44 | * @mode: store the crtc mode value |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimc.c b/drivers/gpu/drm/exynos/exynos_drm_fimc.c index 8adfc8f1e08f..30d76b2ff9c2 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fimc.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fimc.c | |||
@@ -345,7 +345,7 @@ static bool fimc_check_ovf(struct fimc_context *ctx) | |||
345 | 345 | ||
346 | fimc_write(cfg, EXYNOS_CIWDOFST); | 346 | fimc_write(cfg, EXYNOS_CIWDOFST); |
347 | 347 | ||
348 | dev_err(ippdrv->dev, "occured overflow at %d, status 0x%x.\n", | 348 | dev_err(ippdrv->dev, "occurred overflow at %d, status 0x%x.\n", |
349 | ctx->id, status); | 349 | ctx->id, status); |
350 | return true; | 350 | return true; |
351 | } | 351 | } |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_g2d.c b/drivers/gpu/drm/exynos/exynos_drm_g2d.c index 7bccedca487a..380aec28840b 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_g2d.c +++ b/drivers/gpu/drm/exynos/exynos_drm_g2d.c | |||
@@ -1126,7 +1126,7 @@ int exynos_g2d_set_cmdlist_ioctl(struct drm_device *drm_dev, void *data, | |||
1126 | * G2D interrupt event once current command list execution is | 1126 | * G2D interrupt event once current command list execution is |
1127 | * finished. | 1127 | * finished. |
1128 | * Otherwise only ACF bit should be set to INTEN register so | 1128 | * Otherwise only ACF bit should be set to INTEN register so |
1129 | * that one interrupt is occured after all command lists | 1129 | * that one interrupt is occurred after all command lists |
1130 | * have been completed. | 1130 | * have been completed. |
1131 | */ | 1131 | */ |
1132 | if (node->event) { | 1132 | if (node->event) { |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.c b/drivers/gpu/drm/exynos/exynos_drm_gem.c index 1ade191d84f4..be59d50d8b16 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_gem.c +++ b/drivers/gpu/drm/exynos/exynos_drm_gem.c | |||
@@ -652,7 +652,7 @@ int exynos_drm_gem_dumb_create(struct drm_file *file_priv, | |||
652 | int ret; | 652 | int ret; |
653 | 653 | ||
654 | /* | 654 | /* |
655 | * alocate memory to be used for framebuffer. | 655 | * allocate memory to be used for framebuffer. |
656 | * - this callback would be called by user application | 656 | * - this callback would be called by user application |
657 | * with DRM_IOCTL_MODE_CREATE_DUMB command. | 657 | * with DRM_IOCTL_MODE_CREATE_DUMB command. |
658 | */ | 658 | */ |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.h b/drivers/gpu/drm/exynos/exynos_drm_gem.h index 702ec3abe85c..b8c818ba2ff4 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_gem.h +++ b/drivers/gpu/drm/exynos/exynos_drm_gem.h | |||
@@ -60,7 +60,7 @@ struct exynos_drm_gem_buf { | |||
60 | * @vma: a pointer to vm_area. | 60 | * @vma: a pointer to vm_area. |
61 | * @flags: indicate memory type to allocated buffer and cache attruibute. | 61 | * @flags: indicate memory type to allocated buffer and cache attruibute. |
62 | * | 62 | * |
63 | * P.S. this object would be transfered to user as kms_bo.handle so | 63 | * P.S. this object would be transferred to user as kms_bo.handle so |
64 | * user can access the buffer through kms_bo.handle. | 64 | * user can access the buffer through kms_bo.handle. |
65 | */ | 65 | */ |
66 | struct exynos_drm_gem_obj { | 66 | struct exynos_drm_gem_obj { |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_gsc.c b/drivers/gpu/drm/exynos/exynos_drm_gsc.c index cd6aebd53bd0..fa75059a6104 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_gsc.c +++ b/drivers/gpu/drm/exynos/exynos_drm_gsc.c | |||
@@ -1301,13 +1301,13 @@ static irqreturn_t gsc_irq_handler(int irq, void *dev_id) | |||
1301 | 1301 | ||
1302 | status = gsc_read(GSC_IRQ); | 1302 | status = gsc_read(GSC_IRQ); |
1303 | if (status & GSC_IRQ_STATUS_OR_IRQ) { | 1303 | if (status & GSC_IRQ_STATUS_OR_IRQ) { |
1304 | dev_err(ippdrv->dev, "occured overflow at %d, status 0x%x.\n", | 1304 | dev_err(ippdrv->dev, "occurred overflow at %d, status 0x%x.\n", |
1305 | ctx->id, status); | 1305 | ctx->id, status); |
1306 | return IRQ_NONE; | 1306 | return IRQ_NONE; |
1307 | } | 1307 | } |
1308 | 1308 | ||
1309 | if (status & GSC_IRQ_STATUS_OR_FRM_DONE) { | 1309 | if (status & GSC_IRQ_STATUS_OR_FRM_DONE) { |
1310 | dev_dbg(ippdrv->dev, "occured frame done at %d, status 0x%x.\n", | 1310 | dev_dbg(ippdrv->dev, "occurred frame done at %d, status 0x%x.\n", |
1311 | ctx->id, status); | 1311 | ctx->id, status); |
1312 | 1312 | ||
1313 | buf_id[EXYNOS_DRM_OPS_SRC] = gsc_get_src_buf_index(ctx); | 1313 | buf_id[EXYNOS_DRM_OPS_SRC] = gsc_get_src_buf_index(ctx); |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_ipp.c b/drivers/gpu/drm/exynos/exynos_drm_ipp.c index 824e0705c8d3..d519a4e5fe40 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_ipp.c +++ b/drivers/gpu/drm/exynos/exynos_drm_ipp.c | |||
@@ -335,7 +335,7 @@ int exynos_drm_ipp_get_property(struct drm_device *drm_dev, void *data, | |||
335 | } else { | 335 | } else { |
336 | /* | 336 | /* |
337 | * Getting ippdrv capability by ipp_id. | 337 | * Getting ippdrv capability by ipp_id. |
338 | * some deivce not supported wb, output interface. | 338 | * some device not supported wb, output interface. |
339 | * so, user application detect correct ipp driver | 339 | * so, user application detect correct ipp driver |
340 | * using this ioctl. | 340 | * using this ioctl. |
341 | */ | 341 | */ |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_ipp.h b/drivers/gpu/drm/exynos/exynos_drm_ipp.h index 4cadbea7dbde..ab1634befc05 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_ipp.h +++ b/drivers/gpu/drm/exynos/exynos_drm_ipp.h | |||
@@ -48,7 +48,7 @@ struct drm_exynos_ipp_cmd_work { | |||
48 | /* | 48 | /* |
49 | * A structure of command node. | 49 | * A structure of command node. |
50 | * | 50 | * |
51 | * @priv: IPP private infomation. | 51 | * @priv: IPP private information. |
52 | * @list: list head to command queue information. | 52 | * @list: list head to command queue information. |
53 | * @event_list: list head of event. | 53 | * @event_list: list head of event. |
54 | * @mem_list: list head to source,destination memory queue information. | 54 | * @mem_list: list head to source,destination memory queue information. |
@@ -92,7 +92,7 @@ struct drm_exynos_ipp_buf_info { | |||
92 | }; | 92 | }; |
93 | 93 | ||
94 | /* | 94 | /* |
95 | * A structure of wb setting infomation. | 95 | * A structure of wb setting information. |
96 | * | 96 | * |
97 | * @enable: enable flag for wb. | 97 | * @enable: enable flag for wb. |
98 | * @refresh: HZ of the refresh rate. | 98 | * @refresh: HZ of the refresh rate. |
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 0cab2d045135..5c648425c1e0 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c | |||
@@ -83,6 +83,14 @@ void i915_update_dri1_breadcrumb(struct drm_device *dev) | |||
83 | drm_i915_private_t *dev_priv = dev->dev_private; | 83 | drm_i915_private_t *dev_priv = dev->dev_private; |
84 | struct drm_i915_master_private *master_priv; | 84 | struct drm_i915_master_private *master_priv; |
85 | 85 | ||
86 | /* | ||
87 | * The dri breadcrumb update races against the drm master disappearing. | ||
88 | * Instead of trying to fix this (this is by far not the only ums issue) | ||
89 | * just don't do the update in kms mode. | ||
90 | */ | ||
91 | if (drm_core_check_feature(dev, DRIVER_MODESET)) | ||
92 | return; | ||
93 | |||
86 | if (dev->primary->master) { | 94 | if (dev->primary->master) { |
87 | master_priv = dev->primary->master->driver_priv; | 95 | master_priv = dev->primary->master->driver_priv; |
88 | if (master_priv->sarea_priv) | 96 | if (master_priv->sarea_priv) |
@@ -1490,16 +1498,9 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) | |||
1490 | spin_lock_init(&dev_priv->uncore.lock); | 1498 | spin_lock_init(&dev_priv->uncore.lock); |
1491 | spin_lock_init(&dev_priv->mm.object_stat_lock); | 1499 | spin_lock_init(&dev_priv->mm.object_stat_lock); |
1492 | mutex_init(&dev_priv->dpio_lock); | 1500 | mutex_init(&dev_priv->dpio_lock); |
1493 | mutex_init(&dev_priv->rps.hw_lock); | ||
1494 | mutex_init(&dev_priv->modeset_restore_lock); | 1501 | mutex_init(&dev_priv->modeset_restore_lock); |
1495 | 1502 | ||
1496 | mutex_init(&dev_priv->pc8.lock); | 1503 | intel_pm_setup(dev); |
1497 | dev_priv->pc8.requirements_met = false; | ||
1498 | dev_priv->pc8.gpu_idle = false; | ||
1499 | dev_priv->pc8.irqs_disabled = false; | ||
1500 | dev_priv->pc8.enabled = false; | ||
1501 | dev_priv->pc8.disable_count = 2; /* requirements_met + gpu_idle */ | ||
1502 | INIT_DELAYED_WORK(&dev_priv->pc8.enable_work, hsw_enable_pc8_work); | ||
1503 | 1504 | ||
1504 | intel_display_crc_init(dev); | 1505 | intel_display_crc_init(dev); |
1505 | 1506 | ||
@@ -1603,7 +1604,6 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) | |||
1603 | } | 1604 | } |
1604 | 1605 | ||
1605 | intel_irq_init(dev); | 1606 | intel_irq_init(dev); |
1606 | intel_pm_init(dev); | ||
1607 | intel_uncore_sanitize(dev); | 1607 | intel_uncore_sanitize(dev); |
1608 | 1608 | ||
1609 | /* Try to make sure MCHBAR is enabled before poking at it */ | 1609 | /* Try to make sure MCHBAR is enabled before poking at it */ |
@@ -1848,8 +1848,10 @@ void i915_driver_lastclose(struct drm_device * dev) | |||
1848 | 1848 | ||
1849 | void i915_driver_preclose(struct drm_device * dev, struct drm_file *file_priv) | 1849 | void i915_driver_preclose(struct drm_device * dev, struct drm_file *file_priv) |
1850 | { | 1850 | { |
1851 | mutex_lock(&dev->struct_mutex); | ||
1851 | i915_gem_context_close(dev, file_priv); | 1852 | i915_gem_context_close(dev, file_priv); |
1852 | i915_gem_release(dev, file_priv); | 1853 | i915_gem_release(dev, file_priv); |
1854 | mutex_unlock(&dev->struct_mutex); | ||
1853 | } | 1855 | } |
1854 | 1856 | ||
1855 | void i915_driver_postclose(struct drm_device *dev, struct drm_file *file) | 1857 | void i915_driver_postclose(struct drm_device *dev, struct drm_file *file) |
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 2e367a1c6a64..5b7b7e06cb3a 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c | |||
@@ -651,6 +651,7 @@ static int __i915_drm_thaw(struct drm_device *dev, bool restore_gtt_mappings) | |||
651 | intel_modeset_init_hw(dev); | 651 | intel_modeset_init_hw(dev); |
652 | 652 | ||
653 | drm_modeset_lock_all(dev); | 653 | drm_modeset_lock_all(dev); |
654 | drm_mode_config_reset(dev); | ||
654 | intel_modeset_setup_hw_state(dev, true); | 655 | intel_modeset_setup_hw_state(dev, true); |
655 | drm_modeset_unlock_all(dev); | 656 | drm_modeset_unlock_all(dev); |
656 | 657 | ||
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index ccdbecca070d..90fcccba17b0 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h | |||
@@ -1755,8 +1755,13 @@ struct drm_i915_file_private { | |||
1755 | #define IS_MOBILE(dev) (INTEL_INFO(dev)->is_mobile) | 1755 | #define IS_MOBILE(dev) (INTEL_INFO(dev)->is_mobile) |
1756 | #define IS_HSW_EARLY_SDV(dev) (IS_HASWELL(dev) && \ | 1756 | #define IS_HSW_EARLY_SDV(dev) (IS_HASWELL(dev) && \ |
1757 | ((dev)->pdev->device & 0xFF00) == 0x0C00) | 1757 | ((dev)->pdev->device & 0xFF00) == 0x0C00) |
1758 | #define IS_ULT(dev) (IS_HASWELL(dev) && \ | 1758 | #define IS_BDW_ULT(dev) (IS_BROADWELL(dev) && \ |
1759 | (((dev)->pdev->device & 0xf) == 0x2 || \ | ||
1760 | ((dev)->pdev->device & 0xf) == 0x6 || \ | ||
1761 | ((dev)->pdev->device & 0xf) == 0xe)) | ||
1762 | #define IS_HSW_ULT(dev) (IS_HASWELL(dev) && \ | ||
1759 | ((dev)->pdev->device & 0xFF00) == 0x0A00) | 1763 | ((dev)->pdev->device & 0xFF00) == 0x0A00) |
1764 | #define IS_ULT(dev) (IS_HSW_ULT(dev) || IS_BDW_ULT(dev)) | ||
1760 | #define IS_HSW_GT3(dev) (IS_HASWELL(dev) && \ | 1765 | #define IS_HSW_GT3(dev) (IS_HASWELL(dev) && \ |
1761 | ((dev)->pdev->device & 0x00F0) == 0x0020) | 1766 | ((dev)->pdev->device & 0x00F0) == 0x0020) |
1762 | #define IS_PRELIMINARY_HW(intel_info) ((intel_info)->is_preliminary) | 1767 | #define IS_PRELIMINARY_HW(intel_info) ((intel_info)->is_preliminary) |
@@ -1901,9 +1906,7 @@ void i915_queue_hangcheck(struct drm_device *dev); | |||
1901 | void i915_handle_error(struct drm_device *dev, bool wedged); | 1906 | void i915_handle_error(struct drm_device *dev, bool wedged); |
1902 | 1907 | ||
1903 | extern void intel_irq_init(struct drm_device *dev); | 1908 | extern void intel_irq_init(struct drm_device *dev); |
1904 | extern void intel_pm_init(struct drm_device *dev); | ||
1905 | extern void intel_hpd_init(struct drm_device *dev); | 1909 | extern void intel_hpd_init(struct drm_device *dev); |
1906 | extern void intel_pm_init(struct drm_device *dev); | ||
1907 | 1910 | ||
1908 | extern void intel_uncore_sanitize(struct drm_device *dev); | 1911 | extern void intel_uncore_sanitize(struct drm_device *dev); |
1909 | extern void intel_uncore_early_sanitize(struct drm_device *dev); | 1912 | extern void intel_uncore_early_sanitize(struct drm_device *dev); |
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 621c7c67a643..76d3d1ab73c6 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c | |||
@@ -2343,15 +2343,24 @@ static void i915_gem_free_request(struct drm_i915_gem_request *request) | |||
2343 | kfree(request); | 2343 | kfree(request); |
2344 | } | 2344 | } |
2345 | 2345 | ||
2346 | static void i915_gem_reset_ring_lists(struct drm_i915_private *dev_priv, | 2346 | static void i915_gem_reset_ring_status(struct drm_i915_private *dev_priv, |
2347 | struct intel_ring_buffer *ring) | 2347 | struct intel_ring_buffer *ring) |
2348 | { | 2348 | { |
2349 | u32 completed_seqno; | 2349 | u32 completed_seqno = ring->get_seqno(ring, false); |
2350 | u32 acthd; | 2350 | u32 acthd = intel_ring_get_active_head(ring); |
2351 | struct drm_i915_gem_request *request; | ||
2352 | |||
2353 | list_for_each_entry(request, &ring->request_list, list) { | ||
2354 | if (i915_seqno_passed(completed_seqno, request->seqno)) | ||
2355 | continue; | ||
2351 | 2356 | ||
2352 | acthd = intel_ring_get_active_head(ring); | 2357 | i915_set_reset_status(ring, request, acthd); |
2353 | completed_seqno = ring->get_seqno(ring, false); | 2358 | } |
2359 | } | ||
2354 | 2360 | ||
2361 | static void i915_gem_reset_ring_cleanup(struct drm_i915_private *dev_priv, | ||
2362 | struct intel_ring_buffer *ring) | ||
2363 | { | ||
2355 | while (!list_empty(&ring->request_list)) { | 2364 | while (!list_empty(&ring->request_list)) { |
2356 | struct drm_i915_gem_request *request; | 2365 | struct drm_i915_gem_request *request; |
2357 | 2366 | ||
@@ -2359,9 +2368,6 @@ static void i915_gem_reset_ring_lists(struct drm_i915_private *dev_priv, | |||
2359 | struct drm_i915_gem_request, | 2368 | struct drm_i915_gem_request, |
2360 | list); | 2369 | list); |
2361 | 2370 | ||
2362 | if (request->seqno > completed_seqno) | ||
2363 | i915_set_reset_status(ring, request, acthd); | ||
2364 | |||
2365 | i915_gem_free_request(request); | 2371 | i915_gem_free_request(request); |
2366 | } | 2372 | } |
2367 | 2373 | ||
@@ -2403,8 +2409,16 @@ void i915_gem_reset(struct drm_device *dev) | |||
2403 | struct intel_ring_buffer *ring; | 2409 | struct intel_ring_buffer *ring; |
2404 | int i; | 2410 | int i; |
2405 | 2411 | ||
2412 | /* | ||
2413 | * Before we free the objects from the requests, we need to inspect | ||
2414 | * them for finding the guilty party. As the requests only borrow | ||
2415 | * their reference to the objects, the inspection must be done first. | ||
2416 | */ | ||
2417 | for_each_ring(ring, dev_priv, i) | ||
2418 | i915_gem_reset_ring_status(dev_priv, ring); | ||
2419 | |||
2406 | for_each_ring(ring, dev_priv, i) | 2420 | for_each_ring(ring, dev_priv, i) |
2407 | i915_gem_reset_ring_lists(dev_priv, ring); | 2421 | i915_gem_reset_ring_cleanup(dev_priv, ring); |
2408 | 2422 | ||
2409 | i915_gem_cleanup_ringbuffer(dev); | 2423 | i915_gem_cleanup_ringbuffer(dev); |
2410 | 2424 | ||
diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c index 72a3df32292f..b0f42b9ca037 100644 --- a/drivers/gpu/drm/i915/i915_gem_context.c +++ b/drivers/gpu/drm/i915/i915_gem_context.c | |||
@@ -347,10 +347,8 @@ void i915_gem_context_close(struct drm_device *dev, struct drm_file *file) | |||
347 | { | 347 | { |
348 | struct drm_i915_file_private *file_priv = file->driver_priv; | 348 | struct drm_i915_file_private *file_priv = file->driver_priv; |
349 | 349 | ||
350 | mutex_lock(&dev->struct_mutex); | ||
351 | idr_for_each(&file_priv->context_idr, context_idr_cleanup, NULL); | 350 | idr_for_each(&file_priv->context_idr, context_idr_cleanup, NULL); |
352 | idr_destroy(&file_priv->context_idr); | 351 | idr_destroy(&file_priv->context_idr); |
353 | mutex_unlock(&dev->struct_mutex); | ||
354 | } | 352 | } |
355 | 353 | ||
356 | static struct i915_hw_context * | 354 | static struct i915_hw_context * |
@@ -423,11 +421,21 @@ static int do_switch(struct i915_hw_context *to) | |||
423 | if (ret) | 421 | if (ret) |
424 | return ret; | 422 | return ret; |
425 | 423 | ||
426 | /* Clear this page out of any CPU caches for coherent swap-in/out. Note | 424 | /* |
425 | * Pin can switch back to the default context if we end up calling into | ||
426 | * evict_everything - as a last ditch gtt defrag effort that also | ||
427 | * switches to the default context. Hence we need to reload from here. | ||
428 | */ | ||
429 | from = ring->last_context; | ||
430 | |||
431 | /* | ||
432 | * Clear this page out of any CPU caches for coherent swap-in/out. Note | ||
427 | * that thanks to write = false in this call and us not setting any gpu | 433 | * that thanks to write = false in this call and us not setting any gpu |
428 | * write domains when putting a context object onto the active list | 434 | * write domains when putting a context object onto the active list |
429 | * (when switching away from it), this won't block. | 435 | * (when switching away from it), this won't block. |
430 | * XXX: We need a real interface to do this instead of trickery. */ | 436 | * |
437 | * XXX: We need a real interface to do this instead of trickery. | ||
438 | */ | ||
431 | ret = i915_gem_object_set_to_gtt_domain(to->obj, false); | 439 | ret = i915_gem_object_set_to_gtt_domain(to->obj, false); |
432 | if (ret) { | 440 | if (ret) { |
433 | i915_gem_object_unpin(to->obj); | 441 | i915_gem_object_unpin(to->obj); |
diff --git a/drivers/gpu/drm/i915/i915_gem_evict.c b/drivers/gpu/drm/i915/i915_gem_evict.c index b7376533633d..8f3adc7d0dc8 100644 --- a/drivers/gpu/drm/i915/i915_gem_evict.c +++ b/drivers/gpu/drm/i915/i915_gem_evict.c | |||
@@ -88,6 +88,7 @@ i915_gem_evict_something(struct drm_device *dev, struct i915_address_space *vm, | |||
88 | } else | 88 | } else |
89 | drm_mm_init_scan(&vm->mm, min_size, alignment, cache_level); | 89 | drm_mm_init_scan(&vm->mm, min_size, alignment, cache_level); |
90 | 90 | ||
91 | search_again: | ||
91 | /* First see if there is a large enough contiguous idle region... */ | 92 | /* First see if there is a large enough contiguous idle region... */ |
92 | list_for_each_entry(vma, &vm->inactive_list, mm_list) { | 93 | list_for_each_entry(vma, &vm->inactive_list, mm_list) { |
93 | if (mark_free(vma, &unwind_list)) | 94 | if (mark_free(vma, &unwind_list)) |
@@ -115,10 +116,17 @@ none: | |||
115 | list_del_init(&vma->exec_list); | 116 | list_del_init(&vma->exec_list); |
116 | } | 117 | } |
117 | 118 | ||
118 | /* We expect the caller to unpin, evict all and try again, or give up. | 119 | /* Can we unpin some objects such as idle hw contents, |
119 | * So calling i915_gem_evict_vm() is unnecessary. | 120 | * or pending flips? |
120 | */ | 121 | */ |
121 | return -ENOSPC; | 122 | ret = nonblocking ? -ENOSPC : i915_gpu_idle(dev); |
123 | if (ret) | ||
124 | return ret; | ||
125 | |||
126 | /* Only idle the GPU and repeat the search once */ | ||
127 | i915_gem_retire_requests(dev); | ||
128 | nonblocking = true; | ||
129 | goto search_again; | ||
122 | 130 | ||
123 | found: | 131 | found: |
124 | /* drm_mm doesn't allow any other other operations while | 132 | /* drm_mm doesn't allow any other other operations while |
diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c index b7e787fb4649..a3ba9a8cd687 100644 --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c | |||
@@ -93,7 +93,7 @@ eb_lookup_vmas(struct eb_vmas *eb, | |||
93 | { | 93 | { |
94 | struct drm_i915_gem_object *obj; | 94 | struct drm_i915_gem_object *obj; |
95 | struct list_head objects; | 95 | struct list_head objects; |
96 | int i, ret = 0; | 96 | int i, ret; |
97 | 97 | ||
98 | INIT_LIST_HEAD(&objects); | 98 | INIT_LIST_HEAD(&objects); |
99 | spin_lock(&file->table_lock); | 99 | spin_lock(&file->table_lock); |
@@ -106,7 +106,7 @@ eb_lookup_vmas(struct eb_vmas *eb, | |||
106 | DRM_DEBUG("Invalid object handle %d at index %d\n", | 106 | DRM_DEBUG("Invalid object handle %d at index %d\n", |
107 | exec[i].handle, i); | 107 | exec[i].handle, i); |
108 | ret = -ENOENT; | 108 | ret = -ENOENT; |
109 | goto out; | 109 | goto err; |
110 | } | 110 | } |
111 | 111 | ||
112 | if (!list_empty(&obj->obj_exec_link)) { | 112 | if (!list_empty(&obj->obj_exec_link)) { |
@@ -114,7 +114,7 @@ eb_lookup_vmas(struct eb_vmas *eb, | |||
114 | DRM_DEBUG("Object %p [handle %d, index %d] appears more than once in object list\n", | 114 | DRM_DEBUG("Object %p [handle %d, index %d] appears more than once in object list\n", |
115 | obj, exec[i].handle, i); | 115 | obj, exec[i].handle, i); |
116 | ret = -EINVAL; | 116 | ret = -EINVAL; |
117 | goto out; | 117 | goto err; |
118 | } | 118 | } |
119 | 119 | ||
120 | drm_gem_object_reference(&obj->base); | 120 | drm_gem_object_reference(&obj->base); |
@@ -123,9 +123,13 @@ eb_lookup_vmas(struct eb_vmas *eb, | |||
123 | spin_unlock(&file->table_lock); | 123 | spin_unlock(&file->table_lock); |
124 | 124 | ||
125 | i = 0; | 125 | i = 0; |
126 | list_for_each_entry(obj, &objects, obj_exec_link) { | 126 | while (!list_empty(&objects)) { |
127 | struct i915_vma *vma; | 127 | struct i915_vma *vma; |
128 | 128 | ||
129 | obj = list_first_entry(&objects, | ||
130 | struct drm_i915_gem_object, | ||
131 | obj_exec_link); | ||
132 | |||
129 | /* | 133 | /* |
130 | * NOTE: We can leak any vmas created here when something fails | 134 | * NOTE: We can leak any vmas created here when something fails |
131 | * later on. But that's no issue since vma_unbind can deal with | 135 | * later on. But that's no issue since vma_unbind can deal with |
@@ -138,10 +142,12 @@ eb_lookup_vmas(struct eb_vmas *eb, | |||
138 | if (IS_ERR(vma)) { | 142 | if (IS_ERR(vma)) { |
139 | DRM_DEBUG("Failed to lookup VMA\n"); | 143 | DRM_DEBUG("Failed to lookup VMA\n"); |
140 | ret = PTR_ERR(vma); | 144 | ret = PTR_ERR(vma); |
141 | goto out; | 145 | goto err; |
142 | } | 146 | } |
143 | 147 | ||
148 | /* Transfer ownership from the objects list to the vmas list. */ | ||
144 | list_add_tail(&vma->exec_list, &eb->vmas); | 149 | list_add_tail(&vma->exec_list, &eb->vmas); |
150 | list_del_init(&obj->obj_exec_link); | ||
145 | 151 | ||
146 | vma->exec_entry = &exec[i]; | 152 | vma->exec_entry = &exec[i]; |
147 | if (eb->and < 0) { | 153 | if (eb->and < 0) { |
@@ -155,16 +161,22 @@ eb_lookup_vmas(struct eb_vmas *eb, | |||
155 | ++i; | 161 | ++i; |
156 | } | 162 | } |
157 | 163 | ||
164 | return 0; | ||
165 | |||
158 | 166 | ||
159 | out: | 167 | err: |
160 | while (!list_empty(&objects)) { | 168 | while (!list_empty(&objects)) { |
161 | obj = list_first_entry(&objects, | 169 | obj = list_first_entry(&objects, |
162 | struct drm_i915_gem_object, | 170 | struct drm_i915_gem_object, |
163 | obj_exec_link); | 171 | obj_exec_link); |
164 | list_del_init(&obj->obj_exec_link); | 172 | list_del_init(&obj->obj_exec_link); |
165 | if (ret) | 173 | drm_gem_object_unreference(&obj->base); |
166 | drm_gem_object_unreference(&obj->base); | ||
167 | } | 174 | } |
175 | /* | ||
176 | * Objects already transfered to the vmas list will be unreferenced by | ||
177 | * eb_destroy. | ||
178 | */ | ||
179 | |||
168 | return ret; | 180 | return ret; |
169 | } | 181 | } |
170 | 182 | ||
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index 38cb8d44a013..3540569948db 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c | |||
@@ -337,8 +337,8 @@ static void gen8_ppgtt_cleanup(struct i915_address_space *vm) | |||
337 | kfree(ppgtt->gen8_pt_dma_addr[i]); | 337 | kfree(ppgtt->gen8_pt_dma_addr[i]); |
338 | } | 338 | } |
339 | 339 | ||
340 | __free_pages(ppgtt->gen8_pt_pages, ppgtt->num_pt_pages << PAGE_SHIFT); | 340 | __free_pages(ppgtt->gen8_pt_pages, get_order(ppgtt->num_pt_pages << PAGE_SHIFT)); |
341 | __free_pages(ppgtt->pd_pages, ppgtt->num_pd_pages << PAGE_SHIFT); | 341 | __free_pages(ppgtt->pd_pages, get_order(ppgtt->num_pd_pages << PAGE_SHIFT)); |
342 | } | 342 | } |
343 | 343 | ||
344 | /** | 344 | /** |
@@ -906,14 +906,12 @@ static void gen8_ggtt_insert_entries(struct i915_address_space *vm, | |||
906 | WARN_ON(readq(>t_entries[i-1]) | 906 | WARN_ON(readq(>t_entries[i-1]) |
907 | != gen8_pte_encode(addr, level, true)); | 907 | != gen8_pte_encode(addr, level, true)); |
908 | 908 | ||
909 | #if 0 /* TODO: Still needed on GEN8? */ | ||
910 | /* This next bit makes the above posting read even more important. We | 909 | /* This next bit makes the above posting read even more important. We |
911 | * want to flush the TLBs only after we're certain all the PTE updates | 910 | * want to flush the TLBs only after we're certain all the PTE updates |
912 | * have finished. | 911 | * have finished. |
913 | */ | 912 | */ |
914 | I915_WRITE(GFX_FLSH_CNTL_GEN6, GFX_FLSH_CNTL_EN); | 913 | I915_WRITE(GFX_FLSH_CNTL_GEN6, GFX_FLSH_CNTL_EN); |
915 | POSTING_READ(GFX_FLSH_CNTL_GEN6); | 914 | POSTING_READ(GFX_FLSH_CNTL_GEN6); |
916 | #endif | ||
917 | } | 915 | } |
918 | 916 | ||
919 | /* | 917 | /* |
@@ -1241,6 +1239,11 @@ static inline unsigned int gen8_get_total_gtt_size(u16 bdw_gmch_ctl) | |||
1241 | bdw_gmch_ctl &= BDW_GMCH_GGMS_MASK; | 1239 | bdw_gmch_ctl &= BDW_GMCH_GGMS_MASK; |
1242 | if (bdw_gmch_ctl) | 1240 | if (bdw_gmch_ctl) |
1243 | bdw_gmch_ctl = 1 << bdw_gmch_ctl; | 1241 | bdw_gmch_ctl = 1 << bdw_gmch_ctl; |
1242 | if (bdw_gmch_ctl > 4) { | ||
1243 | WARN_ON(!i915_preliminary_hw_support); | ||
1244 | return 4<<20; | ||
1245 | } | ||
1246 | |||
1244 | return bdw_gmch_ctl << 20; | 1247 | return bdw_gmch_ctl << 20; |
1245 | } | 1248 | } |
1246 | 1249 | ||
@@ -1262,14 +1265,14 @@ static int ggtt_probe_common(struct drm_device *dev, | |||
1262 | size_t gtt_size) | 1265 | size_t gtt_size) |
1263 | { | 1266 | { |
1264 | struct drm_i915_private *dev_priv = dev->dev_private; | 1267 | struct drm_i915_private *dev_priv = dev->dev_private; |
1265 | phys_addr_t gtt_bus_addr; | 1268 | phys_addr_t gtt_phys_addr; |
1266 | int ret; | 1269 | int ret; |
1267 | 1270 | ||
1268 | /* For Modern GENs the PTEs and register space are split in the BAR */ | 1271 | /* For Modern GENs the PTEs and register space are split in the BAR */ |
1269 | gtt_bus_addr = pci_resource_start(dev->pdev, 0) + | 1272 | gtt_phys_addr = pci_resource_start(dev->pdev, 0) + |
1270 | (pci_resource_len(dev->pdev, 0) / 2); | 1273 | (pci_resource_len(dev->pdev, 0) / 2); |
1271 | 1274 | ||
1272 | dev_priv->gtt.gsm = ioremap_wc(gtt_bus_addr, gtt_size); | 1275 | dev_priv->gtt.gsm = ioremap_wc(gtt_phys_addr, gtt_size); |
1273 | if (!dev_priv->gtt.gsm) { | 1276 | if (!dev_priv->gtt.gsm) { |
1274 | DRM_ERROR("Failed to map the gtt page table\n"); | 1277 | DRM_ERROR("Failed to map the gtt page table\n"); |
1275 | return -ENOMEM; | 1278 | return -ENOMEM; |
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 5d1dedc02f15..f13d5edc39d5 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c | |||
@@ -2713,6 +2713,8 @@ static void gen8_irq_preinstall(struct drm_device *dev) | |||
2713 | #undef GEN8_IRQ_INIT_NDX | 2713 | #undef GEN8_IRQ_INIT_NDX |
2714 | 2714 | ||
2715 | POSTING_READ(GEN8_PCU_IIR); | 2715 | POSTING_READ(GEN8_PCU_IIR); |
2716 | |||
2717 | ibx_irq_preinstall(dev); | ||
2716 | } | 2718 | } |
2717 | 2719 | ||
2718 | static void ibx_hpd_irq_setup(struct drm_device *dev) | 2720 | static void ibx_hpd_irq_setup(struct drm_device *dev) |
diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index 526c8ded16b0..b69dc3e66c16 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c | |||
@@ -1057,12 +1057,18 @@ void intel_ddi_setup_hw_pll_state(struct drm_device *dev) | |||
1057 | enum pipe pipe; | 1057 | enum pipe pipe; |
1058 | struct intel_crtc *intel_crtc; | 1058 | struct intel_crtc *intel_crtc; |
1059 | 1059 | ||
1060 | dev_priv->ddi_plls.spll_refcount = 0; | ||
1061 | dev_priv->ddi_plls.wrpll1_refcount = 0; | ||
1062 | dev_priv->ddi_plls.wrpll2_refcount = 0; | ||
1063 | |||
1060 | for_each_pipe(pipe) { | 1064 | for_each_pipe(pipe) { |
1061 | intel_crtc = | 1065 | intel_crtc = |
1062 | to_intel_crtc(dev_priv->pipe_to_crtc_mapping[pipe]); | 1066 | to_intel_crtc(dev_priv->pipe_to_crtc_mapping[pipe]); |
1063 | 1067 | ||
1064 | if (!intel_crtc->active) | 1068 | if (!intel_crtc->active) { |
1069 | intel_crtc->ddi_pll_sel = PORT_CLK_SEL_NONE; | ||
1065 | continue; | 1070 | continue; |
1071 | } | ||
1066 | 1072 | ||
1067 | intel_crtc->ddi_pll_sel = intel_ddi_get_crtc_pll(dev_priv, | 1073 | intel_crtc->ddi_pll_sel = intel_ddi_get_crtc_pll(dev_priv, |
1068 | pipe); | 1074 | pipe); |
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 080f6fd4e839..2bde35d34eb9 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
@@ -6303,7 +6303,7 @@ static void assert_can_disable_lcpll(struct drm_i915_private *dev_priv) | |||
6303 | uint32_t val; | 6303 | uint32_t val; |
6304 | 6304 | ||
6305 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, base.head) | 6305 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, base.head) |
6306 | WARN(crtc->base.enabled, "CRTC for pipe %c enabled\n", | 6306 | WARN(crtc->active, "CRTC for pipe %c enabled\n", |
6307 | pipe_name(crtc->pipe)); | 6307 | pipe_name(crtc->pipe)); |
6308 | 6308 | ||
6309 | WARN(I915_READ(HSW_PWR_WELL_DRIVER), "Power well on\n"); | 6309 | WARN(I915_READ(HSW_PWR_WELL_DRIVER), "Power well on\n"); |
@@ -9135,7 +9135,7 @@ intel_pipe_config_compare(struct drm_device *dev, | |||
9135 | if (IS_G4X(dev) || INTEL_INFO(dev)->gen >= 5) | 9135 | if (IS_G4X(dev) || INTEL_INFO(dev)->gen >= 5) |
9136 | PIPE_CONF_CHECK_I(pipe_bpp); | 9136 | PIPE_CONF_CHECK_I(pipe_bpp); |
9137 | 9137 | ||
9138 | if (!IS_HASWELL(dev)) { | 9138 | if (!HAS_DDI(dev)) { |
9139 | PIPE_CONF_CHECK_CLOCK_FUZZY(adjusted_mode.crtc_clock); | 9139 | PIPE_CONF_CHECK_CLOCK_FUZZY(adjusted_mode.crtc_clock); |
9140 | PIPE_CONF_CHECK_CLOCK_FUZZY(port_clock); | 9140 | PIPE_CONF_CHECK_CLOCK_FUZZY(port_clock); |
9141 | } | 9141 | } |
@@ -10541,11 +10541,20 @@ static struct intel_quirk intel_quirks[] = { | |||
10541 | /* Sony Vaio Y cannot use SSC on LVDS */ | 10541 | /* Sony Vaio Y cannot use SSC on LVDS */ |
10542 | { 0x0046, 0x104d, 0x9076, quirk_ssc_force_disable }, | 10542 | { 0x0046, 0x104d, 0x9076, quirk_ssc_force_disable }, |
10543 | 10543 | ||
10544 | /* | 10544 | /* Acer Aspire 5734Z must invert backlight brightness */ |
10545 | * All GM45 Acer (and its brands eMachines and Packard Bell) laptops | 10545 | { 0x2a42, 0x1025, 0x0459, quirk_invert_brightness }, |
10546 | * seem to use inverted backlight PWM. | 10546 | |
10547 | */ | 10547 | /* Acer/eMachines G725 */ |
10548 | { 0x2a42, 0x1025, PCI_ANY_ID, quirk_invert_brightness }, | 10548 | { 0x2a42, 0x1025, 0x0210, quirk_invert_brightness }, |
10549 | |||
10550 | /* Acer/eMachines e725 */ | ||
10551 | { 0x2a42, 0x1025, 0x0212, quirk_invert_brightness }, | ||
10552 | |||
10553 | /* Acer/Packard Bell NCL20 */ | ||
10554 | { 0x2a42, 0x1025, 0x034b, quirk_invert_brightness }, | ||
10555 | |||
10556 | /* Acer Aspire 4736Z */ | ||
10557 | { 0x2a42, 0x1025, 0x0260, quirk_invert_brightness }, | ||
10549 | 10558 | ||
10550 | /* Dell XPS13 HD Sandy Bridge */ | 10559 | /* Dell XPS13 HD Sandy Bridge */ |
10551 | { 0x0116, 0x1028, 0x052e, quirk_no_pcm_pwm_enable }, | 10560 | { 0x0116, 0x1028, 0x052e, quirk_no_pcm_pwm_enable }, |
@@ -11036,8 +11045,6 @@ void intel_modeset_setup_hw_state(struct drm_device *dev, | |||
11036 | } | 11045 | } |
11037 | 11046 | ||
11038 | intel_modeset_check_state(dev); | 11047 | intel_modeset_check_state(dev); |
11039 | |||
11040 | drm_mode_config_reset(dev); | ||
11041 | } | 11048 | } |
11042 | 11049 | ||
11043 | void intel_modeset_gem_init(struct drm_device *dev) | 11050 | void intel_modeset_gem_init(struct drm_device *dev) |
@@ -11046,7 +11053,10 @@ void intel_modeset_gem_init(struct drm_device *dev) | |||
11046 | 11053 | ||
11047 | intel_setup_overlay(dev); | 11054 | intel_setup_overlay(dev); |
11048 | 11055 | ||
11056 | mutex_lock(&dev->mode_config.mutex); | ||
11057 | drm_mode_config_reset(dev); | ||
11049 | intel_modeset_setup_hw_state(dev, false); | 11058 | intel_modeset_setup_hw_state(dev, false); |
11059 | mutex_unlock(&dev->mode_config.mutex); | ||
11050 | } | 11060 | } |
11051 | 11061 | ||
11052 | void intel_modeset_cleanup(struct drm_device *dev) | 11062 | void intel_modeset_cleanup(struct drm_device *dev) |
@@ -11125,14 +11135,15 @@ void intel_connector_attach_encoder(struct intel_connector *connector, | |||
11125 | int intel_modeset_vga_set_state(struct drm_device *dev, bool state) | 11135 | int intel_modeset_vga_set_state(struct drm_device *dev, bool state) |
11126 | { | 11136 | { |
11127 | struct drm_i915_private *dev_priv = dev->dev_private; | 11137 | struct drm_i915_private *dev_priv = dev->dev_private; |
11138 | unsigned reg = INTEL_INFO(dev)->gen >= 6 ? SNB_GMCH_CTRL : INTEL_GMCH_CTRL; | ||
11128 | u16 gmch_ctrl; | 11139 | u16 gmch_ctrl; |
11129 | 11140 | ||
11130 | pci_read_config_word(dev_priv->bridge_dev, INTEL_GMCH_CTRL, &gmch_ctrl); | 11141 | pci_read_config_word(dev_priv->bridge_dev, reg, &gmch_ctrl); |
11131 | if (state) | 11142 | if (state) |
11132 | gmch_ctrl &= ~INTEL_GMCH_VGA_DISABLE; | 11143 | gmch_ctrl &= ~INTEL_GMCH_VGA_DISABLE; |
11133 | else | 11144 | else |
11134 | gmch_ctrl |= INTEL_GMCH_VGA_DISABLE; | 11145 | gmch_ctrl |= INTEL_GMCH_VGA_DISABLE; |
11135 | pci_write_config_word(dev_priv->bridge_dev, INTEL_GMCH_CTRL, gmch_ctrl); | 11146 | pci_write_config_word(dev_priv->bridge_dev, reg, gmch_ctrl); |
11136 | return 0; | 11147 | return 0; |
11137 | } | 11148 | } |
11138 | 11149 | ||
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index a18e88b3e425..79f91f26e288 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h | |||
@@ -821,6 +821,7 @@ void intel_update_sprite_watermarks(struct drm_plane *plane, | |||
821 | uint32_t sprite_width, int pixel_size, | 821 | uint32_t sprite_width, int pixel_size, |
822 | bool enabled, bool scaled); | 822 | bool enabled, bool scaled); |
823 | void intel_init_pm(struct drm_device *dev); | 823 | void intel_init_pm(struct drm_device *dev); |
824 | void intel_pm_setup(struct drm_device *dev); | ||
824 | bool intel_fbc_enabled(struct drm_device *dev); | 825 | bool intel_fbc_enabled(struct drm_device *dev); |
825 | void intel_update_fbc(struct drm_device *dev); | 826 | void intel_update_fbc(struct drm_device *dev); |
826 | void intel_gpu_ips_init(struct drm_i915_private *dev_priv); | 827 | void intel_gpu_ips_init(struct drm_i915_private *dev_priv); |
diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c index f161ac02c4f6..e6f782d1c669 100644 --- a/drivers/gpu/drm/i915/intel_panel.c +++ b/drivers/gpu/drm/i915/intel_panel.c | |||
@@ -451,7 +451,9 @@ static u32 intel_panel_get_backlight(struct drm_device *dev, | |||
451 | 451 | ||
452 | spin_lock_irqsave(&dev_priv->backlight.lock, flags); | 452 | spin_lock_irqsave(&dev_priv->backlight.lock, flags); |
453 | 453 | ||
454 | if (HAS_PCH_SPLIT(dev)) { | 454 | if (IS_BROADWELL(dev)) { |
455 | val = I915_READ(BLC_PWM_PCH_CTL2) & BACKLIGHT_DUTY_CYCLE_MASK; | ||
456 | } else if (HAS_PCH_SPLIT(dev)) { | ||
455 | val = I915_READ(BLC_PWM_CPU_CTL) & BACKLIGHT_DUTY_CYCLE_MASK; | 457 | val = I915_READ(BLC_PWM_CPU_CTL) & BACKLIGHT_DUTY_CYCLE_MASK; |
456 | } else { | 458 | } else { |
457 | if (IS_VALLEYVIEW(dev)) | 459 | if (IS_VALLEYVIEW(dev)) |
@@ -479,6 +481,13 @@ static u32 intel_panel_get_backlight(struct drm_device *dev, | |||
479 | return val; | 481 | return val; |
480 | } | 482 | } |
481 | 483 | ||
484 | static void intel_bdw_panel_set_backlight(struct drm_device *dev, u32 level) | ||
485 | { | ||
486 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
487 | u32 val = I915_READ(BLC_PWM_PCH_CTL2) & ~BACKLIGHT_DUTY_CYCLE_MASK; | ||
488 | I915_WRITE(BLC_PWM_PCH_CTL2, val | level); | ||
489 | } | ||
490 | |||
482 | static void intel_pch_panel_set_backlight(struct drm_device *dev, u32 level) | 491 | static void intel_pch_panel_set_backlight(struct drm_device *dev, u32 level) |
483 | { | 492 | { |
484 | struct drm_i915_private *dev_priv = dev->dev_private; | 493 | struct drm_i915_private *dev_priv = dev->dev_private; |
@@ -496,7 +505,9 @@ static void intel_panel_actually_set_backlight(struct drm_device *dev, | |||
496 | DRM_DEBUG_DRIVER("set backlight PWM = %d\n", level); | 505 | DRM_DEBUG_DRIVER("set backlight PWM = %d\n", level); |
497 | level = intel_panel_compute_brightness(dev, pipe, level); | 506 | level = intel_panel_compute_brightness(dev, pipe, level); |
498 | 507 | ||
499 | if (HAS_PCH_SPLIT(dev)) | 508 | if (IS_BROADWELL(dev)) |
509 | return intel_bdw_panel_set_backlight(dev, level); | ||
510 | else if (HAS_PCH_SPLIT(dev)) | ||
500 | return intel_pch_panel_set_backlight(dev, level); | 511 | return intel_pch_panel_set_backlight(dev, level); |
501 | 512 | ||
502 | if (is_backlight_combination_mode(dev)) { | 513 | if (is_backlight_combination_mode(dev)) { |
@@ -666,7 +677,16 @@ void intel_panel_enable_backlight(struct intel_connector *connector) | |||
666 | POSTING_READ(reg); | 677 | POSTING_READ(reg); |
667 | I915_WRITE(reg, tmp | BLM_PWM_ENABLE); | 678 | I915_WRITE(reg, tmp | BLM_PWM_ENABLE); |
668 | 679 | ||
669 | if (HAS_PCH_SPLIT(dev) && | 680 | if (IS_BROADWELL(dev)) { |
681 | /* | ||
682 | * Broadwell requires PCH override to drive the PCH | ||
683 | * backlight pin. The above will configure the CPU | ||
684 | * backlight pin, which we don't plan to use. | ||
685 | */ | ||
686 | tmp = I915_READ(BLC_PWM_PCH_CTL1); | ||
687 | tmp |= BLM_PCH_OVERRIDE_ENABLE | BLM_PCH_PWM_ENABLE; | ||
688 | I915_WRITE(BLC_PWM_PCH_CTL1, tmp); | ||
689 | } else if (HAS_PCH_SPLIT(dev) && | ||
670 | !(dev_priv->quirks & QUIRK_NO_PCH_PWM_ENABLE)) { | 690 | !(dev_priv->quirks & QUIRK_NO_PCH_PWM_ENABLE)) { |
671 | tmp = I915_READ(BLC_PWM_PCH_CTL1); | 691 | tmp = I915_READ(BLC_PWM_PCH_CTL1); |
672 | tmp |= BLM_PCH_PWM_ENABLE; | 692 | tmp |= BLM_PCH_PWM_ENABLE; |
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 6e0d5e075b15..26c29c173221 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c | |||
@@ -5685,8 +5685,11 @@ static void __intel_set_power_well(struct drm_device *dev, bool enable) | |||
5685 | { | 5685 | { |
5686 | struct drm_i915_private *dev_priv = dev->dev_private; | 5686 | struct drm_i915_private *dev_priv = dev->dev_private; |
5687 | bool is_enabled, enable_requested; | 5687 | bool is_enabled, enable_requested; |
5688 | unsigned long irqflags; | ||
5688 | uint32_t tmp; | 5689 | uint32_t tmp; |
5689 | 5690 | ||
5691 | WARN_ON(dev_priv->pc8.enabled); | ||
5692 | |||
5690 | tmp = I915_READ(HSW_PWR_WELL_DRIVER); | 5693 | tmp = I915_READ(HSW_PWR_WELL_DRIVER); |
5691 | is_enabled = tmp & HSW_PWR_WELL_STATE_ENABLED; | 5694 | is_enabled = tmp & HSW_PWR_WELL_STATE_ENABLED; |
5692 | enable_requested = tmp & HSW_PWR_WELL_ENABLE_REQUEST; | 5695 | enable_requested = tmp & HSW_PWR_WELL_ENABLE_REQUEST; |
@@ -5702,9 +5705,24 @@ static void __intel_set_power_well(struct drm_device *dev, bool enable) | |||
5702 | HSW_PWR_WELL_STATE_ENABLED), 20)) | 5705 | HSW_PWR_WELL_STATE_ENABLED), 20)) |
5703 | DRM_ERROR("Timeout enabling power well\n"); | 5706 | DRM_ERROR("Timeout enabling power well\n"); |
5704 | } | 5707 | } |
5708 | |||
5709 | if (IS_BROADWELL(dev)) { | ||
5710 | spin_lock_irqsave(&dev_priv->irq_lock, irqflags); | ||
5711 | I915_WRITE(GEN8_DE_PIPE_IMR(PIPE_B), | ||
5712 | dev_priv->de_irq_mask[PIPE_B]); | ||
5713 | I915_WRITE(GEN8_DE_PIPE_IER(PIPE_B), | ||
5714 | ~dev_priv->de_irq_mask[PIPE_B] | | ||
5715 | GEN8_PIPE_VBLANK); | ||
5716 | I915_WRITE(GEN8_DE_PIPE_IMR(PIPE_C), | ||
5717 | dev_priv->de_irq_mask[PIPE_C]); | ||
5718 | I915_WRITE(GEN8_DE_PIPE_IER(PIPE_C), | ||
5719 | ~dev_priv->de_irq_mask[PIPE_C] | | ||
5720 | GEN8_PIPE_VBLANK); | ||
5721 | POSTING_READ(GEN8_DE_PIPE_IER(PIPE_C)); | ||
5722 | spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); | ||
5723 | } | ||
5705 | } else { | 5724 | } else { |
5706 | if (enable_requested) { | 5725 | if (enable_requested) { |
5707 | unsigned long irqflags; | ||
5708 | enum pipe p; | 5726 | enum pipe p; |
5709 | 5727 | ||
5710 | I915_WRITE(HSW_PWR_WELL_DRIVER, 0); | 5728 | I915_WRITE(HSW_PWR_WELL_DRIVER, 0); |
@@ -5731,16 +5749,24 @@ static void __intel_set_power_well(struct drm_device *dev, bool enable) | |||
5731 | static void __intel_power_well_get(struct drm_device *dev, | 5749 | static void __intel_power_well_get(struct drm_device *dev, |
5732 | struct i915_power_well *power_well) | 5750 | struct i915_power_well *power_well) |
5733 | { | 5751 | { |
5734 | if (!power_well->count++) | 5752 | struct drm_i915_private *dev_priv = dev->dev_private; |
5753 | |||
5754 | if (!power_well->count++) { | ||
5755 | hsw_disable_package_c8(dev_priv); | ||
5735 | __intel_set_power_well(dev, true); | 5756 | __intel_set_power_well(dev, true); |
5757 | } | ||
5736 | } | 5758 | } |
5737 | 5759 | ||
5738 | static void __intel_power_well_put(struct drm_device *dev, | 5760 | static void __intel_power_well_put(struct drm_device *dev, |
5739 | struct i915_power_well *power_well) | 5761 | struct i915_power_well *power_well) |
5740 | { | 5762 | { |
5763 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
5764 | |||
5741 | WARN_ON(!power_well->count); | 5765 | WARN_ON(!power_well->count); |
5742 | if (!--power_well->count && i915_disable_power_well) | 5766 | if (!--power_well->count && i915_disable_power_well) { |
5743 | __intel_set_power_well(dev, false); | 5767 | __intel_set_power_well(dev, false); |
5768 | hsw_enable_package_c8(dev_priv); | ||
5769 | } | ||
5744 | } | 5770 | } |
5745 | 5771 | ||
5746 | void intel_display_power_get(struct drm_device *dev, | 5772 | void intel_display_power_get(struct drm_device *dev, |
@@ -6130,10 +6156,19 @@ int vlv_freq_opcode(int ddr_freq, int val) | |||
6130 | return val; | 6156 | return val; |
6131 | } | 6157 | } |
6132 | 6158 | ||
6133 | void intel_pm_init(struct drm_device *dev) | 6159 | void intel_pm_setup(struct drm_device *dev) |
6134 | { | 6160 | { |
6135 | struct drm_i915_private *dev_priv = dev->dev_private; | 6161 | struct drm_i915_private *dev_priv = dev->dev_private; |
6136 | 6162 | ||
6163 | mutex_init(&dev_priv->rps.hw_lock); | ||
6164 | |||
6165 | mutex_init(&dev_priv->pc8.lock); | ||
6166 | dev_priv->pc8.requirements_met = false; | ||
6167 | dev_priv->pc8.gpu_idle = false; | ||
6168 | dev_priv->pc8.irqs_disabled = false; | ||
6169 | dev_priv->pc8.enabled = false; | ||
6170 | dev_priv->pc8.disable_count = 2; /* requirements_met + gpu_idle */ | ||
6171 | INIT_DELAYED_WORK(&dev_priv->pc8.enable_work, hsw_enable_pc8_work); | ||
6137 | INIT_DELAYED_WORK(&dev_priv->rps.delayed_resume_work, | 6172 | INIT_DELAYED_WORK(&dev_priv->rps.delayed_resume_work, |
6138 | intel_gen6_powersave_work); | 6173 | intel_gen6_powersave_work); |
6139 | } | 6174 | } |
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index b620337e6d67..c2f09d456300 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c | |||
@@ -965,6 +965,7 @@ void intel_ring_setup_status_page(struct intel_ring_buffer *ring) | |||
965 | } else if (IS_GEN6(ring->dev)) { | 965 | } else if (IS_GEN6(ring->dev)) { |
966 | mmio = RING_HWS_PGA_GEN6(ring->mmio_base); | 966 | mmio = RING_HWS_PGA_GEN6(ring->mmio_base); |
967 | } else { | 967 | } else { |
968 | /* XXX: gen8 returns to sanity */ | ||
968 | mmio = RING_HWS_PGA(ring->mmio_base); | 969 | mmio = RING_HWS_PGA(ring->mmio_base); |
969 | } | 970 | } |
970 | 971 | ||
diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c index 0b02078a0b84..25cbe073c388 100644 --- a/drivers/gpu/drm/i915/intel_uncore.c +++ b/drivers/gpu/drm/i915/intel_uncore.c | |||
@@ -784,6 +784,7 @@ static int gen6_do_reset(struct drm_device *dev) | |||
784 | int intel_gpu_reset(struct drm_device *dev) | 784 | int intel_gpu_reset(struct drm_device *dev) |
785 | { | 785 | { |
786 | switch (INTEL_INFO(dev)->gen) { | 786 | switch (INTEL_INFO(dev)->gen) { |
787 | case 8: | ||
787 | case 7: | 788 | case 7: |
788 | case 6: return gen6_do_reset(dev); | 789 | case 6: return gen6_do_reset(dev); |
789 | case 5: return ironlake_do_reset(dev); | 790 | case 5: return ironlake_do_reset(dev); |
diff --git a/drivers/gpu/drm/nouveau/core/core/subdev.c b/drivers/gpu/drm/nouveau/core/core/subdev.c index 48f06378d3f9..2ea5568b6cf5 100644 --- a/drivers/gpu/drm/nouveau/core/core/subdev.c +++ b/drivers/gpu/drm/nouveau/core/core/subdev.c | |||
@@ -104,11 +104,8 @@ nouveau_subdev_create_(struct nouveau_object *parent, | |||
104 | 104 | ||
105 | if (parent) { | 105 | if (parent) { |
106 | struct nouveau_device *device = nv_device(parent); | 106 | struct nouveau_device *device = nv_device(parent); |
107 | int subidx = nv_hclass(subdev) & 0xff; | ||
108 | |||
109 | subdev->debug = nouveau_dbgopt(device->dbgopt, subname); | 107 | subdev->debug = nouveau_dbgopt(device->dbgopt, subname); |
110 | subdev->mmio = nv_subdev(device)->mmio; | 108 | subdev->mmio = nv_subdev(device)->mmio; |
111 | device->subdev[subidx] = *pobject; | ||
112 | } | 109 | } |
113 | 110 | ||
114 | return 0; | 111 | return 0; |
diff --git a/drivers/gpu/drm/nouveau/core/engine/device/base.c b/drivers/gpu/drm/nouveau/core/engine/device/base.c index 9135b25a29d0..dd01c6c435d6 100644 --- a/drivers/gpu/drm/nouveau/core/engine/device/base.c +++ b/drivers/gpu/drm/nouveau/core/engine/device/base.c | |||
@@ -268,6 +268,8 @@ nouveau_devobj_ctor(struct nouveau_object *parent, | |||
268 | if (ret) | 268 | if (ret) |
269 | return ret; | 269 | return ret; |
270 | 270 | ||
271 | device->subdev[i] = devobj->subdev[i]; | ||
272 | |||
271 | /* note: can't init *any* subdevs until devinit has been run | 273 | /* note: can't init *any* subdevs until devinit has been run |
272 | * due to not knowing exactly what the vbios init tables will | 274 | * due to not knowing exactly what the vbios init tables will |
273 | * mess with. devinit also can't be run until all of its | 275 | * mess with. devinit also can't be run until all of its |
diff --git a/drivers/gpu/drm/nouveau/core/engine/device/nvc0.c b/drivers/gpu/drm/nouveau/core/engine/device/nvc0.c index 8d06eef2b9ee..dbc5e33de94f 100644 --- a/drivers/gpu/drm/nouveau/core/engine/device/nvc0.c +++ b/drivers/gpu/drm/nouveau/core/engine/device/nvc0.c | |||
@@ -161,7 +161,7 @@ nvc0_identify(struct nouveau_device *device) | |||
161 | device->oclass[NVDEV_SUBDEV_THERM ] = &nva3_therm_oclass; | 161 | device->oclass[NVDEV_SUBDEV_THERM ] = &nva3_therm_oclass; |
162 | device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass; | 162 | device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass; |
163 | device->oclass[NVDEV_SUBDEV_DEVINIT] = &nvc0_devinit_oclass; | 163 | device->oclass[NVDEV_SUBDEV_DEVINIT] = &nvc0_devinit_oclass; |
164 | device->oclass[NVDEV_SUBDEV_MC ] = nvc3_mc_oclass; | 164 | device->oclass[NVDEV_SUBDEV_MC ] = nvc0_mc_oclass; |
165 | device->oclass[NVDEV_SUBDEV_BUS ] = nvc0_bus_oclass; | 165 | device->oclass[NVDEV_SUBDEV_BUS ] = nvc0_bus_oclass; |
166 | device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; | 166 | device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; |
167 | device->oclass[NVDEV_SUBDEV_FB ] = nvc0_fb_oclass; | 167 | device->oclass[NVDEV_SUBDEV_FB ] = nvc0_fb_oclass; |
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nvc0.c b/drivers/gpu/drm/nouveau/core/engine/graph/nvc0.c index 434bb4b0fa2e..5c8a63dc506a 100644 --- a/drivers/gpu/drm/nouveau/core/engine/graph/nvc0.c +++ b/drivers/gpu/drm/nouveau/core/engine/graph/nvc0.c | |||
@@ -334,7 +334,7 @@ nvc0_graph_mthd(struct nvc0_graph_priv *priv, struct nvc0_graph_mthd *mthds) | |||
334 | while ((mthd = &mthds[i++]) && (init = mthd->init)) { | 334 | while ((mthd = &mthds[i++]) && (init = mthd->init)) { |
335 | u32 addr = 0x80000000 | mthd->oclass; | 335 | u32 addr = 0x80000000 | mthd->oclass; |
336 | for (data = 0; init->count; init++) { | 336 | for (data = 0; init->count; init++) { |
337 | if (data != init->data) { | 337 | if (init == mthd->init || data != init->data) { |
338 | nv_wr32(priv, 0x40448c, init->data); | 338 | nv_wr32(priv, 0x40448c, init->data); |
339 | data = init->data; | 339 | data = init->data; |
340 | } | 340 | } |
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/fb.h b/drivers/gpu/drm/nouveau/core/include/subdev/fb.h index 8541aa382ff2..d89dbdf39b0d 100644 --- a/drivers/gpu/drm/nouveau/core/include/subdev/fb.h +++ b/drivers/gpu/drm/nouveau/core/include/subdev/fb.h | |||
@@ -75,6 +75,11 @@ struct nouveau_fb { | |||
75 | static inline struct nouveau_fb * | 75 | static inline struct nouveau_fb * |
76 | nouveau_fb(void *obj) | 76 | nouveau_fb(void *obj) |
77 | { | 77 | { |
78 | /* fbram uses this before device subdev pointer is valid */ | ||
79 | if (nv_iclass(obj, NV_SUBDEV_CLASS) && | ||
80 | nv_subidx(obj) == NVDEV_SUBDEV_FB) | ||
81 | return obj; | ||
82 | |||
78 | return (void *)nv_device(obj)->subdev[NVDEV_SUBDEV_FB]; | 83 | return (void *)nv_device(obj)->subdev[NVDEV_SUBDEV_FB]; |
79 | } | 84 | } |
80 | 85 | ||
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/i2c.h b/drivers/gpu/drm/nouveau/core/include/subdev/i2c.h index 9fa5da723871..7f50a858b16f 100644 --- a/drivers/gpu/drm/nouveau/core/include/subdev/i2c.h +++ b/drivers/gpu/drm/nouveau/core/include/subdev/i2c.h | |||
@@ -73,7 +73,7 @@ struct nouveau_i2c { | |||
73 | int (*identify)(struct nouveau_i2c *, int index, | 73 | int (*identify)(struct nouveau_i2c *, int index, |
74 | const char *what, struct nouveau_i2c_board_info *, | 74 | const char *what, struct nouveau_i2c_board_info *, |
75 | bool (*match)(struct nouveau_i2c_port *, | 75 | bool (*match)(struct nouveau_i2c_port *, |
76 | struct i2c_board_info *)); | 76 | struct i2c_board_info *, void *), void *); |
77 | struct list_head ports; | 77 | struct list_head ports; |
78 | }; | 78 | }; |
79 | 79 | ||
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/instmem.h b/drivers/gpu/drm/nouveau/core/include/subdev/instmem.h index ec7a54e91a08..4aca33887aaa 100644 --- a/drivers/gpu/drm/nouveau/core/include/subdev/instmem.h +++ b/drivers/gpu/drm/nouveau/core/include/subdev/instmem.h | |||
@@ -50,6 +50,13 @@ struct nouveau_instmem { | |||
50 | static inline struct nouveau_instmem * | 50 | static inline struct nouveau_instmem * |
51 | nouveau_instmem(void *obj) | 51 | nouveau_instmem(void *obj) |
52 | { | 52 | { |
53 | /* nv04/nv40 impls need to create objects in their constructor, | ||
54 | * which is before the subdev pointer is valid | ||
55 | */ | ||
56 | if (nv_iclass(obj, NV_SUBDEV_CLASS) && | ||
57 | nv_subidx(obj) == NVDEV_SUBDEV_INSTMEM) | ||
58 | return obj; | ||
59 | |||
53 | return (void *)nv_device(obj)->subdev[NVDEV_SUBDEV_INSTMEM]; | 60 | return (void *)nv_device(obj)->subdev[NVDEV_SUBDEV_INSTMEM]; |
54 | } | 61 | } |
55 | 62 | ||
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/init.c b/drivers/gpu/drm/nouveau/core/subdev/bios/init.c index 420908cb82b6..df1b1b423093 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/bios/init.c +++ b/drivers/gpu/drm/nouveau/core/subdev/bios/init.c | |||
@@ -365,13 +365,13 @@ static u16 | |||
365 | init_script(struct nouveau_bios *bios, int index) | 365 | init_script(struct nouveau_bios *bios, int index) |
366 | { | 366 | { |
367 | struct nvbios_init init = { .bios = bios }; | 367 | struct nvbios_init init = { .bios = bios }; |
368 | u16 data; | 368 | u16 bmp_ver = bmp_version(bios), data; |
369 | 369 | ||
370 | if (bmp_version(bios) && bmp_version(bios) < 0x0510) { | 370 | if (bmp_ver && bmp_ver < 0x0510) { |
371 | if (index > 1) | 371 | if (index > 1 || bmp_ver < 0x0100) |
372 | return 0x0000; | 372 | return 0x0000; |
373 | 373 | ||
374 | data = bios->bmp_offset + (bios->version.major < 2 ? 14 : 18); | 374 | data = bios->bmp_offset + (bmp_ver < 0x0200 ? 14 : 18); |
375 | return nv_ro16(bios, data + (index * 2)); | 375 | return nv_ro16(bios, data + (index * 2)); |
376 | } | 376 | } |
377 | 377 | ||
@@ -1294,7 +1294,11 @@ init_jump(struct nvbios_init *init) | |||
1294 | u16 offset = nv_ro16(bios, init->offset + 1); | 1294 | u16 offset = nv_ro16(bios, init->offset + 1); |
1295 | 1295 | ||
1296 | trace("JUMP\t0x%04x\n", offset); | 1296 | trace("JUMP\t0x%04x\n", offset); |
1297 | init->offset = offset; | 1297 | |
1298 | if (init_exec(init)) | ||
1299 | init->offset = offset; | ||
1300 | else | ||
1301 | init->offset += 3; | ||
1298 | } | 1302 | } |
1299 | 1303 | ||
1300 | /** | 1304 | /** |
diff --git a/drivers/gpu/drm/nouveau/core/subdev/i2c/base.c b/drivers/gpu/drm/nouveau/core/subdev/i2c/base.c index 041fd5edaebf..c33c03d2f4af 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/i2c/base.c +++ b/drivers/gpu/drm/nouveau/core/subdev/i2c/base.c | |||
@@ -197,7 +197,7 @@ static int | |||
197 | nouveau_i2c_identify(struct nouveau_i2c *i2c, int index, const char *what, | 197 | nouveau_i2c_identify(struct nouveau_i2c *i2c, int index, const char *what, |
198 | struct nouveau_i2c_board_info *info, | 198 | struct nouveau_i2c_board_info *info, |
199 | bool (*match)(struct nouveau_i2c_port *, | 199 | bool (*match)(struct nouveau_i2c_port *, |
200 | struct i2c_board_info *)) | 200 | struct i2c_board_info *, void *), void *data) |
201 | { | 201 | { |
202 | struct nouveau_i2c_port *port = nouveau_i2c_find(i2c, index); | 202 | struct nouveau_i2c_port *port = nouveau_i2c_find(i2c, index); |
203 | int i; | 203 | int i; |
@@ -221,7 +221,7 @@ nouveau_i2c_identify(struct nouveau_i2c *i2c, int index, const char *what, | |||
221 | } | 221 | } |
222 | 222 | ||
223 | if (nv_probe_i2c(port, info[i].dev.addr) && | 223 | if (nv_probe_i2c(port, info[i].dev.addr) && |
224 | (!match || match(port, &info[i].dev))) { | 224 | (!match || match(port, &info[i].dev, data))) { |
225 | nv_info(i2c, "detected %s: %s\n", what, | 225 | nv_info(i2c, "detected %s: %s\n", what, |
226 | info[i].dev.type); | 226 | info[i].dev.type); |
227 | return i; | 227 | return i; |
diff --git a/drivers/gpu/drm/nouveau/core/subdev/mxm/nv50.c b/drivers/gpu/drm/nouveau/core/subdev/mxm/nv50.c index af129c2e8113..64f8b4702bf7 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/mxm/nv50.c +++ b/drivers/gpu/drm/nouveau/core/subdev/mxm/nv50.c | |||
@@ -100,7 +100,7 @@ mxm_match_dcb(struct nouveau_mxm *mxm, u8 *data, void *info) | |||
100 | static int | 100 | static int |
101 | mxm_dcb_sanitise_entry(struct nouveau_bios *bios, void *data, int idx, u16 pdcb) | 101 | mxm_dcb_sanitise_entry(struct nouveau_bios *bios, void *data, int idx, u16 pdcb) |
102 | { | 102 | { |
103 | struct nouveau_mxm *mxm = nouveau_mxm(bios); | 103 | struct nouveau_mxm *mxm = data; |
104 | struct context ctx = { .outp = (u32 *)(bios->data + pdcb) }; | 104 | struct context ctx = { .outp = (u32 *)(bios->data + pdcb) }; |
105 | u8 type, i2cidx, link, ver, len; | 105 | u8 type, i2cidx, link, ver, len; |
106 | u8 *conn; | 106 | u8 *conn; |
@@ -199,7 +199,7 @@ mxm_dcb_sanitise(struct nouveau_mxm *mxm) | |||
199 | return; | 199 | return; |
200 | } | 200 | } |
201 | 201 | ||
202 | dcb_outp_foreach(bios, NULL, mxm_dcb_sanitise_entry); | 202 | dcb_outp_foreach(bios, mxm, mxm_dcb_sanitise_entry); |
203 | mxms_foreach(mxm, 0x01, mxm_show_unmatched, NULL); | 203 | mxms_foreach(mxm, 0x01, mxm_show_unmatched, NULL); |
204 | } | 204 | } |
205 | 205 | ||
diff --git a/drivers/gpu/drm/nouveau/core/subdev/therm/ic.c b/drivers/gpu/drm/nouveau/core/subdev/therm/ic.c index e44ed7b93c6d..7610fc5f8fa2 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/therm/ic.c +++ b/drivers/gpu/drm/nouveau/core/subdev/therm/ic.c | |||
@@ -29,9 +29,9 @@ | |||
29 | 29 | ||
30 | static bool | 30 | static bool |
31 | probe_monitoring_device(struct nouveau_i2c_port *i2c, | 31 | probe_monitoring_device(struct nouveau_i2c_port *i2c, |
32 | struct i2c_board_info *info) | 32 | struct i2c_board_info *info, void *data) |
33 | { | 33 | { |
34 | struct nouveau_therm_priv *priv = (void *)nouveau_therm(i2c); | 34 | struct nouveau_therm_priv *priv = data; |
35 | struct nvbios_therm_sensor *sensor = &priv->bios_sensor; | 35 | struct nvbios_therm_sensor *sensor = &priv->bios_sensor; |
36 | struct i2c_client *client; | 36 | struct i2c_client *client; |
37 | 37 | ||
@@ -96,7 +96,7 @@ nouveau_therm_ic_ctor(struct nouveau_therm *therm) | |||
96 | }; | 96 | }; |
97 | 97 | ||
98 | i2c->identify(i2c, NV_I2C_DEFAULT(0), "monitoring device", | 98 | i2c->identify(i2c, NV_I2C_DEFAULT(0), "monitoring device", |
99 | board, probe_monitoring_device); | 99 | board, probe_monitoring_device, therm); |
100 | if (priv->ic) | 100 | if (priv->ic) |
101 | return; | 101 | return; |
102 | } | 102 | } |
@@ -108,7 +108,7 @@ nouveau_therm_ic_ctor(struct nouveau_therm *therm) | |||
108 | }; | 108 | }; |
109 | 109 | ||
110 | i2c->identify(i2c, NV_I2C_DEFAULT(0), "monitoring device", | 110 | i2c->identify(i2c, NV_I2C_DEFAULT(0), "monitoring device", |
111 | board, probe_monitoring_device); | 111 | board, probe_monitoring_device, therm); |
112 | if (priv->ic) | 112 | if (priv->ic) |
113 | return; | 113 | return; |
114 | } | 114 | } |
@@ -117,5 +117,5 @@ nouveau_therm_ic_ctor(struct nouveau_therm *therm) | |||
117 | device. Let's try our static list. | 117 | device. Let's try our static list. |
118 | */ | 118 | */ |
119 | i2c->identify(i2c, NV_I2C_DEFAULT(0), "monitoring device", | 119 | i2c->identify(i2c, NV_I2C_DEFAULT(0), "monitoring device", |
120 | nv_board_infos, probe_monitoring_device); | 120 | nv_board_infos, probe_monitoring_device, therm); |
121 | } | 121 | } |
diff --git a/drivers/gpu/drm/nouveau/dispnv04/dfp.c b/drivers/gpu/drm/nouveau/dispnv04/dfp.c index 936a71c59080..7fdc51e2a571 100644 --- a/drivers/gpu/drm/nouveau/dispnv04/dfp.c +++ b/drivers/gpu/drm/nouveau/dispnv04/dfp.c | |||
@@ -643,7 +643,7 @@ static void nv04_tmds_slave_init(struct drm_encoder *encoder) | |||
643 | get_tmds_slave(encoder)) | 643 | get_tmds_slave(encoder)) |
644 | return; | 644 | return; |
645 | 645 | ||
646 | type = i2c->identify(i2c, 2, "TMDS transmitter", info, NULL); | 646 | type = i2c->identify(i2c, 2, "TMDS transmitter", info, NULL, NULL); |
647 | if (type < 0) | 647 | if (type < 0) |
648 | return; | 648 | return; |
649 | 649 | ||
diff --git a/drivers/gpu/drm/nouveau/dispnv04/tvnv04.c b/drivers/gpu/drm/nouveau/dispnv04/tvnv04.c index cc4b208ce546..244822df8ffc 100644 --- a/drivers/gpu/drm/nouveau/dispnv04/tvnv04.c +++ b/drivers/gpu/drm/nouveau/dispnv04/tvnv04.c | |||
@@ -59,7 +59,7 @@ int nv04_tv_identify(struct drm_device *dev, int i2c_index) | |||
59 | struct nouveau_i2c *i2c = nouveau_i2c(drm->device); | 59 | struct nouveau_i2c *i2c = nouveau_i2c(drm->device); |
60 | 60 | ||
61 | return i2c->identify(i2c, i2c_index, "TV encoder", | 61 | return i2c->identify(i2c, i2c_index, "TV encoder", |
62 | nv04_tv_encoder_info, NULL); | 62 | nv04_tv_encoder_info, NULL, NULL); |
63 | } | 63 | } |
64 | 64 | ||
65 | 65 | ||
diff --git a/drivers/gpu/drm/nouveau/nouveau_abi16.c b/drivers/gpu/drm/nouveau/nouveau_abi16.c index 6828d81ed7b9..900fae01793e 100644 --- a/drivers/gpu/drm/nouveau/nouveau_abi16.c +++ b/drivers/gpu/drm/nouveau/nouveau_abi16.c | |||
@@ -447,6 +447,8 @@ nouveau_abi16_ioctl_notifierobj_alloc(ABI16_IOCTL_ARGS) | |||
447 | if (ret) | 447 | if (ret) |
448 | goto done; | 448 | goto done; |
449 | 449 | ||
450 | info->offset = ntfy->node->offset; | ||
451 | |||
450 | done: | 452 | done: |
451 | if (ret) | 453 | if (ret) |
452 | nouveau_abi16_ntfy_fini(chan, ntfy); | 454 | nouveau_abi16_ntfy_fini(chan, ntfy); |
diff --git a/drivers/gpu/drm/nouveau/nouveau_acpi.c b/drivers/gpu/drm/nouveau/nouveau_acpi.c index 95c740454049..ba0183fb84f3 100644 --- a/drivers/gpu/drm/nouveau/nouveau_acpi.c +++ b/drivers/gpu/drm/nouveau/nouveau_acpi.c | |||
@@ -51,6 +51,7 @@ static struct nouveau_dsm_priv { | |||
51 | bool dsm_detected; | 51 | bool dsm_detected; |
52 | bool optimus_detected; | 52 | bool optimus_detected; |
53 | acpi_handle dhandle; | 53 | acpi_handle dhandle; |
54 | acpi_handle other_handle; | ||
54 | acpi_handle rom_handle; | 55 | acpi_handle rom_handle; |
55 | } nouveau_dsm_priv; | 56 | } nouveau_dsm_priv; |
56 | 57 | ||
@@ -260,9 +261,10 @@ static int nouveau_dsm_pci_probe(struct pci_dev *pdev) | |||
260 | if (!dhandle) | 261 | if (!dhandle) |
261 | return false; | 262 | return false; |
262 | 263 | ||
263 | if (!acpi_has_method(dhandle, "_DSM")) | 264 | if (!acpi_has_method(dhandle, "_DSM")) { |
265 | nouveau_dsm_priv.other_handle = dhandle; | ||
264 | return false; | 266 | return false; |
265 | 267 | } | |
266 | if (nouveau_test_dsm(dhandle, nouveau_dsm, NOUVEAU_DSM_POWER)) | 268 | if (nouveau_test_dsm(dhandle, nouveau_dsm, NOUVEAU_DSM_POWER)) |
267 | retval |= NOUVEAU_DSM_HAS_MUX; | 269 | retval |= NOUVEAU_DSM_HAS_MUX; |
268 | 270 | ||
@@ -338,6 +340,16 @@ static bool nouveau_dsm_detect(void) | |||
338 | printk(KERN_INFO "VGA switcheroo: detected DSM switching method %s handle\n", | 340 | printk(KERN_INFO "VGA switcheroo: detected DSM switching method %s handle\n", |
339 | acpi_method_name); | 341 | acpi_method_name); |
340 | nouveau_dsm_priv.dsm_detected = true; | 342 | nouveau_dsm_priv.dsm_detected = true; |
343 | /* | ||
344 | * On some systems hotplug events are generated for the device | ||
345 | * being switched off when _DSM is executed. They cause ACPI | ||
346 | * hotplug to trigger and attempt to remove the device from | ||
347 | * the system, which causes it to break down. Prevent that from | ||
348 | * happening by setting the no_hotplug flag for the involved | ||
349 | * ACPI device objects. | ||
350 | */ | ||
351 | acpi_bus_no_hotplug(nouveau_dsm_priv.dhandle); | ||
352 | acpi_bus_no_hotplug(nouveau_dsm_priv.other_handle); | ||
341 | ret = true; | 353 | ret = true; |
342 | } | 354 | } |
343 | 355 | ||
diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c index 29c3efdfc7dd..25ea82f8def3 100644 --- a/drivers/gpu/drm/nouveau/nouveau_display.c +++ b/drivers/gpu/drm/nouveau/nouveau_display.c | |||
@@ -610,7 +610,7 @@ nouveau_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb, | |||
610 | ret = nouveau_fence_sync(fence, chan); | 610 | ret = nouveau_fence_sync(fence, chan); |
611 | nouveau_fence_unref(&fence); | 611 | nouveau_fence_unref(&fence); |
612 | if (ret) | 612 | if (ret) |
613 | return ret; | 613 | goto fail_free; |
614 | 614 | ||
615 | if (new_bo != old_bo) { | 615 | if (new_bo != old_bo) { |
616 | ret = nouveau_bo_pin(new_bo, TTM_PL_FLAG_VRAM); | 616 | ret = nouveau_bo_pin(new_bo, TTM_PL_FLAG_VRAM); |
diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c index 7a3759f1c41a..98a22e6e27a1 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drm.c +++ b/drivers/gpu/drm/nouveau/nouveau_drm.c | |||
@@ -858,6 +858,12 @@ static int nouveau_pmops_runtime_suspend(struct device *dev) | |||
858 | if (nouveau_runtime_pm == 0) | 858 | if (nouveau_runtime_pm == 0) |
859 | return -EINVAL; | 859 | return -EINVAL; |
860 | 860 | ||
861 | /* are we optimus enabled? */ | ||
862 | if (nouveau_runtime_pm == -1 && !nouveau_is_optimus() && !nouveau_is_v1_dsm()) { | ||
863 | DRM_DEBUG_DRIVER("failing to power off - not optimus\n"); | ||
864 | return -EINVAL; | ||
865 | } | ||
866 | |||
861 | nv_debug_level(SILENT); | 867 | nv_debug_level(SILENT); |
862 | drm_kms_helper_poll_disable(drm_dev); | 868 | drm_kms_helper_poll_disable(drm_dev); |
863 | vga_switcheroo_set_dynamic_switch(pdev, VGA_SWITCHEROO_OFF); | 869 | vga_switcheroo_set_dynamic_switch(pdev, VGA_SWITCHEROO_OFF); |
diff --git a/drivers/gpu/drm/qxl/Kconfig b/drivers/gpu/drm/qxl/Kconfig index 037d324bf58f..38c2bb72e456 100644 --- a/drivers/gpu/drm/qxl/Kconfig +++ b/drivers/gpu/drm/qxl/Kconfig | |||
@@ -5,8 +5,11 @@ config DRM_QXL | |||
5 | select FB_SYS_COPYAREA | 5 | select FB_SYS_COPYAREA |
6 | select FB_SYS_IMAGEBLIT | 6 | select FB_SYS_IMAGEBLIT |
7 | select FB_DEFERRED_IO | 7 | select FB_DEFERRED_IO |
8 | select DRM_KMS_HELPER | 8 | select DRM_KMS_HELPER |
9 | select DRM_KMS_FB_HELPER | 9 | select DRM_KMS_FB_HELPER |
10 | select DRM_TTM | 10 | select DRM_TTM |
11 | select CRC32 | ||
11 | help | 12 | help |
12 | QXL virtual GPU for Spice virtualization desktop integration. Do not enable this driver unless your distro ships a corresponding X.org QXL driver that can handle kernel modesetting. | 13 | QXL virtual GPU for Spice virtualization desktop integration. |
14 | Do not enable this driver unless your distro ships a corresponding | ||
15 | X.org QXL driver that can handle kernel modesetting. | ||
diff --git a/drivers/gpu/drm/qxl/qxl_display.c b/drivers/gpu/drm/qxl/qxl_display.c index 5e827c29d194..d70aafb83307 100644 --- a/drivers/gpu/drm/qxl/qxl_display.c +++ b/drivers/gpu/drm/qxl/qxl_display.c | |||
@@ -24,7 +24,7 @@ | |||
24 | */ | 24 | */ |
25 | 25 | ||
26 | 26 | ||
27 | #include "linux/crc32.h" | 27 | #include <linux/crc32.h> |
28 | 28 | ||
29 | #include "qxl_drv.h" | 29 | #include "qxl_drv.h" |
30 | #include "qxl_object.h" | 30 | #include "qxl_object.h" |
diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c index 80a20120e625..0b9621c9aeea 100644 --- a/drivers/gpu/drm/radeon/atombios_crtc.c +++ b/drivers/gpu/drm/radeon/atombios_crtc.c | |||
@@ -1143,31 +1143,53 @@ static int dce4_crtc_do_set_base(struct drm_crtc *crtc, | |||
1143 | } | 1143 | } |
1144 | 1144 | ||
1145 | if (tiling_flags & RADEON_TILING_MACRO) { | 1145 | if (tiling_flags & RADEON_TILING_MACRO) { |
1146 | if (rdev->family >= CHIP_BONAIRE) | 1146 | evergreen_tiling_fields(tiling_flags, &bankw, &bankh, &mtaspect, &tile_split); |
1147 | tmp = rdev->config.cik.tile_config; | ||
1148 | else if (rdev->family >= CHIP_TAHITI) | ||
1149 | tmp = rdev->config.si.tile_config; | ||
1150 | else if (rdev->family >= CHIP_CAYMAN) | ||
1151 | tmp = rdev->config.cayman.tile_config; | ||
1152 | else | ||
1153 | tmp = rdev->config.evergreen.tile_config; | ||
1154 | 1147 | ||
1155 | switch ((tmp & 0xf0) >> 4) { | 1148 | /* Set NUM_BANKS. */ |
1156 | case 0: /* 4 banks */ | 1149 | if (rdev->family >= CHIP_BONAIRE) { |
1157 | fb_format |= EVERGREEN_GRPH_NUM_BANKS(EVERGREEN_ADDR_SURF_4_BANK); | 1150 | unsigned tileb, index, num_banks, tile_split_bytes; |
1158 | break; | 1151 | |
1159 | case 1: /* 8 banks */ | 1152 | /* Calculate the macrotile mode index. */ |
1160 | default: | 1153 | tile_split_bytes = 64 << tile_split; |
1161 | fb_format |= EVERGREEN_GRPH_NUM_BANKS(EVERGREEN_ADDR_SURF_8_BANK); | 1154 | tileb = 8 * 8 * target_fb->bits_per_pixel / 8; |
1162 | break; | 1155 | tileb = min(tile_split_bytes, tileb); |
1163 | case 2: /* 16 banks */ | 1156 | |
1164 | fb_format |= EVERGREEN_GRPH_NUM_BANKS(EVERGREEN_ADDR_SURF_16_BANK); | 1157 | for (index = 0; tileb > 64; index++) { |
1165 | break; | 1158 | tileb >>= 1; |
1159 | } | ||
1160 | |||
1161 | if (index >= 16) { | ||
1162 | DRM_ERROR("Wrong screen bpp (%u) or tile split (%u)\n", | ||
1163 | target_fb->bits_per_pixel, tile_split); | ||
1164 | return -EINVAL; | ||
1165 | } | ||
1166 | |||
1167 | num_banks = (rdev->config.cik.macrotile_mode_array[index] >> 6) & 0x3; | ||
1168 | fb_format |= EVERGREEN_GRPH_NUM_BANKS(num_banks); | ||
1169 | } else { | ||
1170 | /* SI and older. */ | ||
1171 | if (rdev->family >= CHIP_TAHITI) | ||
1172 | tmp = rdev->config.si.tile_config; | ||
1173 | else if (rdev->family >= CHIP_CAYMAN) | ||
1174 | tmp = rdev->config.cayman.tile_config; | ||
1175 | else | ||
1176 | tmp = rdev->config.evergreen.tile_config; | ||
1177 | |||
1178 | switch ((tmp & 0xf0) >> 4) { | ||
1179 | case 0: /* 4 banks */ | ||
1180 | fb_format |= EVERGREEN_GRPH_NUM_BANKS(EVERGREEN_ADDR_SURF_4_BANK); | ||
1181 | break; | ||
1182 | case 1: /* 8 banks */ | ||
1183 | default: | ||
1184 | fb_format |= EVERGREEN_GRPH_NUM_BANKS(EVERGREEN_ADDR_SURF_8_BANK); | ||
1185 | break; | ||
1186 | case 2: /* 16 banks */ | ||
1187 | fb_format |= EVERGREEN_GRPH_NUM_BANKS(EVERGREEN_ADDR_SURF_16_BANK); | ||
1188 | break; | ||
1189 | } | ||
1166 | } | 1190 | } |
1167 | 1191 | ||
1168 | fb_format |= EVERGREEN_GRPH_ARRAY_MODE(EVERGREEN_GRPH_ARRAY_2D_TILED_THIN1); | 1192 | fb_format |= EVERGREEN_GRPH_ARRAY_MODE(EVERGREEN_GRPH_ARRAY_2D_TILED_THIN1); |
1169 | |||
1170 | evergreen_tiling_fields(tiling_flags, &bankw, &bankh, &mtaspect, &tile_split); | ||
1171 | fb_format |= EVERGREEN_GRPH_TILE_SPLIT(tile_split); | 1193 | fb_format |= EVERGREEN_GRPH_TILE_SPLIT(tile_split); |
1172 | fb_format |= EVERGREEN_GRPH_BANK_WIDTH(bankw); | 1194 | fb_format |= EVERGREEN_GRPH_BANK_WIDTH(bankw); |
1173 | fb_format |= EVERGREEN_GRPH_BANK_HEIGHT(bankh); | 1195 | fb_format |= EVERGREEN_GRPH_BANK_HEIGHT(bankh); |
@@ -1180,23 +1202,18 @@ static int dce4_crtc_do_set_base(struct drm_crtc *crtc, | |||
1180 | fb_format |= EVERGREEN_GRPH_ARRAY_MODE(EVERGREEN_GRPH_ARRAY_1D_TILED_THIN1); | 1202 | fb_format |= EVERGREEN_GRPH_ARRAY_MODE(EVERGREEN_GRPH_ARRAY_1D_TILED_THIN1); |
1181 | 1203 | ||
1182 | if (rdev->family >= CHIP_BONAIRE) { | 1204 | if (rdev->family >= CHIP_BONAIRE) { |
1183 | u32 num_pipe_configs = rdev->config.cik.max_tile_pipes; | 1205 | /* Read the pipe config from the 2D TILED SCANOUT mode. |
1184 | u32 num_rb = rdev->config.cik.max_backends_per_se; | 1206 | * It should be the same for the other modes too, but not all |
1185 | if (num_pipe_configs > 8) | 1207 | * modes set the pipe config field. */ |
1186 | num_pipe_configs = 8; | 1208 | u32 pipe_config = (rdev->config.cik.tile_mode_array[10] >> 6) & 0x1f; |
1187 | if (num_pipe_configs == 8) | 1209 | |
1188 | fb_format |= CIK_GRPH_PIPE_CONFIG(CIK_ADDR_SURF_P8_32x32_16x16); | 1210 | fb_format |= CIK_GRPH_PIPE_CONFIG(pipe_config); |
1189 | else if (num_pipe_configs == 4) { | ||
1190 | if (num_rb == 4) | ||
1191 | fb_format |= CIK_GRPH_PIPE_CONFIG(CIK_ADDR_SURF_P4_16x16); | ||
1192 | else if (num_rb < 4) | ||
1193 | fb_format |= CIK_GRPH_PIPE_CONFIG(CIK_ADDR_SURF_P4_8x16); | ||
1194 | } else if (num_pipe_configs == 2) | ||
1195 | fb_format |= CIK_GRPH_PIPE_CONFIG(CIK_ADDR_SURF_P2); | ||
1196 | } else if ((rdev->family == CHIP_TAHITI) || | 1211 | } else if ((rdev->family == CHIP_TAHITI) || |
1197 | (rdev->family == CHIP_PITCAIRN)) | 1212 | (rdev->family == CHIP_PITCAIRN)) |
1198 | fb_format |= SI_GRPH_PIPE_CONFIG(SI_ADDR_SURF_P8_32x32_8x16); | 1213 | fb_format |= SI_GRPH_PIPE_CONFIG(SI_ADDR_SURF_P8_32x32_8x16); |
1199 | else if (rdev->family == CHIP_VERDE) | 1214 | else if ((rdev->family == CHIP_VERDE) || |
1215 | (rdev->family == CHIP_OLAND) || | ||
1216 | (rdev->family == CHIP_HAINAN)) /* for completeness. HAINAN has no display hw */ | ||
1200 | fb_format |= SI_GRPH_PIPE_CONFIG(SI_ADDR_SURF_P4_8x16); | 1217 | fb_format |= SI_GRPH_PIPE_CONFIG(SI_ADDR_SURF_P4_8x16); |
1201 | 1218 | ||
1202 | switch (radeon_crtc->crtc_id) { | 1219 | switch (radeon_crtc->crtc_id) { |
diff --git a/drivers/gpu/drm/radeon/cik.c b/drivers/gpu/drm/radeon/cik.c index b43a3a3c9067..e950fabd7f5e 100644 --- a/drivers/gpu/drm/radeon/cik.c +++ b/drivers/gpu/drm/radeon/cik.c | |||
@@ -3057,7 +3057,7 @@ static u32 cik_create_bitmask(u32 bit_width) | |||
3057 | * Returns the disabled RB bitmask. | 3057 | * Returns the disabled RB bitmask. |
3058 | */ | 3058 | */ |
3059 | static u32 cik_get_rb_disabled(struct radeon_device *rdev, | 3059 | static u32 cik_get_rb_disabled(struct radeon_device *rdev, |
3060 | u32 max_rb_num, u32 se_num, | 3060 | u32 max_rb_num_per_se, |
3061 | u32 sh_per_se) | 3061 | u32 sh_per_se) |
3062 | { | 3062 | { |
3063 | u32 data, mask; | 3063 | u32 data, mask; |
@@ -3071,7 +3071,7 @@ static u32 cik_get_rb_disabled(struct radeon_device *rdev, | |||
3071 | 3071 | ||
3072 | data >>= BACKEND_DISABLE_SHIFT; | 3072 | data >>= BACKEND_DISABLE_SHIFT; |
3073 | 3073 | ||
3074 | mask = cik_create_bitmask(max_rb_num / se_num / sh_per_se); | 3074 | mask = cik_create_bitmask(max_rb_num_per_se / sh_per_se); |
3075 | 3075 | ||
3076 | return data & mask; | 3076 | return data & mask; |
3077 | } | 3077 | } |
@@ -3088,7 +3088,7 @@ static u32 cik_get_rb_disabled(struct radeon_device *rdev, | |||
3088 | */ | 3088 | */ |
3089 | static void cik_setup_rb(struct radeon_device *rdev, | 3089 | static void cik_setup_rb(struct radeon_device *rdev, |
3090 | u32 se_num, u32 sh_per_se, | 3090 | u32 se_num, u32 sh_per_se, |
3091 | u32 max_rb_num) | 3091 | u32 max_rb_num_per_se) |
3092 | { | 3092 | { |
3093 | int i, j; | 3093 | int i, j; |
3094 | u32 data, mask; | 3094 | u32 data, mask; |
@@ -3098,7 +3098,7 @@ static void cik_setup_rb(struct radeon_device *rdev, | |||
3098 | for (i = 0; i < se_num; i++) { | 3098 | for (i = 0; i < se_num; i++) { |
3099 | for (j = 0; j < sh_per_se; j++) { | 3099 | for (j = 0; j < sh_per_se; j++) { |
3100 | cik_select_se_sh(rdev, i, j); | 3100 | cik_select_se_sh(rdev, i, j); |
3101 | data = cik_get_rb_disabled(rdev, max_rb_num, se_num, sh_per_se); | 3101 | data = cik_get_rb_disabled(rdev, max_rb_num_per_se, sh_per_se); |
3102 | if (rdev->family == CHIP_HAWAII) | 3102 | if (rdev->family == CHIP_HAWAII) |
3103 | disabled_rbs |= data << ((i * sh_per_se + j) * HAWAII_RB_BITMAP_WIDTH_PER_SH); | 3103 | disabled_rbs |= data << ((i * sh_per_se + j) * HAWAII_RB_BITMAP_WIDTH_PER_SH); |
3104 | else | 3104 | else |
@@ -3108,12 +3108,14 @@ static void cik_setup_rb(struct radeon_device *rdev, | |||
3108 | cik_select_se_sh(rdev, 0xffffffff, 0xffffffff); | 3108 | cik_select_se_sh(rdev, 0xffffffff, 0xffffffff); |
3109 | 3109 | ||
3110 | mask = 1; | 3110 | mask = 1; |
3111 | for (i = 0; i < max_rb_num; i++) { | 3111 | for (i = 0; i < max_rb_num_per_se * se_num; i++) { |
3112 | if (!(disabled_rbs & mask)) | 3112 | if (!(disabled_rbs & mask)) |
3113 | enabled_rbs |= mask; | 3113 | enabled_rbs |= mask; |
3114 | mask <<= 1; | 3114 | mask <<= 1; |
3115 | } | 3115 | } |
3116 | 3116 | ||
3117 | rdev->config.cik.backend_enable_mask = enabled_rbs; | ||
3118 | |||
3117 | for (i = 0; i < se_num; i++) { | 3119 | for (i = 0; i < se_num; i++) { |
3118 | cik_select_se_sh(rdev, i, 0xffffffff); | 3120 | cik_select_se_sh(rdev, i, 0xffffffff); |
3119 | data = 0; | 3121 | data = 0; |
diff --git a/drivers/gpu/drm/radeon/cik_sdma.c b/drivers/gpu/drm/radeon/cik_sdma.c index 0300727a4f70..d08b83c6267b 100644 --- a/drivers/gpu/drm/radeon/cik_sdma.c +++ b/drivers/gpu/drm/radeon/cik_sdma.c | |||
@@ -458,7 +458,7 @@ int cik_copy_dma(struct radeon_device *rdev, | |||
458 | radeon_ring_write(ring, 0); /* src/dst endian swap */ | 458 | radeon_ring_write(ring, 0); /* src/dst endian swap */ |
459 | radeon_ring_write(ring, src_offset & 0xffffffff); | 459 | radeon_ring_write(ring, src_offset & 0xffffffff); |
460 | radeon_ring_write(ring, upper_32_bits(src_offset) & 0xffffffff); | 460 | radeon_ring_write(ring, upper_32_bits(src_offset) & 0xffffffff); |
461 | radeon_ring_write(ring, dst_offset & 0xfffffffc); | 461 | radeon_ring_write(ring, dst_offset & 0xffffffff); |
462 | radeon_ring_write(ring, upper_32_bits(dst_offset) & 0xffffffff); | 462 | radeon_ring_write(ring, upper_32_bits(dst_offset) & 0xffffffff); |
463 | src_offset += cur_size_in_bytes; | 463 | src_offset += cur_size_in_bytes; |
464 | dst_offset += cur_size_in_bytes; | 464 | dst_offset += cur_size_in_bytes; |
diff --git a/drivers/gpu/drm/radeon/dce6_afmt.c b/drivers/gpu/drm/radeon/dce6_afmt.c index de86493cbc44..713a5d359901 100644 --- a/drivers/gpu/drm/radeon/dce6_afmt.c +++ b/drivers/gpu/drm/radeon/dce6_afmt.c | |||
@@ -174,7 +174,7 @@ void dce6_afmt_write_speaker_allocation(struct drm_encoder *encoder) | |||
174 | } | 174 | } |
175 | 175 | ||
176 | sad_count = drm_edid_to_speaker_allocation(radeon_connector->edid, &sadb); | 176 | sad_count = drm_edid_to_speaker_allocation(radeon_connector->edid, &sadb); |
177 | if (sad_count < 0) { | 177 | if (sad_count <= 0) { |
178 | DRM_ERROR("Couldn't read Speaker Allocation Data Block: %d\n", sad_count); | 178 | DRM_ERROR("Couldn't read Speaker Allocation Data Block: %d\n", sad_count); |
179 | return; | 179 | return; |
180 | } | 180 | } |
@@ -235,7 +235,7 @@ void dce6_afmt_write_sad_regs(struct drm_encoder *encoder) | |||
235 | } | 235 | } |
236 | 236 | ||
237 | sad_count = drm_edid_to_sad(radeon_connector->edid, &sads); | 237 | sad_count = drm_edid_to_sad(radeon_connector->edid, &sads); |
238 | if (sad_count < 0) { | 238 | if (sad_count <= 0) { |
239 | DRM_ERROR("Couldn't read SADs: %d\n", sad_count); | 239 | DRM_ERROR("Couldn't read SADs: %d\n", sad_count); |
240 | return; | 240 | return; |
241 | } | 241 | } |
@@ -308,7 +308,9 @@ int dce6_audio_init(struct radeon_device *rdev) | |||
308 | rdev->audio.enabled = true; | 308 | rdev->audio.enabled = true; |
309 | 309 | ||
310 | if (ASIC_IS_DCE8(rdev)) | 310 | if (ASIC_IS_DCE8(rdev)) |
311 | rdev->audio.num_pins = 7; | 311 | rdev->audio.num_pins = 6; |
312 | else if (ASIC_IS_DCE61(rdev)) | ||
313 | rdev->audio.num_pins = 4; | ||
312 | else | 314 | else |
313 | rdev->audio.num_pins = 6; | 315 | rdev->audio.num_pins = 6; |
314 | 316 | ||
diff --git a/drivers/gpu/drm/radeon/evergreen_hdmi.c b/drivers/gpu/drm/radeon/evergreen_hdmi.c index aa695c4feb3d..0c6d5cef4cf1 100644 --- a/drivers/gpu/drm/radeon/evergreen_hdmi.c +++ b/drivers/gpu/drm/radeon/evergreen_hdmi.c | |||
@@ -118,7 +118,7 @@ static void dce4_afmt_write_speaker_allocation(struct drm_encoder *encoder) | |||
118 | } | 118 | } |
119 | 119 | ||
120 | sad_count = drm_edid_to_speaker_allocation(radeon_connector->edid, &sadb); | 120 | sad_count = drm_edid_to_speaker_allocation(radeon_connector->edid, &sadb); |
121 | if (sad_count < 0) { | 121 | if (sad_count <= 0) { |
122 | DRM_ERROR("Couldn't read Speaker Allocation Data Block: %d\n", sad_count); | 122 | DRM_ERROR("Couldn't read Speaker Allocation Data Block: %d\n", sad_count); |
123 | return; | 123 | return; |
124 | } | 124 | } |
@@ -173,7 +173,7 @@ static void evergreen_hdmi_write_sad_regs(struct drm_encoder *encoder) | |||
173 | } | 173 | } |
174 | 174 | ||
175 | sad_count = drm_edid_to_sad(radeon_connector->edid, &sads); | 175 | sad_count = drm_edid_to_sad(radeon_connector->edid, &sads); |
176 | if (sad_count < 0) { | 176 | if (sad_count <= 0) { |
177 | DRM_ERROR("Couldn't read SADs: %d\n", sad_count); | 177 | DRM_ERROR("Couldn't read SADs: %d\n", sad_count); |
178 | return; | 178 | return; |
179 | } | 179 | } |
diff --git a/drivers/gpu/drm/radeon/mkregtable.c b/drivers/gpu/drm/radeon/mkregtable.c index af85299f2126..4a85bb644e24 100644 --- a/drivers/gpu/drm/radeon/mkregtable.c +++ b/drivers/gpu/drm/radeon/mkregtable.c | |||
@@ -655,7 +655,7 @@ static int parser_auth(struct table *t, const char *filename) | |||
655 | 655 | ||
656 | /* first line will contain the last register | 656 | /* first line will contain the last register |
657 | * and gpu name */ | 657 | * and gpu name */ |
658 | sscanf(buf, "%s %s", gpu_name, last_reg_s); | 658 | sscanf(buf, "%9s %9s", gpu_name, last_reg_s); |
659 | t->gpu_prefix = gpu_name; | 659 | t->gpu_prefix = gpu_name; |
660 | last_reg = strtol(last_reg_s, NULL, 16); | 660 | last_reg = strtol(last_reg_s, NULL, 16); |
661 | 661 | ||
diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c index 11aab2ab54ce..f59a9e9fccf8 100644 --- a/drivers/gpu/drm/radeon/ni.c +++ b/drivers/gpu/drm/radeon/ni.c | |||
@@ -895,6 +895,10 @@ static void cayman_gpu_init(struct radeon_device *rdev) | |||
895 | (rdev->pdev->device == 0x999C)) { | 895 | (rdev->pdev->device == 0x999C)) { |
896 | rdev->config.cayman.max_simds_per_se = 6; | 896 | rdev->config.cayman.max_simds_per_se = 6; |
897 | rdev->config.cayman.max_backends_per_se = 2; | 897 | rdev->config.cayman.max_backends_per_se = 2; |
898 | rdev->config.cayman.max_hw_contexts = 8; | ||
899 | rdev->config.cayman.sx_max_export_size = 256; | ||
900 | rdev->config.cayman.sx_max_export_pos_size = 64; | ||
901 | rdev->config.cayman.sx_max_export_smx_size = 192; | ||
898 | } else if ((rdev->pdev->device == 0x9903) || | 902 | } else if ((rdev->pdev->device == 0x9903) || |
899 | (rdev->pdev->device == 0x9904) || | 903 | (rdev->pdev->device == 0x9904) || |
900 | (rdev->pdev->device == 0x990A) || | 904 | (rdev->pdev->device == 0x990A) || |
@@ -905,6 +909,10 @@ static void cayman_gpu_init(struct radeon_device *rdev) | |||
905 | (rdev->pdev->device == 0x999D)) { | 909 | (rdev->pdev->device == 0x999D)) { |
906 | rdev->config.cayman.max_simds_per_se = 4; | 910 | rdev->config.cayman.max_simds_per_se = 4; |
907 | rdev->config.cayman.max_backends_per_se = 2; | 911 | rdev->config.cayman.max_backends_per_se = 2; |
912 | rdev->config.cayman.max_hw_contexts = 8; | ||
913 | rdev->config.cayman.sx_max_export_size = 256; | ||
914 | rdev->config.cayman.sx_max_export_pos_size = 64; | ||
915 | rdev->config.cayman.sx_max_export_smx_size = 192; | ||
908 | } else if ((rdev->pdev->device == 0x9919) || | 916 | } else if ((rdev->pdev->device == 0x9919) || |
909 | (rdev->pdev->device == 0x9990) || | 917 | (rdev->pdev->device == 0x9990) || |
910 | (rdev->pdev->device == 0x9991) || | 918 | (rdev->pdev->device == 0x9991) || |
@@ -915,9 +923,17 @@ static void cayman_gpu_init(struct radeon_device *rdev) | |||
915 | (rdev->pdev->device == 0x99A0)) { | 923 | (rdev->pdev->device == 0x99A0)) { |
916 | rdev->config.cayman.max_simds_per_se = 3; | 924 | rdev->config.cayman.max_simds_per_se = 3; |
917 | rdev->config.cayman.max_backends_per_se = 1; | 925 | rdev->config.cayman.max_backends_per_se = 1; |
926 | rdev->config.cayman.max_hw_contexts = 4; | ||
927 | rdev->config.cayman.sx_max_export_size = 128; | ||
928 | rdev->config.cayman.sx_max_export_pos_size = 32; | ||
929 | rdev->config.cayman.sx_max_export_smx_size = 96; | ||
918 | } else { | 930 | } else { |
919 | rdev->config.cayman.max_simds_per_se = 2; | 931 | rdev->config.cayman.max_simds_per_se = 2; |
920 | rdev->config.cayman.max_backends_per_se = 1; | 932 | rdev->config.cayman.max_backends_per_se = 1; |
933 | rdev->config.cayman.max_hw_contexts = 4; | ||
934 | rdev->config.cayman.sx_max_export_size = 128; | ||
935 | rdev->config.cayman.sx_max_export_pos_size = 32; | ||
936 | rdev->config.cayman.sx_max_export_smx_size = 96; | ||
921 | } | 937 | } |
922 | rdev->config.cayman.max_texture_channel_caches = 2; | 938 | rdev->config.cayman.max_texture_channel_caches = 2; |
923 | rdev->config.cayman.max_gprs = 256; | 939 | rdev->config.cayman.max_gprs = 256; |
@@ -925,10 +941,6 @@ static void cayman_gpu_init(struct radeon_device *rdev) | |||
925 | rdev->config.cayman.max_gs_threads = 32; | 941 | rdev->config.cayman.max_gs_threads = 32; |
926 | rdev->config.cayman.max_stack_entries = 512; | 942 | rdev->config.cayman.max_stack_entries = 512; |
927 | rdev->config.cayman.sx_num_of_sets = 8; | 943 | rdev->config.cayman.sx_num_of_sets = 8; |
928 | rdev->config.cayman.sx_max_export_size = 256; | ||
929 | rdev->config.cayman.sx_max_export_pos_size = 64; | ||
930 | rdev->config.cayman.sx_max_export_smx_size = 192; | ||
931 | rdev->config.cayman.max_hw_contexts = 8; | ||
932 | rdev->config.cayman.sq_num_cf_insts = 2; | 944 | rdev->config.cayman.sq_num_cf_insts = 2; |
933 | 945 | ||
934 | rdev->config.cayman.sc_prim_fifo_size = 0x40; | 946 | rdev->config.cayman.sc_prim_fifo_size = 0x40; |
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index b1f990d0eaa1..45e1f447bc79 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h | |||
@@ -1940,7 +1940,7 @@ struct si_asic { | |||
1940 | unsigned sc_earlyz_tile_fifo_size; | 1940 | unsigned sc_earlyz_tile_fifo_size; |
1941 | 1941 | ||
1942 | unsigned num_tile_pipes; | 1942 | unsigned num_tile_pipes; |
1943 | unsigned num_backends_per_se; | 1943 | unsigned backend_enable_mask; |
1944 | unsigned backend_disable_mask_per_asic; | 1944 | unsigned backend_disable_mask_per_asic; |
1945 | unsigned backend_map; | 1945 | unsigned backend_map; |
1946 | unsigned num_texture_channel_caches; | 1946 | unsigned num_texture_channel_caches; |
@@ -1970,7 +1970,7 @@ struct cik_asic { | |||
1970 | unsigned sc_earlyz_tile_fifo_size; | 1970 | unsigned sc_earlyz_tile_fifo_size; |
1971 | 1971 | ||
1972 | unsigned num_tile_pipes; | 1972 | unsigned num_tile_pipes; |
1973 | unsigned num_backends_per_se; | 1973 | unsigned backend_enable_mask; |
1974 | unsigned backend_disable_mask_per_asic; | 1974 | unsigned backend_disable_mask_per_asic; |
1975 | unsigned backend_map; | 1975 | unsigned backend_map; |
1976 | unsigned num_texture_channel_caches; | 1976 | unsigned num_texture_channel_caches; |
diff --git a/drivers/gpu/drm/radeon/radeon_asic.c b/drivers/gpu/drm/radeon/radeon_asic.c index e354ce94cdd1..c0425bb6223a 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.c +++ b/drivers/gpu/drm/radeon/radeon_asic.c | |||
@@ -2021,7 +2021,7 @@ static struct radeon_asic ci_asic = { | |||
2021 | .hdmi_setmode = &evergreen_hdmi_setmode, | 2021 | .hdmi_setmode = &evergreen_hdmi_setmode, |
2022 | }, | 2022 | }, |
2023 | .copy = { | 2023 | .copy = { |
2024 | .blit = NULL, | 2024 | .blit = &cik_copy_cpdma, |
2025 | .blit_ring_index = RADEON_RING_TYPE_GFX_INDEX, | 2025 | .blit_ring_index = RADEON_RING_TYPE_GFX_INDEX, |
2026 | .dma = &cik_copy_dma, | 2026 | .dma = &cik_copy_dma, |
2027 | .dma_ring_index = R600_RING_TYPE_DMA_INDEX, | 2027 | .dma_ring_index = R600_RING_TYPE_DMA_INDEX, |
@@ -2122,7 +2122,7 @@ static struct radeon_asic kv_asic = { | |||
2122 | .hdmi_setmode = &evergreen_hdmi_setmode, | 2122 | .hdmi_setmode = &evergreen_hdmi_setmode, |
2123 | }, | 2123 | }, |
2124 | .copy = { | 2124 | .copy = { |
2125 | .blit = NULL, | 2125 | .blit = &cik_copy_cpdma, |
2126 | .blit_ring_index = RADEON_RING_TYPE_GFX_INDEX, | 2126 | .blit_ring_index = RADEON_RING_TYPE_GFX_INDEX, |
2127 | .dma = &cik_copy_dma, | 2127 | .dma = &cik_copy_dma, |
2128 | .dma_ring_index = R600_RING_TYPE_DMA_INDEX, | 2128 | .dma_ring_index = R600_RING_TYPE_DMA_INDEX, |
diff --git a/drivers/gpu/drm/radeon/radeon_atpx_handler.c b/drivers/gpu/drm/radeon/radeon_atpx_handler.c index 9d302eaeea15..485848f889f5 100644 --- a/drivers/gpu/drm/radeon/radeon_atpx_handler.c +++ b/drivers/gpu/drm/radeon/radeon_atpx_handler.c | |||
@@ -33,6 +33,7 @@ static struct radeon_atpx_priv { | |||
33 | bool atpx_detected; | 33 | bool atpx_detected; |
34 | /* handle for device - and atpx */ | 34 | /* handle for device - and atpx */ |
35 | acpi_handle dhandle; | 35 | acpi_handle dhandle; |
36 | acpi_handle other_handle; | ||
36 | struct radeon_atpx atpx; | 37 | struct radeon_atpx atpx; |
37 | } radeon_atpx_priv; | 38 | } radeon_atpx_priv; |
38 | 39 | ||
@@ -451,9 +452,10 @@ static bool radeon_atpx_pci_probe_handle(struct pci_dev *pdev) | |||
451 | return false; | 452 | return false; |
452 | 453 | ||
453 | status = acpi_get_handle(dhandle, "ATPX", &atpx_handle); | 454 | status = acpi_get_handle(dhandle, "ATPX", &atpx_handle); |
454 | if (ACPI_FAILURE(status)) | 455 | if (ACPI_FAILURE(status)) { |
456 | radeon_atpx_priv.other_handle = dhandle; | ||
455 | return false; | 457 | return false; |
456 | 458 | } | |
457 | radeon_atpx_priv.dhandle = dhandle; | 459 | radeon_atpx_priv.dhandle = dhandle; |
458 | radeon_atpx_priv.atpx.handle = atpx_handle; | 460 | radeon_atpx_priv.atpx.handle = atpx_handle; |
459 | return true; | 461 | return true; |
@@ -530,6 +532,16 @@ static bool radeon_atpx_detect(void) | |||
530 | printk(KERN_INFO "VGA switcheroo: detected switching method %s handle\n", | 532 | printk(KERN_INFO "VGA switcheroo: detected switching method %s handle\n", |
531 | acpi_method_name); | 533 | acpi_method_name); |
532 | radeon_atpx_priv.atpx_detected = true; | 534 | radeon_atpx_priv.atpx_detected = true; |
535 | /* | ||
536 | * On some systems hotplug events are generated for the device | ||
537 | * being switched off when ATPX is executed. They cause ACPI | ||
538 | * hotplug to trigger and attempt to remove the device from | ||
539 | * the system, which causes it to break down. Prevent that from | ||
540 | * happening by setting the no_hotplug flag for the involved | ||
541 | * ACPI device objects. | ||
542 | */ | ||
543 | acpi_bus_no_hotplug(radeon_atpx_priv.dhandle); | ||
544 | acpi_bus_no_hotplug(radeon_atpx_priv.other_handle); | ||
533 | return true; | 545 | return true; |
534 | } | 546 | } |
535 | return false; | 547 | return false; |
diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c index 9f5ff28864f6..db39ea36bf22 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.c +++ b/drivers/gpu/drm/radeon/radeon_drv.c | |||
@@ -77,9 +77,10 @@ | |||
77 | * 2.33.0 - Add SI tiling mode array query | 77 | * 2.33.0 - Add SI tiling mode array query |
78 | * 2.34.0 - Add CIK tiling mode array query | 78 | * 2.34.0 - Add CIK tiling mode array query |
79 | * 2.35.0 - Add CIK macrotile mode array query | 79 | * 2.35.0 - Add CIK macrotile mode array query |
80 | * 2.36.0 - Fix CIK DCE tiling setup | ||
80 | */ | 81 | */ |
81 | #define KMS_DRIVER_MAJOR 2 | 82 | #define KMS_DRIVER_MAJOR 2 |
82 | #define KMS_DRIVER_MINOR 35 | 83 | #define KMS_DRIVER_MINOR 36 |
83 | #define KMS_DRIVER_PATCHLEVEL 0 | 84 | #define KMS_DRIVER_PATCHLEVEL 0 |
84 | int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags); | 85 | int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags); |
85 | int radeon_driver_unload_kms(struct drm_device *dev); | 86 | int radeon_driver_unload_kms(struct drm_device *dev); |
@@ -508,15 +509,6 @@ static const struct file_operations radeon_driver_kms_fops = { | |||
508 | #endif | 509 | #endif |
509 | }; | 510 | }; |
510 | 511 | ||
511 | |||
512 | static void | ||
513 | radeon_pci_shutdown(struct pci_dev *pdev) | ||
514 | { | ||
515 | struct drm_device *dev = pci_get_drvdata(pdev); | ||
516 | |||
517 | radeon_driver_unload_kms(dev); | ||
518 | } | ||
519 | |||
520 | static struct drm_driver kms_driver = { | 512 | static struct drm_driver kms_driver = { |
521 | .driver_features = | 513 | .driver_features = |
522 | DRIVER_USE_AGP | | 514 | DRIVER_USE_AGP | |
@@ -586,7 +578,6 @@ static struct pci_driver radeon_kms_pci_driver = { | |||
586 | .probe = radeon_pci_probe, | 578 | .probe = radeon_pci_probe, |
587 | .remove = radeon_pci_remove, | 579 | .remove = radeon_pci_remove, |
588 | .driver.pm = &radeon_pm_ops, | 580 | .driver.pm = &radeon_pm_ops, |
589 | .shutdown = radeon_pci_shutdown, | ||
590 | }; | 581 | }; |
591 | 582 | ||
592 | static int __init radeon_init(void) | 583 | static int __init radeon_init(void) |
diff --git a/drivers/gpu/drm/radeon/radeon_kms.c b/drivers/gpu/drm/radeon/radeon_kms.c index 55d0b474bd37..21d593c0ecaf 100644 --- a/drivers/gpu/drm/radeon/radeon_kms.c +++ b/drivers/gpu/drm/radeon/radeon_kms.c | |||
@@ -461,6 +461,15 @@ int radeon_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) | |||
461 | case RADEON_INFO_SI_CP_DMA_COMPUTE: | 461 | case RADEON_INFO_SI_CP_DMA_COMPUTE: |
462 | *value = 1; | 462 | *value = 1; |
463 | break; | 463 | break; |
464 | case RADEON_INFO_SI_BACKEND_ENABLED_MASK: | ||
465 | if (rdev->family >= CHIP_BONAIRE) { | ||
466 | *value = rdev->config.cik.backend_enable_mask; | ||
467 | } else if (rdev->family >= CHIP_TAHITI) { | ||
468 | *value = rdev->config.si.backend_enable_mask; | ||
469 | } else { | ||
470 | DRM_DEBUG_KMS("BACKEND_ENABLED_MASK is si+ only!\n"); | ||
471 | } | ||
472 | break; | ||
464 | default: | 473 | default: |
465 | DRM_DEBUG_KMS("Invalid request %d\n", info->request); | 474 | DRM_DEBUG_KMS("Invalid request %d\n", info->request); |
466 | return -EINVAL; | 475 | return -EINVAL; |
diff --git a/drivers/gpu/drm/radeon/radeon_uvd.c b/drivers/gpu/drm/radeon/radeon_uvd.c index 373d088bac66..b9c0529b4a2e 100644 --- a/drivers/gpu/drm/radeon/radeon_uvd.c +++ b/drivers/gpu/drm/radeon/radeon_uvd.c | |||
@@ -473,7 +473,7 @@ static int radeon_uvd_cs_reloc(struct radeon_cs_parser *p, | |||
473 | return -EINVAL; | 473 | return -EINVAL; |
474 | } | 474 | } |
475 | 475 | ||
476 | if ((start >> 28) != (end >> 28)) { | 476 | if ((start >> 28) != ((end - 1) >> 28)) { |
477 | DRM_ERROR("reloc %LX-%LX crossing 256MB boundary!\n", | 477 | DRM_ERROR("reloc %LX-%LX crossing 256MB boundary!\n", |
478 | start, end); | 478 | start, end); |
479 | return -EINVAL; | 479 | return -EINVAL; |
diff --git a/drivers/gpu/drm/radeon/rs690.c b/drivers/gpu/drm/radeon/rs690.c index 1c560629575a..e7dab069cccf 100644 --- a/drivers/gpu/drm/radeon/rs690.c +++ b/drivers/gpu/drm/radeon/rs690.c | |||
@@ -162,6 +162,16 @@ static void rs690_mc_init(struct radeon_device *rdev) | |||
162 | base = RREG32_MC(R_000100_MCCFG_FB_LOCATION); | 162 | base = RREG32_MC(R_000100_MCCFG_FB_LOCATION); |
163 | base = G_000100_MC_FB_START(base) << 16; | 163 | base = G_000100_MC_FB_START(base) << 16; |
164 | rdev->mc.igp_sideport_enabled = radeon_atombios_sideport_present(rdev); | 164 | rdev->mc.igp_sideport_enabled = radeon_atombios_sideport_present(rdev); |
165 | /* Some boards seem to be configured for 128MB of sideport memory, | ||
166 | * but really only have 64MB. Just skip the sideport and use | ||
167 | * UMA memory. | ||
168 | */ | ||
169 | if (rdev->mc.igp_sideport_enabled && | ||
170 | (rdev->mc.real_vram_size == (384 * 1024 * 1024))) { | ||
171 | base += 128 * 1024 * 1024; | ||
172 | rdev->mc.real_vram_size -= 128 * 1024 * 1024; | ||
173 | rdev->mc.mc_vram_size = rdev->mc.real_vram_size; | ||
174 | } | ||
165 | 175 | ||
166 | /* Use K8 direct mapping for fast fb access. */ | 176 | /* Use K8 direct mapping for fast fb access. */ |
167 | rdev->fastfb_working = false; | 177 | rdev->fastfb_working = false; |
diff --git a/drivers/gpu/drm/radeon/rv770_dpm.c b/drivers/gpu/drm/radeon/rv770_dpm.c index 913b025ae9b3..374499db20c7 100644 --- a/drivers/gpu/drm/radeon/rv770_dpm.c +++ b/drivers/gpu/drm/radeon/rv770_dpm.c | |||
@@ -2328,6 +2328,12 @@ void rv770_get_engine_memory_ss(struct radeon_device *rdev) | |||
2328 | pi->mclk_ss = radeon_atombios_get_asic_ss_info(rdev, &ss, | 2328 | pi->mclk_ss = radeon_atombios_get_asic_ss_info(rdev, &ss, |
2329 | ASIC_INTERNAL_MEMORY_SS, 0); | 2329 | ASIC_INTERNAL_MEMORY_SS, 0); |
2330 | 2330 | ||
2331 | /* disable ss, causes hangs on some cayman boards */ | ||
2332 | if (rdev->family == CHIP_CAYMAN) { | ||
2333 | pi->sclk_ss = false; | ||
2334 | pi->mclk_ss = false; | ||
2335 | } | ||
2336 | |||
2331 | if (pi->sclk_ss || pi->mclk_ss) | 2337 | if (pi->sclk_ss || pi->mclk_ss) |
2332 | pi->dynamic_ss = true; | 2338 | pi->dynamic_ss = true; |
2333 | else | 2339 | else |
diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c index a36736dab5e0..85e1edfaa3be 100644 --- a/drivers/gpu/drm/radeon/si.c +++ b/drivers/gpu/drm/radeon/si.c | |||
@@ -2811,7 +2811,7 @@ static void si_setup_spi(struct radeon_device *rdev, | |||
2811 | } | 2811 | } |
2812 | 2812 | ||
2813 | static u32 si_get_rb_disabled(struct radeon_device *rdev, | 2813 | static u32 si_get_rb_disabled(struct radeon_device *rdev, |
2814 | u32 max_rb_num, u32 se_num, | 2814 | u32 max_rb_num_per_se, |
2815 | u32 sh_per_se) | 2815 | u32 sh_per_se) |
2816 | { | 2816 | { |
2817 | u32 data, mask; | 2817 | u32 data, mask; |
@@ -2825,14 +2825,14 @@ static u32 si_get_rb_disabled(struct radeon_device *rdev, | |||
2825 | 2825 | ||
2826 | data >>= BACKEND_DISABLE_SHIFT; | 2826 | data >>= BACKEND_DISABLE_SHIFT; |
2827 | 2827 | ||
2828 | mask = si_create_bitmask(max_rb_num / se_num / sh_per_se); | 2828 | mask = si_create_bitmask(max_rb_num_per_se / sh_per_se); |
2829 | 2829 | ||
2830 | return data & mask; | 2830 | return data & mask; |
2831 | } | 2831 | } |
2832 | 2832 | ||
2833 | static void si_setup_rb(struct radeon_device *rdev, | 2833 | static void si_setup_rb(struct radeon_device *rdev, |
2834 | u32 se_num, u32 sh_per_se, | 2834 | u32 se_num, u32 sh_per_se, |
2835 | u32 max_rb_num) | 2835 | u32 max_rb_num_per_se) |
2836 | { | 2836 | { |
2837 | int i, j; | 2837 | int i, j; |
2838 | u32 data, mask; | 2838 | u32 data, mask; |
@@ -2842,19 +2842,21 @@ static void si_setup_rb(struct radeon_device *rdev, | |||
2842 | for (i = 0; i < se_num; i++) { | 2842 | for (i = 0; i < se_num; i++) { |
2843 | for (j = 0; j < sh_per_se; j++) { | 2843 | for (j = 0; j < sh_per_se; j++) { |
2844 | si_select_se_sh(rdev, i, j); | 2844 | si_select_se_sh(rdev, i, j); |
2845 | data = si_get_rb_disabled(rdev, max_rb_num, se_num, sh_per_se); | 2845 | data = si_get_rb_disabled(rdev, max_rb_num_per_se, sh_per_se); |
2846 | disabled_rbs |= data << ((i * sh_per_se + j) * TAHITI_RB_BITMAP_WIDTH_PER_SH); | 2846 | disabled_rbs |= data << ((i * sh_per_se + j) * TAHITI_RB_BITMAP_WIDTH_PER_SH); |
2847 | } | 2847 | } |
2848 | } | 2848 | } |
2849 | si_select_se_sh(rdev, 0xffffffff, 0xffffffff); | 2849 | si_select_se_sh(rdev, 0xffffffff, 0xffffffff); |
2850 | 2850 | ||
2851 | mask = 1; | 2851 | mask = 1; |
2852 | for (i = 0; i < max_rb_num; i++) { | 2852 | for (i = 0; i < max_rb_num_per_se * se_num; i++) { |
2853 | if (!(disabled_rbs & mask)) | 2853 | if (!(disabled_rbs & mask)) |
2854 | enabled_rbs |= mask; | 2854 | enabled_rbs |= mask; |
2855 | mask <<= 1; | 2855 | mask <<= 1; |
2856 | } | 2856 | } |
2857 | 2857 | ||
2858 | rdev->config.si.backend_enable_mask = enabled_rbs; | ||
2859 | |||
2858 | for (i = 0; i < se_num; i++) { | 2860 | for (i = 0; i < se_num; i++) { |
2859 | si_select_se_sh(rdev, i, 0xffffffff); | 2861 | si_select_se_sh(rdev, i, 0xffffffff); |
2860 | data = 0; | 2862 | data = 0; |
diff --git a/drivers/gpu/drm/ttm/ttm_bo_util.c b/drivers/gpu/drm/ttm/ttm_bo_util.c index 15b86a94949d..406152152315 100644 --- a/drivers/gpu/drm/ttm/ttm_bo_util.c +++ b/drivers/gpu/drm/ttm/ttm_bo_util.c | |||
@@ -353,7 +353,8 @@ int ttm_bo_move_memcpy(struct ttm_buffer_object *bo, | |||
353 | * Don't move nonexistent data. Clear destination instead. | 353 | * Don't move nonexistent data. Clear destination instead. |
354 | */ | 354 | */ |
355 | if (old_iomap == NULL && | 355 | if (old_iomap == NULL && |
356 | (ttm == NULL || ttm->state == tt_unpopulated)) { | 356 | (ttm == NULL || (ttm->state == tt_unpopulated && |
357 | !(ttm->page_flags & TTM_PAGE_FLAG_SWAPPED)))) { | ||
357 | memset_io(new_iomap, 0, new_mem->num_pages*PAGE_SIZE); | 358 | memset_io(new_iomap, 0, new_mem->num_pages*PAGE_SIZE); |
358 | goto out2; | 359 | goto out2; |
359 | } | 360 | } |
diff --git a/drivers/gpu/drm/ttm/ttm_bo_vm.c b/drivers/gpu/drm/ttm/ttm_bo_vm.c index b249ab9b1eb2..6440eeac22d2 100644 --- a/drivers/gpu/drm/ttm/ttm_bo_vm.c +++ b/drivers/gpu/drm/ttm/ttm_bo_vm.c | |||
@@ -169,9 +169,9 @@ static int ttm_bo_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf) | |||
169 | } | 169 | } |
170 | 170 | ||
171 | page_offset = ((address - vma->vm_start) >> PAGE_SHIFT) + | 171 | page_offset = ((address - vma->vm_start) >> PAGE_SHIFT) + |
172 | drm_vma_node_start(&bo->vma_node) - vma->vm_pgoff; | 172 | vma->vm_pgoff - drm_vma_node_start(&bo->vma_node); |
173 | page_last = vma_pages(vma) + | 173 | page_last = vma_pages(vma) + vma->vm_pgoff - |
174 | drm_vma_node_start(&bo->vma_node) - vma->vm_pgoff; | 174 | drm_vma_node_start(&bo->vma_node); |
175 | 175 | ||
176 | if (unlikely(page_offset >= bo->num_pages)) { | 176 | if (unlikely(page_offset >= bo->num_pages)) { |
177 | retval = VM_FAULT_SIGBUS; | 177 | retval = VM_FAULT_SIGBUS; |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c index a51f48e3e917..45d5b5ab6ca9 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c | |||
@@ -68,6 +68,9 @@ int vmw_getparam_ioctl(struct drm_device *dev, void *data, | |||
68 | SVGA_FIFO_3D_HWVERSION)); | 68 | SVGA_FIFO_3D_HWVERSION)); |
69 | break; | 69 | break; |
70 | } | 70 | } |
71 | case DRM_VMW_PARAM_MAX_SURF_MEMORY: | ||
72 | param->value = dev_priv->memory_size; | ||
73 | break; | ||
71 | default: | 74 | default: |
72 | DRM_ERROR("Illegal vmwgfx get param request: %d\n", | 75 | DRM_ERROR("Illegal vmwgfx get param request: %d\n", |
73 | param->param); | 76 | param->param); |