diff options
Diffstat (limited to 'drivers/gpu')
80 files changed, 625 insertions, 298 deletions
diff --git a/drivers/gpu/drm/armada/armada_crtc.c b/drivers/gpu/drm/armada/armada_crtc.c index 9a0cc09e6653..e4a1490b42c2 100644 --- a/drivers/gpu/drm/armada/armada_crtc.c +++ b/drivers/gpu/drm/armada/armada_crtc.c | |||
| @@ -260,7 +260,7 @@ static void armada_drm_vblank_off(struct armada_crtc *dcrtc) | |||
| 260 | * Tell the DRM core that vblank IRQs aren't going to happen for | 260 | * Tell the DRM core that vblank IRQs aren't going to happen for |
| 261 | * a while. This cleans up any pending vblank events for us. | 261 | * a while. This cleans up any pending vblank events for us. |
| 262 | */ | 262 | */ |
| 263 | drm_vblank_off(dev, dcrtc->num); | 263 | drm_crtc_vblank_off(&dcrtc->crtc); |
| 264 | 264 | ||
| 265 | /* Handle any pending flip event. */ | 265 | /* Handle any pending flip event. */ |
| 266 | spin_lock_irq(&dev->event_lock); | 266 | spin_lock_irq(&dev->event_lock); |
| @@ -289,6 +289,8 @@ static void armada_drm_crtc_dpms(struct drm_crtc *crtc, int dpms) | |||
| 289 | armada_drm_crtc_update(dcrtc); | 289 | armada_drm_crtc_update(dcrtc); |
| 290 | if (dpms_blanked(dpms)) | 290 | if (dpms_blanked(dpms)) |
| 291 | armada_drm_vblank_off(dcrtc); | 291 | armada_drm_vblank_off(dcrtc); |
| 292 | else | ||
| 293 | drm_crtc_vblank_on(&dcrtc->crtc); | ||
| 292 | } | 294 | } |
| 293 | } | 295 | } |
| 294 | 296 | ||
| @@ -526,7 +528,7 @@ static int armada_drm_crtc_mode_set(struct drm_crtc *crtc, | |||
| 526 | /* Wait for pending flips to complete */ | 528 | /* Wait for pending flips to complete */ |
| 527 | wait_event(dcrtc->frame_wait, !dcrtc->frame_work); | 529 | wait_event(dcrtc->frame_wait, !dcrtc->frame_work); |
| 528 | 530 | ||
| 529 | drm_vblank_pre_modeset(crtc->dev, dcrtc->num); | 531 | drm_crtc_vblank_off(crtc); |
| 530 | 532 | ||
| 531 | crtc->mode = *adj; | 533 | crtc->mode = *adj; |
| 532 | 534 | ||
| @@ -617,7 +619,7 @@ static int armada_drm_crtc_mode_set(struct drm_crtc *crtc, | |||
| 617 | 619 | ||
| 618 | armada_drm_crtc_update(dcrtc); | 620 | armada_drm_crtc_update(dcrtc); |
| 619 | 621 | ||
| 620 | drm_vblank_post_modeset(crtc->dev, dcrtc->num); | 622 | drm_crtc_vblank_on(crtc); |
| 621 | armada_drm_crtc_finish_fb(dcrtc, old_fb, dpms_blanked(dcrtc->dpms)); | 623 | armada_drm_crtc_finish_fb(dcrtc, old_fb, dpms_blanked(dcrtc->dpms)); |
| 622 | 624 | ||
| 623 | return 0; | 625 | return 0; |
| @@ -945,18 +947,15 @@ static int armada_drm_crtc_page_flip(struct drm_crtc *crtc, | |||
| 945 | armada_reg_queue_end(work->regs, i); | 947 | armada_reg_queue_end(work->regs, i); |
| 946 | 948 | ||
| 947 | /* | 949 | /* |
| 948 | * Hold the old framebuffer for the work - DRM appears to drop our | 950 | * Ensure that we hold a reference on the new framebuffer. |
| 949 | * reference to the old framebuffer in drm_mode_page_flip_ioctl(). | 951 | * This has to match the behaviour in mode_set. |
| 950 | */ | 952 | */ |
| 951 | drm_framebuffer_reference(work->old_fb); | 953 | drm_framebuffer_reference(fb); |
| 952 | 954 | ||
| 953 | ret = armada_drm_crtc_queue_frame_work(dcrtc, work); | 955 | ret = armada_drm_crtc_queue_frame_work(dcrtc, work); |
| 954 | if (ret) { | 956 | if (ret) { |
| 955 | /* | 957 | /* Undo our reference above */ |
| 956 | * Undo our reference above; DRM does not drop the reference | 958 | drm_framebuffer_unreference(fb); |
| 957 | * to this object on error, so that's okay. | ||
| 958 | */ | ||
| 959 | drm_framebuffer_unreference(work->old_fb); | ||
| 960 | kfree(work); | 959 | kfree(work); |
| 961 | return ret; | 960 | return ret; |
| 962 | } | 961 | } |
diff --git a/drivers/gpu/drm/armada/armada_drv.c b/drivers/gpu/drm/armada/armada_drv.c index f672e6ad8afa..908e5316eac4 100644 --- a/drivers/gpu/drm/armada/armada_drv.c +++ b/drivers/gpu/drm/armada/armada_drv.c | |||
| @@ -190,6 +190,7 @@ static int armada_drm_load(struct drm_device *dev, unsigned long flags) | |||
| 190 | if (ret) | 190 | if (ret) |
| 191 | goto err_comp; | 191 | goto err_comp; |
| 192 | 192 | ||
| 193 | dev->irq_enabled = true; | ||
| 193 | dev->vblank_disable_allowed = 1; | 194 | dev->vblank_disable_allowed = 1; |
| 194 | 195 | ||
| 195 | ret = armada_fbdev_init(dev); | 196 | ret = armada_fbdev_init(dev); |
| @@ -331,7 +332,7 @@ static struct drm_driver armada_drm_driver = { | |||
| 331 | .desc = "Armada SoC DRM", | 332 | .desc = "Armada SoC DRM", |
| 332 | .date = "20120730", | 333 | .date = "20120730", |
| 333 | .driver_features = DRIVER_GEM | DRIVER_MODESET | | 334 | .driver_features = DRIVER_GEM | DRIVER_MODESET | |
| 334 | DRIVER_PRIME, | 335 | DRIVER_HAVE_IRQ | DRIVER_PRIME, |
| 335 | .ioctls = armada_ioctls, | 336 | .ioctls = armada_ioctls, |
| 336 | .fops = &armada_drm_fops, | 337 | .fops = &armada_drm_fops, |
| 337 | }; | 338 | }; |
diff --git a/drivers/gpu/drm/armada/armada_gem.c b/drivers/gpu/drm/armada/armada_gem.c index 7496f55611a5..ef5feeecec84 100644 --- a/drivers/gpu/drm/armada/armada_gem.c +++ b/drivers/gpu/drm/armada/armada_gem.c | |||
| @@ -226,7 +226,7 @@ struct armada_gem_object *armada_gem_alloc_object(struct drm_device *dev, | |||
| 226 | 226 | ||
| 227 | obj->dev_addr = DMA_ERROR_CODE; | 227 | obj->dev_addr = DMA_ERROR_CODE; |
| 228 | 228 | ||
| 229 | mapping = obj->obj.filp->f_path.dentry->d_inode->i_mapping; | 229 | mapping = file_inode(obj->obj.filp)->i_mapping; |
| 230 | mapping_set_gfp_mask(mapping, GFP_HIGHUSER | __GFP_RECLAIMABLE); | 230 | mapping_set_gfp_mask(mapping, GFP_HIGHUSER | __GFP_RECLAIMABLE); |
| 231 | 231 | ||
| 232 | DRM_DEBUG_DRIVER("alloc obj %p size %zu\n", obj, size); | 232 | DRM_DEBUG_DRIVER("alloc obj %p size %zu\n", obj, size); |
diff --git a/drivers/gpu/drm/cirrus/cirrus_drv.c b/drivers/gpu/drm/cirrus/cirrus_drv.c index e705335101a5..c2a1cba1e984 100644 --- a/drivers/gpu/drm/cirrus/cirrus_drv.c +++ b/drivers/gpu/drm/cirrus/cirrus_drv.c | |||
| @@ -32,6 +32,8 @@ static struct drm_driver driver; | |||
| 32 | static const struct pci_device_id pciidlist[] = { | 32 | static const struct pci_device_id pciidlist[] = { |
| 33 | { PCI_VENDOR_ID_CIRRUS, PCI_DEVICE_ID_CIRRUS_5446, 0x1af4, 0x1100, 0, | 33 | { PCI_VENDOR_ID_CIRRUS, PCI_DEVICE_ID_CIRRUS_5446, 0x1af4, 0x1100, 0, |
| 34 | 0, 0 }, | 34 | 0, 0 }, |
| 35 | { PCI_VENDOR_ID_CIRRUS, PCI_DEVICE_ID_CIRRUS_5446, PCI_VENDOR_ID_XEN, | ||
| 36 | 0x0001, 0, 0, 0 }, | ||
| 35 | {0,} | 37 | {0,} |
| 36 | }; | 38 | }; |
| 37 | 39 | ||
diff --git a/drivers/gpu/drm/exynos/exynos_dp_core.c b/drivers/gpu/drm/exynos/exynos_dp_core.c index cd50ece31601..6adb1e5cfb08 100644 --- a/drivers/gpu/drm/exynos/exynos_dp_core.c +++ b/drivers/gpu/drm/exynos/exynos_dp_core.c | |||
| @@ -1355,13 +1355,8 @@ static void exynos_dp_unbind(struct device *dev, struct device *master, | |||
| 1355 | void *data) | 1355 | void *data) |
| 1356 | { | 1356 | { |
| 1357 | struct exynos_drm_display *display = dev_get_drvdata(dev); | 1357 | struct exynos_drm_display *display = dev_get_drvdata(dev); |
| 1358 | struct exynos_dp_device *dp = display->ctx; | ||
| 1359 | struct drm_encoder *encoder = dp->encoder; | ||
| 1360 | 1358 | ||
| 1361 | exynos_dp_dpms(display, DRM_MODE_DPMS_OFF); | 1359 | exynos_dp_dpms(display, DRM_MODE_DPMS_OFF); |
| 1362 | |||
| 1363 | exynos_dp_connector_destroy(&dp->connector); | ||
| 1364 | encoder->funcs->destroy(encoder); | ||
| 1365 | } | 1360 | } |
| 1366 | 1361 | ||
| 1367 | static const struct component_ops exynos_dp_ops = { | 1362 | static const struct component_ops exynos_dp_ops = { |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_crtc.c b/drivers/gpu/drm/exynos/exynos_drm_crtc.c index 8e38e9f8e542..45026e693225 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_crtc.c +++ b/drivers/gpu/drm/exynos/exynos_drm_crtc.c | |||
| @@ -71,13 +71,16 @@ static void exynos_drm_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
| 71 | !atomic_read(&exynos_crtc->pending_flip), | 71 | !atomic_read(&exynos_crtc->pending_flip), |
| 72 | HZ/20)) | 72 | HZ/20)) |
| 73 | atomic_set(&exynos_crtc->pending_flip, 0); | 73 | atomic_set(&exynos_crtc->pending_flip, 0); |
| 74 | drm_vblank_off(crtc->dev, exynos_crtc->pipe); | 74 | drm_crtc_vblank_off(crtc); |
| 75 | } | 75 | } |
| 76 | 76 | ||
| 77 | if (manager->ops->dpms) | 77 | if (manager->ops->dpms) |
| 78 | manager->ops->dpms(manager, mode); | 78 | manager->ops->dpms(manager, mode); |
| 79 | 79 | ||
| 80 | exynos_crtc->dpms = mode; | 80 | exynos_crtc->dpms = mode; |
| 81 | |||
| 82 | if (mode == DRM_MODE_DPMS_ON) | ||
| 83 | drm_crtc_vblank_on(crtc); | ||
| 81 | } | 84 | } |
| 82 | 85 | ||
| 83 | static void exynos_drm_crtc_prepare(struct drm_crtc *crtc) | 86 | static void exynos_drm_crtc_prepare(struct drm_crtc *crtc) |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_dpi.c b/drivers/gpu/drm/exynos/exynos_drm_dpi.c index 96c87db388fb..3dc678ed9949 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_dpi.c +++ b/drivers/gpu/drm/exynos/exynos_drm_dpi.c | |||
| @@ -338,14 +338,10 @@ err_del_component: | |||
| 338 | 338 | ||
| 339 | int exynos_dpi_remove(struct device *dev) | 339 | int exynos_dpi_remove(struct device *dev) |
| 340 | { | 340 | { |
| 341 | struct drm_encoder *encoder = exynos_dpi_display.encoder; | ||
| 342 | struct exynos_dpi *ctx = exynos_dpi_display.ctx; | 341 | struct exynos_dpi *ctx = exynos_dpi_display.ctx; |
| 343 | 342 | ||
| 344 | exynos_dpi_dpms(&exynos_dpi_display, DRM_MODE_DPMS_OFF); | 343 | exynos_dpi_dpms(&exynos_dpi_display, DRM_MODE_DPMS_OFF); |
| 345 | 344 | ||
| 346 | exynos_dpi_connector_destroy(&ctx->connector); | ||
| 347 | encoder->funcs->destroy(encoder); | ||
| 348 | |||
| 349 | if (ctx->panel) | 345 | if (ctx->panel) |
| 350 | drm_panel_detach(ctx->panel); | 346 | drm_panel_detach(ctx->panel); |
| 351 | 347 | ||
diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c b/drivers/gpu/drm/exynos/exynos_drm_drv.c index 443a2069858a..e5c4c6c8c967 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_drv.c +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c | |||
| @@ -87,16 +87,12 @@ static int exynos_drm_load(struct drm_device *dev, unsigned long flags) | |||
| 87 | 87 | ||
| 88 | plane = exynos_plane_init(dev, possible_crtcs, | 88 | plane = exynos_plane_init(dev, possible_crtcs, |
| 89 | DRM_PLANE_TYPE_OVERLAY); | 89 | DRM_PLANE_TYPE_OVERLAY); |
| 90 | if (IS_ERR(plane)) | 90 | if (!IS_ERR(plane)) |
| 91 | goto err_mode_config_cleanup; | 91 | continue; |
| 92 | } | ||
| 93 | |||
| 94 | /* init kms poll for handling hpd */ | ||
| 95 | drm_kms_helper_poll_init(dev); | ||
| 96 | 92 | ||
| 97 | ret = drm_vblank_init(dev, MAX_CRTC); | 93 | ret = PTR_ERR(plane); |
| 98 | if (ret) | ||
| 99 | goto err_mode_config_cleanup; | 94 | goto err_mode_config_cleanup; |
| 95 | } | ||
| 100 | 96 | ||
| 101 | /* setup possible_clones. */ | 97 | /* setup possible_clones. */ |
| 102 | exynos_drm_encoder_setup(dev); | 98 | exynos_drm_encoder_setup(dev); |
| @@ -106,15 +102,16 @@ static int exynos_drm_load(struct drm_device *dev, unsigned long flags) | |||
| 106 | /* Try to bind all sub drivers. */ | 102 | /* Try to bind all sub drivers. */ |
| 107 | ret = component_bind_all(dev->dev, dev); | 103 | ret = component_bind_all(dev->dev, dev); |
| 108 | if (ret) | 104 | if (ret) |
| 109 | goto err_cleanup_vblank; | 105 | goto err_mode_config_cleanup; |
| 110 | 106 | ||
| 111 | /* Probe non kms sub drivers and virtual display driver. */ | 107 | ret = drm_vblank_init(dev, dev->mode_config.num_crtc); |
| 112 | ret = exynos_drm_device_subdrv_probe(dev); | ||
| 113 | if (ret) | 108 | if (ret) |
| 114 | goto err_unbind_all; | 109 | goto err_unbind_all; |
| 115 | 110 | ||
| 116 | /* force connectors detection */ | 111 | /* Probe non kms sub drivers and virtual display driver. */ |
| 117 | drm_helper_hpd_irq_event(dev); | 112 | ret = exynos_drm_device_subdrv_probe(dev); |
| 113 | if (ret) | ||
| 114 | goto err_cleanup_vblank; | ||
| 118 | 115 | ||
| 119 | /* | 116 | /* |
| 120 | * enable drm irq mode. | 117 | * enable drm irq mode. |
| @@ -133,12 +130,18 @@ static int exynos_drm_load(struct drm_device *dev, unsigned long flags) | |||
| 133 | */ | 130 | */ |
| 134 | dev->vblank_disable_allowed = true; | 131 | dev->vblank_disable_allowed = true; |
| 135 | 132 | ||
| 133 | /* init kms poll for handling hpd */ | ||
| 134 | drm_kms_helper_poll_init(dev); | ||
| 135 | |||
| 136 | /* force connectors detection */ | ||
| 137 | drm_helper_hpd_irq_event(dev); | ||
| 138 | |||
| 136 | return 0; | 139 | return 0; |
| 137 | 140 | ||
| 138 | err_unbind_all: | ||
| 139 | component_unbind_all(dev->dev, dev); | ||
| 140 | err_cleanup_vblank: | 141 | err_cleanup_vblank: |
| 141 | drm_vblank_cleanup(dev); | 142 | drm_vblank_cleanup(dev); |
| 143 | err_unbind_all: | ||
| 144 | component_unbind_all(dev->dev, dev); | ||
| 142 | err_mode_config_cleanup: | 145 | err_mode_config_cleanup: |
| 143 | drm_mode_config_cleanup(dev); | 146 | drm_mode_config_cleanup(dev); |
| 144 | drm_release_iommu_mapping(dev); | 147 | drm_release_iommu_mapping(dev); |
| @@ -155,8 +158,8 @@ static int exynos_drm_unload(struct drm_device *dev) | |||
| 155 | exynos_drm_fbdev_fini(dev); | 158 | exynos_drm_fbdev_fini(dev); |
| 156 | drm_kms_helper_poll_fini(dev); | 159 | drm_kms_helper_poll_fini(dev); |
| 157 | 160 | ||
| 158 | component_unbind_all(dev->dev, dev); | ||
| 159 | drm_vblank_cleanup(dev); | 161 | drm_vblank_cleanup(dev); |
| 162 | component_unbind_all(dev->dev, dev); | ||
| 160 | drm_mode_config_cleanup(dev); | 163 | drm_mode_config_cleanup(dev); |
| 161 | drm_release_iommu_mapping(dev); | 164 | drm_release_iommu_mapping(dev); |
| 162 | 165 | ||
| @@ -191,8 +194,12 @@ static int exynos_drm_resume(struct drm_device *dev) | |||
| 191 | 194 | ||
| 192 | drm_modeset_lock_all(dev); | 195 | drm_modeset_lock_all(dev); |
| 193 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { | 196 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { |
| 194 | if (connector->funcs->dpms) | 197 | if (connector->funcs->dpms) { |
| 195 | connector->funcs->dpms(connector, connector->dpms); | 198 | int dpms = connector->dpms; |
| 199 | |||
| 200 | connector->dpms = DRM_MODE_DPMS_OFF; | ||
| 201 | connector->funcs->dpms(connector, dpms); | ||
| 202 | } | ||
| 196 | } | 203 | } |
| 197 | drm_modeset_unlock_all(dev); | 204 | drm_modeset_unlock_all(dev); |
| 198 | 205 | ||
| @@ -488,6 +495,12 @@ static struct component_match *exynos_drm_match_add(struct device *dev) | |||
| 488 | 495 | ||
| 489 | mutex_lock(&drm_component_lock); | 496 | mutex_lock(&drm_component_lock); |
| 490 | 497 | ||
| 498 | /* Do not retry to probe if there is no any kms driver regitered. */ | ||
| 499 | if (list_empty(&drm_component_list)) { | ||
| 500 | mutex_unlock(&drm_component_lock); | ||
| 501 | return ERR_PTR(-ENODEV); | ||
| 502 | } | ||
| 503 | |||
| 491 | list_for_each_entry(cdev, &drm_component_list, list) { | 504 | list_for_each_entry(cdev, &drm_component_list, list) { |
| 492 | /* | 505 | /* |
| 493 | * Add components to master only in case that crtc and | 506 | * Add components to master only in case that crtc and |
| @@ -578,10 +591,21 @@ static int exynos_drm_platform_probe(struct platform_device *pdev) | |||
| 578 | goto err_unregister_mixer_drv; | 591 | goto err_unregister_mixer_drv; |
| 579 | #endif | 592 | #endif |
| 580 | 593 | ||
| 594 | match = exynos_drm_match_add(&pdev->dev); | ||
| 595 | if (IS_ERR(match)) { | ||
| 596 | ret = PTR_ERR(match); | ||
| 597 | goto err_unregister_hdmi_drv; | ||
| 598 | } | ||
| 599 | |||
| 600 | ret = component_master_add_with_match(&pdev->dev, &exynos_drm_ops, | ||
| 601 | match); | ||
| 602 | if (ret < 0) | ||
| 603 | goto err_unregister_hdmi_drv; | ||
| 604 | |||
| 581 | #ifdef CONFIG_DRM_EXYNOS_G2D | 605 | #ifdef CONFIG_DRM_EXYNOS_G2D |
| 582 | ret = platform_driver_register(&g2d_driver); | 606 | ret = platform_driver_register(&g2d_driver); |
| 583 | if (ret < 0) | 607 | if (ret < 0) |
| 584 | goto err_unregister_hdmi_drv; | 608 | goto err_del_component_master; |
| 585 | #endif | 609 | #endif |
| 586 | 610 | ||
| 587 | #ifdef CONFIG_DRM_EXYNOS_FIMC | 611 | #ifdef CONFIG_DRM_EXYNOS_FIMC |
| @@ -612,23 +636,9 @@ static int exynos_drm_platform_probe(struct platform_device *pdev) | |||
| 612 | goto err_unregister_ipp_drv; | 636 | goto err_unregister_ipp_drv; |
| 613 | #endif | 637 | #endif |
| 614 | 638 | ||
| 615 | match = exynos_drm_match_add(&pdev->dev); | ||
| 616 | if (IS_ERR(match)) { | ||
| 617 | ret = PTR_ERR(match); | ||
| 618 | goto err_unregister_resources; | ||
| 619 | } | ||
| 620 | |||
| 621 | ret = component_master_add_with_match(&pdev->dev, &exynos_drm_ops, | ||
| 622 | match); | ||
| 623 | if (ret < 0) | ||
| 624 | goto err_unregister_resources; | ||
| 625 | |||
| 626 | return ret; | 639 | return ret; |
| 627 | 640 | ||
| 628 | err_unregister_resources: | ||
| 629 | |||
| 630 | #ifdef CONFIG_DRM_EXYNOS_IPP | 641 | #ifdef CONFIG_DRM_EXYNOS_IPP |
| 631 | exynos_platform_device_ipp_unregister(); | ||
| 632 | err_unregister_ipp_drv: | 642 | err_unregister_ipp_drv: |
| 633 | platform_driver_unregister(&ipp_driver); | 643 | platform_driver_unregister(&ipp_driver); |
| 634 | err_unregister_gsc_drv: | 644 | err_unregister_gsc_drv: |
| @@ -651,9 +661,11 @@ err_unregister_g2d_drv: | |||
| 651 | 661 | ||
| 652 | #ifdef CONFIG_DRM_EXYNOS_G2D | 662 | #ifdef CONFIG_DRM_EXYNOS_G2D |
| 653 | platform_driver_unregister(&g2d_driver); | 663 | platform_driver_unregister(&g2d_driver); |
| 654 | err_unregister_hdmi_drv: | 664 | err_del_component_master: |
| 655 | #endif | 665 | #endif |
| 666 | component_master_del(&pdev->dev, &exynos_drm_ops); | ||
| 656 | 667 | ||
| 668 | err_unregister_hdmi_drv: | ||
| 657 | #ifdef CONFIG_DRM_EXYNOS_HDMI | 669 | #ifdef CONFIG_DRM_EXYNOS_HDMI |
| 658 | platform_driver_unregister(&hdmi_driver); | 670 | platform_driver_unregister(&hdmi_driver); |
| 659 | err_unregister_mixer_drv: | 671 | err_unregister_mixer_drv: |
| @@ -734,6 +746,18 @@ static int exynos_drm_init(void) | |||
| 734 | { | 746 | { |
| 735 | int ret; | 747 | int ret; |
| 736 | 748 | ||
| 749 | /* | ||
| 750 | * Register device object only in case of Exynos SoC. | ||
| 751 | * | ||
| 752 | * Below codes resolves temporarily infinite loop issue incurred | ||
| 753 | * by Exynos drm driver when using multi-platform kernel. | ||
| 754 | * So these codes will be replaced with more generic way later. | ||
| 755 | */ | ||
| 756 | if (!of_machine_is_compatible("samsung,exynos3") && | ||
| 757 | !of_machine_is_compatible("samsung,exynos4") && | ||
| 758 | !of_machine_is_compatible("samsung,exynos5")) | ||
| 759 | return -ENODEV; | ||
| 760 | |||
| 737 | exynos_drm_pdev = platform_device_register_simple("exynos-drm", -1, | 761 | exynos_drm_pdev = platform_device_register_simple("exynos-drm", -1, |
| 738 | NULL, 0); | 762 | NULL, 0); |
| 739 | if (IS_ERR(exynos_drm_pdev)) | 763 | if (IS_ERR(exynos_drm_pdev)) |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_dsi.c b/drivers/gpu/drm/exynos/exynos_drm_dsi.c index 24741d8758e8..acf7e9e39dcd 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_dsi.c +++ b/drivers/gpu/drm/exynos/exynos_drm_dsi.c | |||
| @@ -1660,13 +1660,9 @@ static void exynos_dsi_unbind(struct device *dev, struct device *master, | |||
| 1660 | void *data) | 1660 | void *data) |
| 1661 | { | 1661 | { |
| 1662 | struct exynos_dsi *dsi = exynos_dsi_display.ctx; | 1662 | struct exynos_dsi *dsi = exynos_dsi_display.ctx; |
| 1663 | struct drm_encoder *encoder = dsi->encoder; | ||
| 1664 | 1663 | ||
| 1665 | exynos_dsi_dpms(&exynos_dsi_display, DRM_MODE_DPMS_OFF); | 1664 | exynos_dsi_dpms(&exynos_dsi_display, DRM_MODE_DPMS_OFF); |
| 1666 | 1665 | ||
| 1667 | exynos_dsi_connector_destroy(&dsi->connector); | ||
| 1668 | encoder->funcs->destroy(encoder); | ||
| 1669 | |||
| 1670 | mipi_dsi_host_unregister(&dsi->dsi_host); | 1666 | mipi_dsi_host_unregister(&dsi->dsi_host); |
| 1671 | } | 1667 | } |
| 1672 | 1668 | ||
diff --git a/drivers/gpu/drm/exynos/exynos_drm_g2d.c b/drivers/gpu/drm/exynos/exynos_drm_g2d.c index df7a77d3eff8..6ff8599f6cbf 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_g2d.c +++ b/drivers/gpu/drm/exynos/exynos_drm_g2d.c | |||
| @@ -302,9 +302,12 @@ static void g2d_fini_cmdlist(struct g2d_data *g2d) | |||
| 302 | struct exynos_drm_subdrv *subdrv = &g2d->subdrv; | 302 | struct exynos_drm_subdrv *subdrv = &g2d->subdrv; |
| 303 | 303 | ||
| 304 | kfree(g2d->cmdlist_node); | 304 | kfree(g2d->cmdlist_node); |
| 305 | dma_free_attrs(subdrv->drm_dev->dev, G2D_CMDLIST_POOL_SIZE, | 305 | |
| 306 | g2d->cmdlist_pool_virt, | 306 | if (g2d->cmdlist_pool_virt && g2d->cmdlist_pool) { |
| 307 | g2d->cmdlist_pool, &g2d->cmdlist_dma_attrs); | 307 | dma_free_attrs(subdrv->drm_dev->dev, G2D_CMDLIST_POOL_SIZE, |
| 308 | g2d->cmdlist_pool_virt, | ||
| 309 | g2d->cmdlist_pool, &g2d->cmdlist_dma_attrs); | ||
| 310 | } | ||
| 308 | } | 311 | } |
| 309 | 312 | ||
| 310 | static struct g2d_cmdlist_node *g2d_get_cmdlist(struct g2d_data *g2d) | 313 | static struct g2d_cmdlist_node *g2d_get_cmdlist(struct g2d_data *g2d) |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_vidi.c b/drivers/gpu/drm/exynos/exynos_drm_vidi.c index d565207040a2..50faf913e574 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_vidi.c +++ b/drivers/gpu/drm/exynos/exynos_drm_vidi.c | |||
| @@ -630,7 +630,6 @@ static int vidi_remove(struct platform_device *pdev) | |||
| 630 | { | 630 | { |
| 631 | struct exynos_drm_manager *mgr = platform_get_drvdata(pdev); | 631 | struct exynos_drm_manager *mgr = platform_get_drvdata(pdev); |
| 632 | struct vidi_context *ctx = mgr->ctx; | 632 | struct vidi_context *ctx = mgr->ctx; |
| 633 | struct drm_encoder *encoder = ctx->encoder; | ||
| 634 | 633 | ||
| 635 | if (ctx->raw_edid != (struct edid *)fake_edid_info) { | 634 | if (ctx->raw_edid != (struct edid *)fake_edid_info) { |
| 636 | kfree(ctx->raw_edid); | 635 | kfree(ctx->raw_edid); |
| @@ -639,9 +638,6 @@ static int vidi_remove(struct platform_device *pdev) | |||
| 639 | return -EINVAL; | 638 | return -EINVAL; |
| 640 | } | 639 | } |
| 641 | 640 | ||
| 642 | encoder->funcs->destroy(encoder); | ||
| 643 | drm_connector_cleanup(&ctx->connector); | ||
| 644 | |||
| 645 | return 0; | 641 | return 0; |
| 646 | } | 642 | } |
| 647 | 643 | ||
diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c b/drivers/gpu/drm/exynos/exynos_hdmi.c index 7910fb37d9bb..563a19e62eb2 100644 --- a/drivers/gpu/drm/exynos/exynos_hdmi.c +++ b/drivers/gpu/drm/exynos/exynos_hdmi.c | |||
| @@ -2312,12 +2312,6 @@ static int hdmi_bind(struct device *dev, struct device *master, void *data) | |||
| 2312 | 2312 | ||
| 2313 | static void hdmi_unbind(struct device *dev, struct device *master, void *data) | 2313 | static void hdmi_unbind(struct device *dev, struct device *master, void *data) |
| 2314 | { | 2314 | { |
| 2315 | struct exynos_drm_display *display = get_hdmi_display(dev); | ||
| 2316 | struct drm_encoder *encoder = display->encoder; | ||
| 2317 | struct hdmi_context *hdata = display->ctx; | ||
| 2318 | |||
| 2319 | hdmi_connector_destroy(&hdata->connector); | ||
| 2320 | encoder->funcs->destroy(encoder); | ||
| 2321 | } | 2315 | } |
| 2322 | 2316 | ||
| 2323 | static const struct component_ops hdmi_component_ops = { | 2317 | static const struct component_ops hdmi_component_ops = { |
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 1403b01e8216..318ade9bb5af 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c | |||
| @@ -1670,15 +1670,17 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) | |||
| 1670 | goto out_regs; | 1670 | goto out_regs; |
| 1671 | 1671 | ||
| 1672 | if (drm_core_check_feature(dev, DRIVER_MODESET)) { | 1672 | if (drm_core_check_feature(dev, DRIVER_MODESET)) { |
| 1673 | ret = i915_kick_out_vgacon(dev_priv); | 1673 | /* WARNING: Apparently we must kick fbdev drivers before vgacon, |
| 1674 | * otherwise the vga fbdev driver falls over. */ | ||
| 1675 | ret = i915_kick_out_firmware_fb(dev_priv); | ||
| 1674 | if (ret) { | 1676 | if (ret) { |
| 1675 | DRM_ERROR("failed to remove conflicting VGA console\n"); | 1677 | DRM_ERROR("failed to remove conflicting framebuffer drivers\n"); |
| 1676 | goto out_gtt; | 1678 | goto out_gtt; |
| 1677 | } | 1679 | } |
| 1678 | 1680 | ||
| 1679 | ret = i915_kick_out_firmware_fb(dev_priv); | 1681 | ret = i915_kick_out_vgacon(dev_priv); |
| 1680 | if (ret) { | 1682 | if (ret) { |
| 1681 | DRM_ERROR("failed to remove conflicting framebuffer drivers\n"); | 1683 | DRM_ERROR("failed to remove conflicting VGA console\n"); |
| 1682 | goto out_gtt; | 1684 | goto out_gtt; |
| 1683 | } | 1685 | } |
| 1684 | } | 1686 | } |
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 055d5e7fbf12..2318b4c7a8f8 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c | |||
| @@ -986,6 +986,15 @@ static int i915_pm_freeze(struct device *dev) | |||
| 986 | return i915_drm_freeze(drm_dev); | 986 | return i915_drm_freeze(drm_dev); |
| 987 | } | 987 | } |
| 988 | 988 | ||
| 989 | static int i915_pm_freeze_late(struct device *dev) | ||
| 990 | { | ||
| 991 | struct pci_dev *pdev = to_pci_dev(dev); | ||
| 992 | struct drm_device *drm_dev = pci_get_drvdata(pdev); | ||
| 993 | struct drm_i915_private *dev_priv = drm_dev->dev_private; | ||
| 994 | |||
| 995 | return intel_suspend_complete(dev_priv); | ||
| 996 | } | ||
| 997 | |||
| 989 | static int i915_pm_thaw_early(struct device *dev) | 998 | static int i915_pm_thaw_early(struct device *dev) |
| 990 | { | 999 | { |
| 991 | struct pci_dev *pdev = to_pci_dev(dev); | 1000 | struct pci_dev *pdev = to_pci_dev(dev); |
| @@ -1570,6 +1579,7 @@ static const struct dev_pm_ops i915_pm_ops = { | |||
| 1570 | .resume_early = i915_pm_resume_early, | 1579 | .resume_early = i915_pm_resume_early, |
| 1571 | .resume = i915_pm_resume, | 1580 | .resume = i915_pm_resume, |
| 1572 | .freeze = i915_pm_freeze, | 1581 | .freeze = i915_pm_freeze, |
| 1582 | .freeze_late = i915_pm_freeze_late, | ||
| 1573 | .thaw_early = i915_pm_thaw_early, | 1583 | .thaw_early = i915_pm_thaw_early, |
| 1574 | .thaw = i915_pm_thaw, | 1584 | .thaw = i915_pm_thaw, |
| 1575 | .poweroff = i915_pm_poweroff, | 1585 | .poweroff = i915_pm_poweroff, |
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index b672b843fd5e..728938f02341 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c | |||
| @@ -1902,6 +1902,22 @@ static void bdw_setup_private_ppat(struct drm_i915_private *dev_priv) | |||
| 1902 | GEN8_PPAT(6, GEN8_PPAT_WB | GEN8_PPAT_LLCELLC | GEN8_PPAT_AGE(2)) | | 1902 | GEN8_PPAT(6, GEN8_PPAT_WB | GEN8_PPAT_LLCELLC | GEN8_PPAT_AGE(2)) | |
| 1903 | GEN8_PPAT(7, GEN8_PPAT_WB | GEN8_PPAT_LLCELLC | GEN8_PPAT_AGE(3)); | 1903 | GEN8_PPAT(7, GEN8_PPAT_WB | GEN8_PPAT_LLCELLC | GEN8_PPAT_AGE(3)); |
| 1904 | 1904 | ||
| 1905 | if (!USES_PPGTT(dev_priv->dev)) | ||
| 1906 | /* Spec: "For GGTT, there is NO pat_sel[2:0] from the entry, | ||
| 1907 | * so RTL will always use the value corresponding to | ||
| 1908 | * pat_sel = 000". | ||
| 1909 | * So let's disable cache for GGTT to avoid screen corruptions. | ||
| 1910 | * MOCS still can be used though. | ||
| 1911 | * - System agent ggtt writes (i.e. cpu gtt mmaps) already work | ||
| 1912 | * before this patch, i.e. the same uncached + snooping access | ||
| 1913 | * like on gen6/7 seems to be in effect. | ||
| 1914 | * - So this just fixes blitter/render access. Again it looks | ||
| 1915 | * like it's not just uncached access, but uncached + snooping. | ||
| 1916 | * So we can still hold onto all our assumptions wrt cpu | ||
| 1917 | * clflushing on LLC machines. | ||
| 1918 | */ | ||
| 1919 | pat = GEN8_PPAT(0, GEN8_PPAT_UC); | ||
| 1920 | |||
| 1905 | /* XXX: spec defines this as 2 distinct registers. It's unclear if a 64b | 1921 | /* XXX: spec defines this as 2 distinct registers. It's unclear if a 64b |
| 1906 | * write would work. */ | 1922 | * write would work. */ |
| 1907 | I915_WRITE(GEN8_PRIVATE_PAT, pat); | 1923 | I915_WRITE(GEN8_PRIVATE_PAT, pat); |
diff --git a/drivers/gpu/drm/i915/i915_gem_tiling.c b/drivers/gpu/drm/i915/i915_gem_tiling.c index 2cefb597df6d..2b1eaa29ada4 100644 --- a/drivers/gpu/drm/i915/i915_gem_tiling.c +++ b/drivers/gpu/drm/i915/i915_gem_tiling.c | |||
| @@ -364,22 +364,9 @@ i915_gem_set_tiling(struct drm_device *dev, void *data, | |||
| 364 | * has to also include the unfenced register the GPU uses | 364 | * has to also include the unfenced register the GPU uses |
| 365 | * whilst executing a fenced command for an untiled object. | 365 | * whilst executing a fenced command for an untiled object. |
| 366 | */ | 366 | */ |
| 367 | 367 | if (obj->map_and_fenceable && | |
| 368 | obj->map_and_fenceable = | 368 | !i915_gem_object_fence_ok(obj, args->tiling_mode)) |
| 369 | !i915_gem_obj_ggtt_bound(obj) || | 369 | ret = i915_gem_object_ggtt_unbind(obj); |
| 370 | (i915_gem_obj_ggtt_offset(obj) + | ||
| 371 | obj->base.size <= dev_priv->gtt.mappable_end && | ||
| 372 | i915_gem_object_fence_ok(obj, args->tiling_mode)); | ||
| 373 | |||
| 374 | /* Rebind if we need a change of alignment */ | ||
| 375 | if (!obj->map_and_fenceable) { | ||
| 376 | u32 unfenced_align = | ||
| 377 | i915_gem_get_gtt_alignment(dev, obj->base.size, | ||
| 378 | args->tiling_mode, | ||
| 379 | false); | ||
| 380 | if (i915_gem_obj_ggtt_offset(obj) & (unfenced_align - 1)) | ||
| 381 | ret = i915_gem_object_ggtt_unbind(obj); | ||
| 382 | } | ||
| 383 | 370 | ||
| 384 | if (ret == 0) { | 371 | if (ret == 0) { |
| 385 | obj->fence_dirty = | 372 | obj->fence_dirty = |
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 3201986bf25e..f66392b6e287 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c | |||
| @@ -1711,7 +1711,7 @@ static irqreturn_t gen8_gt_irq_handler(struct drm_device *dev, | |||
| 1711 | #define HPD_STORM_DETECT_PERIOD 1000 | 1711 | #define HPD_STORM_DETECT_PERIOD 1000 |
| 1712 | #define HPD_STORM_THRESHOLD 5 | 1712 | #define HPD_STORM_THRESHOLD 5 |
| 1713 | 1713 | ||
| 1714 | static int ilk_port_to_hotplug_shift(enum port port) | 1714 | static int pch_port_to_hotplug_shift(enum port port) |
| 1715 | { | 1715 | { |
| 1716 | switch (port) { | 1716 | switch (port) { |
| 1717 | case PORT_A: | 1717 | case PORT_A: |
| @@ -1727,7 +1727,7 @@ static int ilk_port_to_hotplug_shift(enum port port) | |||
| 1727 | } | 1727 | } |
| 1728 | } | 1728 | } |
| 1729 | 1729 | ||
| 1730 | static int g4x_port_to_hotplug_shift(enum port port) | 1730 | static int i915_port_to_hotplug_shift(enum port port) |
| 1731 | { | 1731 | { |
| 1732 | switch (port) { | 1732 | switch (port) { |
| 1733 | case PORT_A: | 1733 | case PORT_A: |
| @@ -1785,12 +1785,12 @@ static inline void intel_hpd_irq_handler(struct drm_device *dev, | |||
| 1785 | if (port && dev_priv->hpd_irq_port[port]) { | 1785 | if (port && dev_priv->hpd_irq_port[port]) { |
| 1786 | bool long_hpd; | 1786 | bool long_hpd; |
| 1787 | 1787 | ||
| 1788 | if (IS_G4X(dev)) { | 1788 | if (HAS_PCH_SPLIT(dev)) { |
| 1789 | dig_shift = g4x_port_to_hotplug_shift(port); | 1789 | dig_shift = pch_port_to_hotplug_shift(port); |
| 1790 | long_hpd = (hotplug_trigger >> dig_shift) & PORTB_HOTPLUG_LONG_DETECT; | ||
| 1791 | } else { | ||
| 1792 | dig_shift = ilk_port_to_hotplug_shift(port); | ||
| 1793 | long_hpd = (dig_hotplug_reg >> dig_shift) & PORTB_HOTPLUG_LONG_DETECT; | 1790 | long_hpd = (dig_hotplug_reg >> dig_shift) & PORTB_HOTPLUG_LONG_DETECT; |
| 1791 | } else { | ||
| 1792 | dig_shift = i915_port_to_hotplug_shift(port); | ||
| 1793 | long_hpd = (hotplug_trigger >> dig_shift) & PORTB_HOTPLUG_LONG_DETECT; | ||
| 1794 | } | 1794 | } |
| 1795 | 1795 | ||
| 1796 | DRM_DEBUG_DRIVER("digital hpd port %c - %s\n", | 1796 | DRM_DEBUG_DRIVER("digital hpd port %c - %s\n", |
| @@ -3458,12 +3458,13 @@ static void gen8_irq_reset(struct drm_device *dev) | |||
| 3458 | void gen8_irq_power_well_post_enable(struct drm_i915_private *dev_priv) | 3458 | void gen8_irq_power_well_post_enable(struct drm_i915_private *dev_priv) |
| 3459 | { | 3459 | { |
| 3460 | unsigned long irqflags; | 3460 | unsigned long irqflags; |
| 3461 | uint32_t extra_ier = GEN8_PIPE_VBLANK | GEN8_PIPE_FIFO_UNDERRUN; | ||
| 3461 | 3462 | ||
| 3462 | spin_lock_irqsave(&dev_priv->irq_lock, irqflags); | 3463 | spin_lock_irqsave(&dev_priv->irq_lock, irqflags); |
| 3463 | GEN8_IRQ_INIT_NDX(DE_PIPE, PIPE_B, dev_priv->de_irq_mask[PIPE_B], | 3464 | GEN8_IRQ_INIT_NDX(DE_PIPE, PIPE_B, dev_priv->de_irq_mask[PIPE_B], |
| 3464 | ~dev_priv->de_irq_mask[PIPE_B]); | 3465 | ~dev_priv->de_irq_mask[PIPE_B] | extra_ier); |
| 3465 | GEN8_IRQ_INIT_NDX(DE_PIPE, PIPE_C, dev_priv->de_irq_mask[PIPE_C], | 3466 | GEN8_IRQ_INIT_NDX(DE_PIPE, PIPE_C, dev_priv->de_irq_mask[PIPE_C], |
| 3466 | ~dev_priv->de_irq_mask[PIPE_C]); | 3467 | ~dev_priv->de_irq_mask[PIPE_C] | extra_ier); |
| 3467 | spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); | 3468 | spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); |
| 3468 | } | 3469 | } |
| 3469 | 3470 | ||
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 507370513f3d..9cb5c95d5898 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
| @@ -73,9 +73,6 @@ static const uint32_t intel_cursor_formats[] = { | |||
| 73 | DRM_FORMAT_ARGB8888, | 73 | DRM_FORMAT_ARGB8888, |
| 74 | }; | 74 | }; |
| 75 | 75 | ||
| 76 | #define DIV_ROUND_CLOSEST_ULL(ll, d) \ | ||
| 77 | ({ unsigned long long _tmp = (ll)+(d)/2; do_div(_tmp, d); _tmp; }) | ||
| 78 | |||
| 79 | static void intel_increase_pllclock(struct drm_device *dev, | 76 | static void intel_increase_pllclock(struct drm_device *dev, |
| 80 | enum pipe pipe); | 77 | enum pipe pipe); |
| 81 | static void intel_crtc_update_cursor(struct drm_crtc *crtc, bool on); | 78 | static void intel_crtc_update_cursor(struct drm_crtc *crtc, bool on); |
| @@ -4328,7 +4325,6 @@ static void ironlake_crtc_disable(struct drm_crtc *crtc) | |||
| 4328 | ironlake_fdi_disable(crtc); | 4325 | ironlake_fdi_disable(crtc); |
| 4329 | 4326 | ||
| 4330 | ironlake_disable_pch_transcoder(dev_priv, pipe); | 4327 | ironlake_disable_pch_transcoder(dev_priv, pipe); |
| 4331 | intel_set_pch_fifo_underrun_reporting(dev, pipe, true); | ||
| 4332 | 4328 | ||
| 4333 | if (HAS_PCH_CPT(dev)) { | 4329 | if (HAS_PCH_CPT(dev)) { |
| 4334 | /* disable TRANS_DP_CTL */ | 4330 | /* disable TRANS_DP_CTL */ |
| @@ -4392,7 +4388,6 @@ static void haswell_crtc_disable(struct drm_crtc *crtc) | |||
| 4392 | 4388 | ||
| 4393 | if (intel_crtc->config.has_pch_encoder) { | 4389 | if (intel_crtc->config.has_pch_encoder) { |
| 4394 | lpt_disable_pch_transcoder(dev_priv); | 4390 | lpt_disable_pch_transcoder(dev_priv); |
| 4395 | intel_set_pch_fifo_underrun_reporting(dev, TRANSCODER_A, true); | ||
| 4396 | intel_ddi_fdi_disable(crtc); | 4391 | intel_ddi_fdi_disable(crtc); |
| 4397 | } | 4392 | } |
| 4398 | 4393 | ||
| @@ -4588,7 +4583,7 @@ static void vlv_update_cdclk(struct drm_device *dev) | |||
| 4588 | * BSpec erroneously claims we should aim for 4MHz, but | 4583 | * BSpec erroneously claims we should aim for 4MHz, but |
| 4589 | * in fact 1MHz is the correct frequency. | 4584 | * in fact 1MHz is the correct frequency. |
| 4590 | */ | 4585 | */ |
| 4591 | I915_WRITE(GMBUSFREQ_VLV, dev_priv->vlv_cdclk_freq); | 4586 | I915_WRITE(GMBUSFREQ_VLV, DIV_ROUND_UP(dev_priv->vlv_cdclk_freq, 1000)); |
| 4592 | } | 4587 | } |
| 4593 | 4588 | ||
| 4594 | /* Adjust CDclk dividers to allow high res or save power if possible */ | 4589 | /* Adjust CDclk dividers to allow high res or save power if possible */ |
| @@ -9411,6 +9406,10 @@ static bool page_flip_finished(struct intel_crtc *crtc) | |||
| 9411 | struct drm_device *dev = crtc->base.dev; | 9406 | struct drm_device *dev = crtc->base.dev; |
| 9412 | struct drm_i915_private *dev_priv = dev->dev_private; | 9407 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 9413 | 9408 | ||
| 9409 | if (i915_reset_in_progress(&dev_priv->gpu_error) || | ||
| 9410 | crtc->reset_counter != atomic_read(&dev_priv->gpu_error.reset_counter)) | ||
| 9411 | return true; | ||
| 9412 | |||
| 9414 | /* | 9413 | /* |
| 9415 | * The relevant registers doen't exist on pre-ctg. | 9414 | * The relevant registers doen't exist on pre-ctg. |
| 9416 | * As the flip done interrupt doesn't trigger for mmio | 9415 | * As the flip done interrupt doesn't trigger for mmio |
| @@ -12357,27 +12356,36 @@ static void intel_setup_outputs(struct drm_device *dev) | |||
| 12357 | if (I915_READ(PCH_DP_D) & DP_DETECTED) | 12356 | if (I915_READ(PCH_DP_D) & DP_DETECTED) |
| 12358 | intel_dp_init(dev, PCH_DP_D, PORT_D); | 12357 | intel_dp_init(dev, PCH_DP_D, PORT_D); |
| 12359 | } else if (IS_VALLEYVIEW(dev)) { | 12358 | } else if (IS_VALLEYVIEW(dev)) { |
| 12360 | if (I915_READ(VLV_DISPLAY_BASE + GEN4_HDMIB) & SDVO_DETECTED) { | 12359 | /* |
| 12360 | * The DP_DETECTED bit is the latched state of the DDC | ||
| 12361 | * SDA pin at boot. However since eDP doesn't require DDC | ||
| 12362 | * (no way to plug in a DP->HDMI dongle) the DDC pins for | ||
| 12363 | * eDP ports may have been muxed to an alternate function. | ||
| 12364 | * Thus we can't rely on the DP_DETECTED bit alone to detect | ||
| 12365 | * eDP ports. Consult the VBT as well as DP_DETECTED to | ||
| 12366 | * detect eDP ports. | ||
| 12367 | */ | ||
| 12368 | if (I915_READ(VLV_DISPLAY_BASE + GEN4_HDMIB) & SDVO_DETECTED) | ||
| 12361 | intel_hdmi_init(dev, VLV_DISPLAY_BASE + GEN4_HDMIB, | 12369 | intel_hdmi_init(dev, VLV_DISPLAY_BASE + GEN4_HDMIB, |
| 12362 | PORT_B); | 12370 | PORT_B); |
| 12363 | if (I915_READ(VLV_DISPLAY_BASE + DP_B) & DP_DETECTED) | 12371 | if (I915_READ(VLV_DISPLAY_BASE + DP_B) & DP_DETECTED || |
| 12364 | intel_dp_init(dev, VLV_DISPLAY_BASE + DP_B, PORT_B); | 12372 | intel_dp_is_edp(dev, PORT_B)) |
| 12365 | } | 12373 | intel_dp_init(dev, VLV_DISPLAY_BASE + DP_B, PORT_B); |
| 12366 | 12374 | ||
| 12367 | if (I915_READ(VLV_DISPLAY_BASE + GEN4_HDMIC) & SDVO_DETECTED) { | 12375 | if (I915_READ(VLV_DISPLAY_BASE + GEN4_HDMIC) & SDVO_DETECTED) |
| 12368 | intel_hdmi_init(dev, VLV_DISPLAY_BASE + GEN4_HDMIC, | 12376 | intel_hdmi_init(dev, VLV_DISPLAY_BASE + GEN4_HDMIC, |
| 12369 | PORT_C); | 12377 | PORT_C); |
| 12370 | if (I915_READ(VLV_DISPLAY_BASE + DP_C) & DP_DETECTED) | 12378 | if (I915_READ(VLV_DISPLAY_BASE + DP_C) & DP_DETECTED || |
| 12371 | intel_dp_init(dev, VLV_DISPLAY_BASE + DP_C, PORT_C); | 12379 | intel_dp_is_edp(dev, PORT_C)) |
| 12372 | } | 12380 | intel_dp_init(dev, VLV_DISPLAY_BASE + DP_C, PORT_C); |
| 12373 | 12381 | ||
| 12374 | if (IS_CHERRYVIEW(dev)) { | 12382 | if (IS_CHERRYVIEW(dev)) { |
| 12375 | if (I915_READ(VLV_DISPLAY_BASE + CHV_HDMID) & SDVO_DETECTED) { | 12383 | if (I915_READ(VLV_DISPLAY_BASE + CHV_HDMID) & SDVO_DETECTED) |
| 12376 | intel_hdmi_init(dev, VLV_DISPLAY_BASE + CHV_HDMID, | 12384 | intel_hdmi_init(dev, VLV_DISPLAY_BASE + CHV_HDMID, |
| 12377 | PORT_D); | 12385 | PORT_D); |
| 12378 | if (I915_READ(VLV_DISPLAY_BASE + DP_D) & DP_DETECTED) | 12386 | /* eDP not supported on port D, so don't check VBT */ |
| 12379 | intel_dp_init(dev, VLV_DISPLAY_BASE + DP_D, PORT_D); | 12387 | if (I915_READ(VLV_DISPLAY_BASE + DP_D) & DP_DETECTED) |
| 12380 | } | 12388 | intel_dp_init(dev, VLV_DISPLAY_BASE + DP_D, PORT_D); |
| 12381 | } | 12389 | } |
| 12382 | 12390 | ||
| 12383 | intel_dsi_init(dev); | 12391 | intel_dsi_init(dev); |
| @@ -12879,6 +12887,9 @@ static struct intel_quirk intel_quirks[] = { | |||
| 12879 | /* Acer C720 Chromebook (Core i3 4005U) */ | 12887 | /* Acer C720 Chromebook (Core i3 4005U) */ |
| 12880 | { 0x0a16, 0x1025, 0x0a11, quirk_backlight_present }, | 12888 | { 0x0a16, 0x1025, 0x0a11, quirk_backlight_present }, |
| 12881 | 12889 | ||
| 12890 | /* Apple Macbook 2,1 (Core 2 T7400) */ | ||
| 12891 | { 0x27a2, 0x8086, 0x7270, quirk_backlight_present }, | ||
| 12892 | |||
| 12882 | /* Toshiba CB35 Chromebook (Celeron 2955U) */ | 12893 | /* Toshiba CB35 Chromebook (Celeron 2955U) */ |
| 12883 | { 0x0a06, 0x1179, 0x0a88, quirk_backlight_present }, | 12894 | { 0x0a06, 0x1179, 0x0a88, quirk_backlight_present }, |
| 12884 | 12895 | ||
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index f6a3fdd5589e..4bcd91757321 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c | |||
| @@ -2806,6 +2806,13 @@ intel_dp_dpcd_read_wake(struct drm_dp_aux *aux, unsigned int offset, | |||
| 2806 | ssize_t ret; | 2806 | ssize_t ret; |
| 2807 | int i; | 2807 | int i; |
| 2808 | 2808 | ||
| 2809 | /* | ||
| 2810 | * Sometime we just get the same incorrect byte repeated | ||
| 2811 | * over the entire buffer. Doing just one throw away read | ||
| 2812 | * initially seems to "solve" it. | ||
| 2813 | */ | ||
| 2814 | drm_dp_dpcd_read(aux, DP_DPCD_REV, buffer, 1); | ||
| 2815 | |||
| 2809 | for (i = 0; i < 3; i++) { | 2816 | for (i = 0; i < 3; i++) { |
| 2810 | ret = drm_dp_dpcd_read(aux, offset, buffer, size); | 2817 | ret = drm_dp_dpcd_read(aux, offset, buffer, size); |
| 2811 | if (ret == size) | 2818 | if (ret == size) |
| @@ -3724,9 +3731,10 @@ intel_dp_get_dpcd(struct intel_dp *intel_dp) | |||
| 3724 | } | 3731 | } |
| 3725 | } | 3732 | } |
| 3726 | 3733 | ||
| 3727 | /* Training Pattern 3 support */ | 3734 | /* Training Pattern 3 support, both source and sink */ |
| 3728 | if (intel_dp->dpcd[DP_DPCD_REV] >= 0x12 && | 3735 | if (intel_dp->dpcd[DP_DPCD_REV] >= 0x12 && |
| 3729 | intel_dp->dpcd[DP_MAX_LANE_COUNT] & DP_TPS3_SUPPORTED) { | 3736 | intel_dp->dpcd[DP_MAX_LANE_COUNT] & DP_TPS3_SUPPORTED && |
| 3737 | (IS_HASWELL(dev_priv) || INTEL_INFO(dev_priv)->gen >= 8)) { | ||
| 3730 | intel_dp->use_tps3 = true; | 3738 | intel_dp->use_tps3 = true; |
| 3731 | DRM_DEBUG_KMS("Displayport TPS3 supported\n"); | 3739 | DRM_DEBUG_KMS("Displayport TPS3 supported\n"); |
| 3732 | } else | 3740 | } else |
| @@ -4442,6 +4450,7 @@ static void intel_dp_encoder_suspend(struct intel_encoder *intel_encoder) | |||
| 4442 | * vdd might still be enabled do to the delayed vdd off. | 4450 | * vdd might still be enabled do to the delayed vdd off. |
| 4443 | * Make sure vdd is actually turned off here. | 4451 | * Make sure vdd is actually turned off here. |
| 4444 | */ | 4452 | */ |
| 4453 | cancel_delayed_work_sync(&intel_dp->panel_vdd_work); | ||
| 4445 | pps_lock(intel_dp); | 4454 | pps_lock(intel_dp); |
| 4446 | edp_panel_vdd_off_sync(intel_dp); | 4455 | edp_panel_vdd_off_sync(intel_dp); |
| 4447 | pps_unlock(intel_dp); | 4456 | pps_unlock(intel_dp); |
| @@ -4491,6 +4500,18 @@ intel_dp_hpd_pulse(struct intel_digital_port *intel_dig_port, bool long_hpd) | |||
| 4491 | if (intel_dig_port->base.type != INTEL_OUTPUT_EDP) | 4500 | if (intel_dig_port->base.type != INTEL_OUTPUT_EDP) |
| 4492 | intel_dig_port->base.type = INTEL_OUTPUT_DISPLAYPORT; | 4501 | intel_dig_port->base.type = INTEL_OUTPUT_DISPLAYPORT; |
| 4493 | 4502 | ||
| 4503 | if (long_hpd && intel_dig_port->base.type == INTEL_OUTPUT_EDP) { | ||
| 4504 | /* | ||
| 4505 | * vdd off can generate a long pulse on eDP which | ||
| 4506 | * would require vdd on to handle it, and thus we | ||
| 4507 | * would end up in an endless cycle of | ||
| 4508 | * "vdd off -> long hpd -> vdd on -> detect -> vdd off -> ..." | ||
| 4509 | */ | ||
| 4510 | DRM_DEBUG_KMS("ignoring long hpd on eDP port %c\n", | ||
| 4511 | port_name(intel_dig_port->port)); | ||
| 4512 | return false; | ||
| 4513 | } | ||
| 4514 | |||
| 4494 | DRM_DEBUG_KMS("got hpd irq on port %c - %s\n", | 4515 | DRM_DEBUG_KMS("got hpd irq on port %c - %s\n", |
| 4495 | port_name(intel_dig_port->port), | 4516 | port_name(intel_dig_port->port), |
| 4496 | long_hpd ? "long" : "short"); | 4517 | long_hpd ? "long" : "short"); |
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 07ce04683c30..ba715229a540 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h | |||
| @@ -35,6 +35,9 @@ | |||
| 35 | #include <drm/drm_fb_helper.h> | 35 | #include <drm/drm_fb_helper.h> |
| 36 | #include <drm/drm_dp_mst_helper.h> | 36 | #include <drm/drm_dp_mst_helper.h> |
| 37 | 37 | ||
| 38 | #define DIV_ROUND_CLOSEST_ULL(ll, d) \ | ||
| 39 | ({ unsigned long long _tmp = (ll)+(d)/2; do_div(_tmp, d); _tmp; }) | ||
| 40 | |||
| 38 | /** | 41 | /** |
| 39 | * _wait_for - magic (register) wait macro | 42 | * _wait_for - magic (register) wait macro |
| 40 | * | 43 | * |
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index a6bd1422e38f..c0bbf2172446 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c | |||
| @@ -899,6 +899,17 @@ void intel_lvds_init(struct drm_device *dev) | |||
| 899 | int pipe; | 899 | int pipe; |
| 900 | u8 pin; | 900 | u8 pin; |
| 901 | 901 | ||
| 902 | /* | ||
| 903 | * Unlock registers and just leave them unlocked. Do this before | ||
| 904 | * checking quirk lists to avoid bogus WARNINGs. | ||
| 905 | */ | ||
| 906 | if (HAS_PCH_SPLIT(dev)) { | ||
| 907 | I915_WRITE(PCH_PP_CONTROL, | ||
| 908 | I915_READ(PCH_PP_CONTROL) | PANEL_UNLOCK_REGS); | ||
| 909 | } else { | ||
| 910 | I915_WRITE(PP_CONTROL, | ||
| 911 | I915_READ(PP_CONTROL) | PANEL_UNLOCK_REGS); | ||
| 912 | } | ||
| 902 | if (!intel_lvds_supported(dev)) | 913 | if (!intel_lvds_supported(dev)) |
| 903 | return; | 914 | return; |
| 904 | 915 | ||
| @@ -1097,17 +1108,6 @@ out: | |||
| 1097 | lvds_encoder->a3_power = I915_READ(lvds_encoder->reg) & | 1108 | lvds_encoder->a3_power = I915_READ(lvds_encoder->reg) & |
| 1098 | LVDS_A3_POWER_MASK; | 1109 | LVDS_A3_POWER_MASK; |
| 1099 | 1110 | ||
| 1100 | /* | ||
| 1101 | * Unlock registers and just | ||
| 1102 | * leave them unlocked | ||
| 1103 | */ | ||
| 1104 | if (HAS_PCH_SPLIT(dev)) { | ||
| 1105 | I915_WRITE(PCH_PP_CONTROL, | ||
| 1106 | I915_READ(PCH_PP_CONTROL) | PANEL_UNLOCK_REGS); | ||
| 1107 | } else { | ||
| 1108 | I915_WRITE(PP_CONTROL, | ||
| 1109 | I915_READ(PP_CONTROL) | PANEL_UNLOCK_REGS); | ||
| 1110 | } | ||
| 1111 | lvds_connector->lid_notifier.notifier_call = intel_lid_notify; | 1111 | lvds_connector->lid_notifier.notifier_call = intel_lid_notify; |
| 1112 | if (acpi_lid_notifier_register(&lvds_connector->lid_notifier)) { | 1112 | if (acpi_lid_notifier_register(&lvds_connector->lid_notifier)) { |
| 1113 | DRM_DEBUG_KMS("lid notifier registration failed\n"); | 1113 | DRM_DEBUG_KMS("lid notifier registration failed\n"); |
diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c index 18784470a760..41b3be217493 100644 --- a/drivers/gpu/drm/i915/intel_panel.c +++ b/drivers/gpu/drm/i915/intel_panel.c | |||
| @@ -419,9 +419,8 @@ static uint32_t scale(uint32_t source_val, | |||
| 419 | source_val = clamp(source_val, source_min, source_max); | 419 | source_val = clamp(source_val, source_min, source_max); |
| 420 | 420 | ||
| 421 | /* avoid overflows */ | 421 | /* avoid overflows */ |
| 422 | target_val = (uint64_t)(source_val - source_min) * | 422 | target_val = DIV_ROUND_CLOSEST_ULL((uint64_t)(source_val - source_min) * |
| 423 | (target_max - target_min); | 423 | (target_max - target_min), source_max - source_min); |
| 424 | do_div(target_val, source_max - source_min); | ||
| 425 | target_val += target_min; | 424 | target_val += target_min; |
| 426 | 425 | ||
| 427 | return target_val; | 426 | return target_val; |
| @@ -1099,12 +1098,25 @@ static u32 get_backlight_min_vbt(struct intel_connector *connector) | |||
| 1099 | struct drm_device *dev = connector->base.dev; | 1098 | struct drm_device *dev = connector->base.dev; |
| 1100 | struct drm_i915_private *dev_priv = dev->dev_private; | 1099 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 1101 | struct intel_panel *panel = &connector->panel; | 1100 | struct intel_panel *panel = &connector->panel; |
| 1101 | int min; | ||
| 1102 | 1102 | ||
| 1103 | WARN_ON(panel->backlight.max == 0); | 1103 | WARN_ON(panel->backlight.max == 0); |
| 1104 | 1104 | ||
| 1105 | /* | ||
| 1106 | * XXX: If the vbt value is 255, it makes min equal to max, which leads | ||
| 1107 | * to problems. There are such machines out there. Either our | ||
| 1108 | * interpretation is wrong or the vbt has bogus data. Or both. Safeguard | ||
| 1109 | * against this by letting the minimum be at most (arbitrarily chosen) | ||
| 1110 | * 25% of the max. | ||
| 1111 | */ | ||
| 1112 | min = clamp_t(int, dev_priv->vbt.backlight.min_brightness, 0, 64); | ||
| 1113 | if (min != dev_priv->vbt.backlight.min_brightness) { | ||
| 1114 | DRM_DEBUG_KMS("clamping VBT min backlight %d/255 to %d/255\n", | ||
| 1115 | dev_priv->vbt.backlight.min_brightness, min); | ||
| 1116 | } | ||
| 1117 | |||
| 1105 | /* vbt value is a coefficient in range [0..255] */ | 1118 | /* vbt value is a coefficient in range [0..255] */ |
| 1106 | return scale(dev_priv->vbt.backlight.min_brightness, 0, 255, | 1119 | return scale(min, 0, 255, 0, panel->backlight.max); |
| 1107 | 0, panel->backlight.max); | ||
| 1108 | } | 1120 | } |
| 1109 | 1121 | ||
| 1110 | static int bdw_setup_backlight(struct intel_connector *connector) | 1122 | static int bdw_setup_backlight(struct intel_connector *connector) |
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index c27b6140bfd1..ad2fd605f76b 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c | |||
| @@ -5469,11 +5469,6 @@ static void gen6_init_clock_gating(struct drm_device *dev) | |||
| 5469 | I915_WRITE(_3D_CHICKEN, | 5469 | I915_WRITE(_3D_CHICKEN, |
| 5470 | _MASKED_BIT_ENABLE(_3D_CHICKEN_HIZ_PLANE_DISABLE_MSAA_4X_SNB)); | 5470 | _MASKED_BIT_ENABLE(_3D_CHICKEN_HIZ_PLANE_DISABLE_MSAA_4X_SNB)); |
| 5471 | 5471 | ||
| 5472 | /* WaSetupGtModeTdRowDispatch:snb */ | ||
| 5473 | if (IS_SNB_GT1(dev)) | ||
| 5474 | I915_WRITE(GEN6_GT_MODE, | ||
| 5475 | _MASKED_BIT_ENABLE(GEN6_TD_FOUR_ROW_DISPATCH_DISABLE)); | ||
| 5476 | |||
| 5477 | /* WaDisable_RenderCache_OperationalFlush:snb */ | 5472 | /* WaDisable_RenderCache_OperationalFlush:snb */ |
| 5478 | I915_WRITE(CACHE_MODE_0, _MASKED_BIT_DISABLE(RC_OP_FLUSH_ENABLE)); | 5473 | I915_WRITE(CACHE_MODE_0, _MASKED_BIT_DISABLE(RC_OP_FLUSH_ENABLE)); |
| 5479 | 5474 | ||
diff --git a/drivers/gpu/drm/nouveau/core/engine/device/nvc0.c b/drivers/gpu/drm/nouveau/core/engine/device/nvc0.c index cd05677ad4b7..72a40f95d048 100644 --- a/drivers/gpu/drm/nouveau/core/engine/device/nvc0.c +++ b/drivers/gpu/drm/nouveau/core/engine/device/nvc0.c | |||
| @@ -218,7 +218,6 @@ nvc0_identify(struct nouveau_device *device) | |||
| 218 | device->oclass[NVDEV_ENGINE_BSP ] = &nvc0_bsp_oclass; | 218 | device->oclass[NVDEV_ENGINE_BSP ] = &nvc0_bsp_oclass; |
| 219 | device->oclass[NVDEV_ENGINE_PPP ] = &nvc0_ppp_oclass; | 219 | device->oclass[NVDEV_ENGINE_PPP ] = &nvc0_ppp_oclass; |
| 220 | device->oclass[NVDEV_ENGINE_COPY0 ] = &nvc0_copy0_oclass; | 220 | device->oclass[NVDEV_ENGINE_COPY0 ] = &nvc0_copy0_oclass; |
| 221 | device->oclass[NVDEV_ENGINE_COPY1 ] = &nvc0_copy1_oclass; | ||
| 222 | device->oclass[NVDEV_ENGINE_DISP ] = nva3_disp_oclass; | 221 | device->oclass[NVDEV_ENGINE_DISP ] = nva3_disp_oclass; |
| 223 | device->oclass[NVDEV_ENGINE_PERFMON] = &nvc0_perfmon_oclass; | 222 | device->oclass[NVDEV_ENGINE_PERFMON] = &nvc0_perfmon_oclass; |
| 224 | break; | 223 | break; |
diff --git a/drivers/gpu/drm/nouveau/core/engine/fifo/nv04.c b/drivers/gpu/drm/nouveau/core/engine/fifo/nv04.c index 5ae6a43893b5..1931057f9962 100644 --- a/drivers/gpu/drm/nouveau/core/engine/fifo/nv04.c +++ b/drivers/gpu/drm/nouveau/core/engine/fifo/nv04.c | |||
| @@ -551,8 +551,8 @@ nv04_fifo_intr(struct nouveau_subdev *subdev) | |||
| 551 | } | 551 | } |
| 552 | 552 | ||
| 553 | if (status & 0x40000000) { | 553 | if (status & 0x40000000) { |
| 554 | nouveau_fifo_uevent(&priv->base); | ||
| 555 | nv_wr32(priv, 0x002100, 0x40000000); | 554 | nv_wr32(priv, 0x002100, 0x40000000); |
| 555 | nouveau_fifo_uevent(&priv->base); | ||
| 556 | status &= ~0x40000000; | 556 | status &= ~0x40000000; |
| 557 | } | 557 | } |
| 558 | } | 558 | } |
diff --git a/drivers/gpu/drm/nouveau/core/engine/fifo/nvc0.c b/drivers/gpu/drm/nouveau/core/engine/fifo/nvc0.c index 1fe1f8fbda0c..074d434c3077 100644 --- a/drivers/gpu/drm/nouveau/core/engine/fifo/nvc0.c +++ b/drivers/gpu/drm/nouveau/core/engine/fifo/nvc0.c | |||
| @@ -740,6 +740,8 @@ nvc0_fifo_intr_engine_unit(struct nvc0_fifo_priv *priv, int engn) | |||
| 740 | u32 inte = nv_rd32(priv, 0x002628); | 740 | u32 inte = nv_rd32(priv, 0x002628); |
| 741 | u32 unkn; | 741 | u32 unkn; |
| 742 | 742 | ||
| 743 | nv_wr32(priv, 0x0025a8 + (engn * 0x04), intr); | ||
| 744 | |||
| 743 | for (unkn = 0; unkn < 8; unkn++) { | 745 | for (unkn = 0; unkn < 8; unkn++) { |
| 744 | u32 ints = (intr >> (unkn * 0x04)) & inte; | 746 | u32 ints = (intr >> (unkn * 0x04)) & inte; |
| 745 | if (ints & 0x1) { | 747 | if (ints & 0x1) { |
| @@ -751,8 +753,6 @@ nvc0_fifo_intr_engine_unit(struct nvc0_fifo_priv *priv, int engn) | |||
| 751 | nv_mask(priv, 0x002628, ints, 0); | 753 | nv_mask(priv, 0x002628, ints, 0); |
| 752 | } | 754 | } |
| 753 | } | 755 | } |
| 754 | |||
| 755 | nv_wr32(priv, 0x0025a8 + (engn * 0x04), intr); | ||
| 756 | } | 756 | } |
| 757 | 757 | ||
| 758 | static void | 758 | static void |
diff --git a/drivers/gpu/drm/nouveau/core/engine/fifo/nve0.c b/drivers/gpu/drm/nouveau/core/engine/fifo/nve0.c index d2f0fd39c145..f8734eb74eaa 100644 --- a/drivers/gpu/drm/nouveau/core/engine/fifo/nve0.c +++ b/drivers/gpu/drm/nouveau/core/engine/fifo/nve0.c | |||
| @@ -952,8 +952,8 @@ nve0_fifo_intr(struct nouveau_subdev *subdev) | |||
| 952 | } | 952 | } |
| 953 | 953 | ||
| 954 | if (stat & 0x80000000) { | 954 | if (stat & 0x80000000) { |
| 955 | nve0_fifo_intr_engine(priv); | ||
| 956 | nv_wr32(priv, 0x002100, 0x80000000); | 955 | nv_wr32(priv, 0x002100, 0x80000000); |
| 956 | nve0_fifo_intr_engine(priv); | ||
| 957 | stat &= ~0x80000000; | 957 | stat &= ~0x80000000; |
| 958 | } | 958 | } |
| 959 | 959 | ||
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/ctxnv50.c b/drivers/gpu/drm/nouveau/core/engine/graph/ctxnv50.c index 552fdbd45ebe..1d0e33fb5f61 100644 --- a/drivers/gpu/drm/nouveau/core/engine/graph/ctxnv50.c +++ b/drivers/gpu/drm/nouveau/core/engine/graph/ctxnv50.c | |||
| @@ -113,6 +113,8 @@ | |||
| 113 | #define IS_NVA3F(x) (((x) > 0xa0 && (x) < 0xaa) || (x) == 0xaf) | 113 | #define IS_NVA3F(x) (((x) > 0xa0 && (x) < 0xaa) || (x) == 0xaf) |
| 114 | #define IS_NVAAF(x) ((x) >= 0xaa && (x) <= 0xac) | 114 | #define IS_NVAAF(x) ((x) >= 0xaa && (x) <= 0xac) |
| 115 | 115 | ||
| 116 | #include <subdev/fb.h> | ||
| 117 | |||
| 116 | /* | 118 | /* |
| 117 | * This code deals with PGRAPH contexts on NV50 family cards. Like NV40, it's | 119 | * This code deals with PGRAPH contexts on NV50 family cards. Like NV40, it's |
| 118 | * the GPU itself that does context-switching, but it needs a special | 120 | * the GPU itself that does context-switching, but it needs a special |
| @@ -569,8 +571,12 @@ nv50_graph_construct_mmio(struct nouveau_grctx *ctx) | |||
| 569 | gr_def(ctx, 0x407d08, 0x00010040); | 571 | gr_def(ctx, 0x407d08, 0x00010040); |
| 570 | else if (device->chipset < 0xa0) | 572 | else if (device->chipset < 0xa0) |
| 571 | gr_def(ctx, 0x407d08, 0x00390040); | 573 | gr_def(ctx, 0x407d08, 0x00390040); |
| 572 | else | 574 | else { |
| 573 | gr_def(ctx, 0x407d08, 0x003d0040); | 575 | if (nouveau_fb(device)->ram->type != NV_MEM_TYPE_GDDR5) |
| 576 | gr_def(ctx, 0x407d08, 0x003d0040); | ||
| 577 | else | ||
| 578 | gr_def(ctx, 0x407d08, 0x003c0040); | ||
| 579 | } | ||
| 574 | gr_def(ctx, 0x407d0c, 0x00000022); | 580 | gr_def(ctx, 0x407d0c, 0x00000022); |
| 575 | } | 581 | } |
| 576 | 582 | ||
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/gk20a.c b/drivers/gpu/drm/nouveau/core/subdev/fb/gk20a.c index a16024a74771..fde42e4d1b56 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/fb/gk20a.c +++ b/drivers/gpu/drm/nouveau/core/subdev/fb/gk20a.c | |||
| @@ -27,6 +27,20 @@ struct gk20a_fb_priv { | |||
| 27 | }; | 27 | }; |
| 28 | 28 | ||
| 29 | static int | 29 | static int |
| 30 | gk20a_fb_init(struct nouveau_object *object) | ||
| 31 | { | ||
| 32 | struct gk20a_fb_priv *priv = (void *)object; | ||
| 33 | int ret; | ||
| 34 | |||
| 35 | ret = nouveau_fb_init(&priv->base); | ||
| 36 | if (ret) | ||
| 37 | return ret; | ||
| 38 | |||
| 39 | nv_mask(priv, 0x100c80, 0x00000001, 0x00000000); /* 128KiB lpg */ | ||
| 40 | return 0; | ||
| 41 | } | ||
| 42 | |||
| 43 | static int | ||
| 30 | gk20a_fb_ctor(struct nouveau_object *parent, struct nouveau_object *engine, | 44 | gk20a_fb_ctor(struct nouveau_object *parent, struct nouveau_object *engine, |
| 31 | struct nouveau_oclass *oclass, void *data, u32 size, | 45 | struct nouveau_oclass *oclass, void *data, u32 size, |
| 32 | struct nouveau_object **pobject) | 46 | struct nouveau_object **pobject) |
| @@ -48,7 +62,7 @@ gk20a_fb_oclass = &(struct nouveau_fb_impl) { | |||
| 48 | .base.ofuncs = &(struct nouveau_ofuncs) { | 62 | .base.ofuncs = &(struct nouveau_ofuncs) { |
| 49 | .ctor = gk20a_fb_ctor, | 63 | .ctor = gk20a_fb_ctor, |
| 50 | .dtor = _nouveau_fb_dtor, | 64 | .dtor = _nouveau_fb_dtor, |
| 51 | .init = _nouveau_fb_init, | 65 | .init = gk20a_fb_init, |
| 52 | .fini = _nouveau_fb_fini, | 66 | .fini = _nouveau_fb_fini, |
| 53 | }, | 67 | }, |
| 54 | .memtype = nvc0_fb_memtype_valid, | 68 | .memtype = nvc0_fb_memtype_valid, |
diff --git a/drivers/gpu/drm/nouveau/nouveau_chan.c b/drivers/gpu/drm/nouveau/nouveau_chan.c index 589dbb582da2..fd3dbd59d73e 100644 --- a/drivers/gpu/drm/nouveau/nouveau_chan.c +++ b/drivers/gpu/drm/nouveau/nouveau_chan.c | |||
| @@ -400,15 +400,20 @@ nouveau_channel_new(struct nouveau_drm *drm, struct nvif_device *device, | |||
| 400 | struct nouveau_channel **pchan) | 400 | struct nouveau_channel **pchan) |
| 401 | { | 401 | { |
| 402 | struct nouveau_cli *cli = (void *)nvif_client(&device->base); | 402 | struct nouveau_cli *cli = (void *)nvif_client(&device->base); |
| 403 | bool super; | ||
| 403 | int ret; | 404 | int ret; |
| 404 | 405 | ||
| 406 | /* hack until fencenv50 is fixed, and agp access relaxed */ | ||
| 407 | super = cli->base.super; | ||
| 408 | cli->base.super = true; | ||
| 409 | |||
| 405 | ret = nouveau_channel_ind(drm, device, handle, arg0, pchan); | 410 | ret = nouveau_channel_ind(drm, device, handle, arg0, pchan); |
| 406 | if (ret) { | 411 | if (ret) { |
| 407 | NV_PRINTK(debug, cli, "ib channel create, %d\n", ret); | 412 | NV_PRINTK(debug, cli, "ib channel create, %d\n", ret); |
| 408 | ret = nouveau_channel_dma(drm, device, handle, pchan); | 413 | ret = nouveau_channel_dma(drm, device, handle, pchan); |
| 409 | if (ret) { | 414 | if (ret) { |
| 410 | NV_PRINTK(debug, cli, "dma channel create, %d\n", ret); | 415 | NV_PRINTK(debug, cli, "dma channel create, %d\n", ret); |
| 411 | return ret; | 416 | goto done; |
| 412 | } | 417 | } |
| 413 | } | 418 | } |
| 414 | 419 | ||
| @@ -416,8 +421,9 @@ nouveau_channel_new(struct nouveau_drm *drm, struct nvif_device *device, | |||
| 416 | if (ret) { | 421 | if (ret) { |
| 417 | NV_PRINTK(error, cli, "channel failed to initialise, %d\n", ret); | 422 | NV_PRINTK(error, cli, "channel failed to initialise, %d\n", ret); |
| 418 | nouveau_channel_del(pchan); | 423 | nouveau_channel_del(pchan); |
| 419 | return ret; | ||
| 420 | } | 424 | } |
| 421 | 425 | ||
| 422 | return 0; | 426 | done: |
| 427 | cli->base.super = super; | ||
| 428 | return ret; | ||
| 423 | } | 429 | } |
diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c index 57238076049f..62b97c4eef8d 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drm.c +++ b/drivers/gpu/drm/nouveau/nouveau_drm.c | |||
| @@ -629,7 +629,6 @@ int nouveau_pmops_suspend(struct device *dev) | |||
| 629 | 629 | ||
| 630 | pci_save_state(pdev); | 630 | pci_save_state(pdev); |
| 631 | pci_disable_device(pdev); | 631 | pci_disable_device(pdev); |
| 632 | pci_ignore_hotplug(pdev); | ||
| 633 | pci_set_power_state(pdev, PCI_D3hot); | 632 | pci_set_power_state(pdev, PCI_D3hot); |
| 634 | return 0; | 633 | return 0; |
| 635 | } | 634 | } |
| @@ -933,6 +932,7 @@ static int nouveau_pmops_runtime_suspend(struct device *dev) | |||
| 933 | ret = nouveau_do_suspend(drm_dev, true); | 932 | ret = nouveau_do_suspend(drm_dev, true); |
| 934 | pci_save_state(pdev); | 933 | pci_save_state(pdev); |
| 935 | pci_disable_device(pdev); | 934 | pci_disable_device(pdev); |
| 935 | pci_ignore_hotplug(pdev); | ||
| 936 | pci_set_power_state(pdev, PCI_D3cold); | 936 | pci_set_power_state(pdev, PCI_D3cold); |
| 937 | drm_dev->switch_power_state = DRM_SWITCH_POWER_DYNAMIC_OFF; | 937 | drm_dev->switch_power_state = DRM_SWITCH_POWER_DYNAMIC_OFF; |
| 938 | return ret; | 938 | return ret; |
diff --git a/drivers/gpu/drm/nouveau/nouveau_fence.c b/drivers/gpu/drm/nouveau/nouveau_fence.c index 515cd9aebb99..f32a434724e3 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fence.c +++ b/drivers/gpu/drm/nouveau/nouveau_fence.c | |||
| @@ -52,20 +52,24 @@ nouveau_fctx(struct nouveau_fence *fence) | |||
| 52 | return container_of(fence->base.lock, struct nouveau_fence_chan, lock); | 52 | return container_of(fence->base.lock, struct nouveau_fence_chan, lock); |
| 53 | } | 53 | } |
| 54 | 54 | ||
| 55 | static void | 55 | static int |
| 56 | nouveau_fence_signal(struct nouveau_fence *fence) | 56 | nouveau_fence_signal(struct nouveau_fence *fence) |
| 57 | { | 57 | { |
| 58 | int drop = 0; | ||
| 59 | |||
| 58 | fence_signal_locked(&fence->base); | 60 | fence_signal_locked(&fence->base); |
| 59 | list_del(&fence->head); | 61 | list_del(&fence->head); |
| 62 | rcu_assign_pointer(fence->channel, NULL); | ||
| 60 | 63 | ||
| 61 | if (test_bit(FENCE_FLAG_USER_BITS, &fence->base.flags)) { | 64 | if (test_bit(FENCE_FLAG_USER_BITS, &fence->base.flags)) { |
| 62 | struct nouveau_fence_chan *fctx = nouveau_fctx(fence); | 65 | struct nouveau_fence_chan *fctx = nouveau_fctx(fence); |
| 63 | 66 | ||
| 64 | if (!--fctx->notify_ref) | 67 | if (!--fctx->notify_ref) |
| 65 | nvif_notify_put(&fctx->notify); | 68 | drop = 1; |
| 66 | } | 69 | } |
| 67 | 70 | ||
| 68 | fence_put(&fence->base); | 71 | fence_put(&fence->base); |
| 72 | return drop; | ||
| 69 | } | 73 | } |
| 70 | 74 | ||
| 71 | static struct nouveau_fence * | 75 | static struct nouveau_fence * |
| @@ -88,16 +92,23 @@ nouveau_fence_context_del(struct nouveau_fence_chan *fctx) | |||
| 88 | { | 92 | { |
| 89 | struct nouveau_fence *fence; | 93 | struct nouveau_fence *fence; |
| 90 | 94 | ||
| 91 | nvif_notify_fini(&fctx->notify); | ||
| 92 | |||
| 93 | spin_lock_irq(&fctx->lock); | 95 | spin_lock_irq(&fctx->lock); |
| 94 | while (!list_empty(&fctx->pending)) { | 96 | while (!list_empty(&fctx->pending)) { |
| 95 | fence = list_entry(fctx->pending.next, typeof(*fence), head); | 97 | fence = list_entry(fctx->pending.next, typeof(*fence), head); |
| 96 | 98 | ||
| 97 | nouveau_fence_signal(fence); | 99 | if (nouveau_fence_signal(fence)) |
| 98 | fence->channel = NULL; | 100 | nvif_notify_put(&fctx->notify); |
| 99 | } | 101 | } |
| 100 | spin_unlock_irq(&fctx->lock); | 102 | spin_unlock_irq(&fctx->lock); |
| 103 | |||
| 104 | nvif_notify_fini(&fctx->notify); | ||
| 105 | fctx->dead = 1; | ||
| 106 | |||
| 107 | /* | ||
| 108 | * Ensure that all accesses to fence->channel complete before freeing | ||
| 109 | * the channel. | ||
| 110 | */ | ||
| 111 | synchronize_rcu(); | ||
| 101 | } | 112 | } |
| 102 | 113 | ||
| 103 | static void | 114 | static void |
| @@ -112,21 +123,23 @@ nouveau_fence_context_free(struct nouveau_fence_chan *fctx) | |||
| 112 | kref_put(&fctx->fence_ref, nouveau_fence_context_put); | 123 | kref_put(&fctx->fence_ref, nouveau_fence_context_put); |
| 113 | } | 124 | } |
| 114 | 125 | ||
| 115 | static void | 126 | static int |
| 116 | nouveau_fence_update(struct nouveau_channel *chan, struct nouveau_fence_chan *fctx) | 127 | nouveau_fence_update(struct nouveau_channel *chan, struct nouveau_fence_chan *fctx) |
| 117 | { | 128 | { |
| 118 | struct nouveau_fence *fence; | 129 | struct nouveau_fence *fence; |
| 119 | 130 | int drop = 0; | |
| 120 | u32 seq = fctx->read(chan); | 131 | u32 seq = fctx->read(chan); |
| 121 | 132 | ||
| 122 | while (!list_empty(&fctx->pending)) { | 133 | while (!list_empty(&fctx->pending)) { |
| 123 | fence = list_entry(fctx->pending.next, typeof(*fence), head); | 134 | fence = list_entry(fctx->pending.next, typeof(*fence), head); |
| 124 | 135 | ||
| 125 | if ((int)(seq - fence->base.seqno) < 0) | 136 | if ((int)(seq - fence->base.seqno) < 0) |
| 126 | return; | 137 | break; |
| 127 | 138 | ||
| 128 | nouveau_fence_signal(fence); | 139 | drop |= nouveau_fence_signal(fence); |
| 129 | } | 140 | } |
| 141 | |||
| 142 | return drop; | ||
| 130 | } | 143 | } |
| 131 | 144 | ||
| 132 | static int | 145 | static int |
| @@ -135,18 +148,21 @@ nouveau_fence_wait_uevent_handler(struct nvif_notify *notify) | |||
| 135 | struct nouveau_fence_chan *fctx = | 148 | struct nouveau_fence_chan *fctx = |
| 136 | container_of(notify, typeof(*fctx), notify); | 149 | container_of(notify, typeof(*fctx), notify); |
| 137 | unsigned long flags; | 150 | unsigned long flags; |
| 151 | int ret = NVIF_NOTIFY_KEEP; | ||
| 138 | 152 | ||
| 139 | spin_lock_irqsave(&fctx->lock, flags); | 153 | spin_lock_irqsave(&fctx->lock, flags); |
| 140 | if (!list_empty(&fctx->pending)) { | 154 | if (!list_empty(&fctx->pending)) { |
| 141 | struct nouveau_fence *fence; | 155 | struct nouveau_fence *fence; |
| 156 | struct nouveau_channel *chan; | ||
| 142 | 157 | ||
| 143 | fence = list_entry(fctx->pending.next, typeof(*fence), head); | 158 | fence = list_entry(fctx->pending.next, typeof(*fence), head); |
| 144 | nouveau_fence_update(fence->channel, fctx); | 159 | chan = rcu_dereference_protected(fence->channel, lockdep_is_held(&fctx->lock)); |
| 160 | if (nouveau_fence_update(fence->channel, fctx)) | ||
| 161 | ret = NVIF_NOTIFY_DROP; | ||
| 145 | } | 162 | } |
| 146 | spin_unlock_irqrestore(&fctx->lock, flags); | 163 | spin_unlock_irqrestore(&fctx->lock, flags); |
| 147 | 164 | ||
| 148 | /* Always return keep here. NVIF refcount is handled with nouveau_fence_update */ | 165 | return ret; |
| 149 | return NVIF_NOTIFY_KEEP; | ||
| 150 | } | 166 | } |
| 151 | 167 | ||
| 152 | void | 168 | void |
| @@ -262,7 +278,10 @@ nouveau_fence_emit(struct nouveau_fence *fence, struct nouveau_channel *chan) | |||
| 262 | if (!ret) { | 278 | if (!ret) { |
| 263 | fence_get(&fence->base); | 279 | fence_get(&fence->base); |
| 264 | spin_lock_irq(&fctx->lock); | 280 | spin_lock_irq(&fctx->lock); |
| 265 | nouveau_fence_update(chan, fctx); | 281 | |
| 282 | if (nouveau_fence_update(chan, fctx)) | ||
| 283 | nvif_notify_put(&fctx->notify); | ||
| 284 | |||
| 266 | list_add_tail(&fence->head, &fctx->pending); | 285 | list_add_tail(&fence->head, &fctx->pending); |
| 267 | spin_unlock_irq(&fctx->lock); | 286 | spin_unlock_irq(&fctx->lock); |
| 268 | } | 287 | } |
| @@ -276,13 +295,16 @@ nouveau_fence_done(struct nouveau_fence *fence) | |||
| 276 | if (fence->base.ops == &nouveau_fence_ops_legacy || | 295 | if (fence->base.ops == &nouveau_fence_ops_legacy || |
| 277 | fence->base.ops == &nouveau_fence_ops_uevent) { | 296 | fence->base.ops == &nouveau_fence_ops_uevent) { |
| 278 | struct nouveau_fence_chan *fctx = nouveau_fctx(fence); | 297 | struct nouveau_fence_chan *fctx = nouveau_fctx(fence); |
| 298 | struct nouveau_channel *chan; | ||
| 279 | unsigned long flags; | 299 | unsigned long flags; |
| 280 | 300 | ||
| 281 | if (test_bit(FENCE_FLAG_SIGNALED_BIT, &fence->base.flags)) | 301 | if (test_bit(FENCE_FLAG_SIGNALED_BIT, &fence->base.flags)) |
| 282 | return true; | 302 | return true; |
| 283 | 303 | ||
| 284 | spin_lock_irqsave(&fctx->lock, flags); | 304 | spin_lock_irqsave(&fctx->lock, flags); |
| 285 | nouveau_fence_update(fence->channel, fctx); | 305 | chan = rcu_dereference_protected(fence->channel, lockdep_is_held(&fctx->lock)); |
| 306 | if (chan && nouveau_fence_update(chan, fctx)) | ||
| 307 | nvif_notify_put(&fctx->notify); | ||
| 286 | spin_unlock_irqrestore(&fctx->lock, flags); | 308 | spin_unlock_irqrestore(&fctx->lock, flags); |
| 287 | } | 309 | } |
| 288 | return fence_is_signaled(&fence->base); | 310 | return fence_is_signaled(&fence->base); |
| @@ -387,12 +409,18 @@ nouveau_fence_sync(struct nouveau_bo *nvbo, struct nouveau_channel *chan, bool e | |||
| 387 | 409 | ||
| 388 | if (fence && (!exclusive || !fobj || !fobj->shared_count)) { | 410 | if (fence && (!exclusive || !fobj || !fobj->shared_count)) { |
| 389 | struct nouveau_channel *prev = NULL; | 411 | struct nouveau_channel *prev = NULL; |
| 412 | bool must_wait = true; | ||
| 390 | 413 | ||
| 391 | f = nouveau_local_fence(fence, chan->drm); | 414 | f = nouveau_local_fence(fence, chan->drm); |
| 392 | if (f) | 415 | if (f) { |
| 393 | prev = f->channel; | 416 | rcu_read_lock(); |
| 417 | prev = rcu_dereference(f->channel); | ||
| 418 | if (prev && (prev == chan || fctx->sync(f, prev, chan) == 0)) | ||
| 419 | must_wait = false; | ||
| 420 | rcu_read_unlock(); | ||
| 421 | } | ||
| 394 | 422 | ||
| 395 | if (!prev || (prev != chan && (ret = fctx->sync(f, prev, chan)))) | 423 | if (must_wait) |
| 396 | ret = fence_wait(fence, intr); | 424 | ret = fence_wait(fence, intr); |
| 397 | 425 | ||
| 398 | return ret; | 426 | return ret; |
| @@ -403,19 +431,22 @@ nouveau_fence_sync(struct nouveau_bo *nvbo, struct nouveau_channel *chan, bool e | |||
| 403 | 431 | ||
| 404 | for (i = 0; i < fobj->shared_count && !ret; ++i) { | 432 | for (i = 0; i < fobj->shared_count && !ret; ++i) { |
| 405 | struct nouveau_channel *prev = NULL; | 433 | struct nouveau_channel *prev = NULL; |
| 434 | bool must_wait = true; | ||
| 406 | 435 | ||
| 407 | fence = rcu_dereference_protected(fobj->shared[i], | 436 | fence = rcu_dereference_protected(fobj->shared[i], |
| 408 | reservation_object_held(resv)); | 437 | reservation_object_held(resv)); |
| 409 | 438 | ||
| 410 | f = nouveau_local_fence(fence, chan->drm); | 439 | f = nouveau_local_fence(fence, chan->drm); |
| 411 | if (f) | 440 | if (f) { |
| 412 | prev = f->channel; | 441 | rcu_read_lock(); |
| 442 | prev = rcu_dereference(f->channel); | ||
| 443 | if (prev && (prev == chan || fctx->sync(f, prev, chan) == 0)) | ||
| 444 | must_wait = false; | ||
| 445 | rcu_read_unlock(); | ||
| 446 | } | ||
| 413 | 447 | ||
| 414 | if (!prev || (prev != chan && (ret = fctx->sync(f, prev, chan)))) | 448 | if (must_wait) |
| 415 | ret = fence_wait(fence, intr); | 449 | ret = fence_wait(fence, intr); |
| 416 | |||
| 417 | if (ret) | ||
| 418 | break; | ||
| 419 | } | 450 | } |
| 420 | 451 | ||
| 421 | return ret; | 452 | return ret; |
| @@ -463,7 +494,7 @@ static const char *nouveau_fence_get_timeline_name(struct fence *f) | |||
| 463 | struct nouveau_fence *fence = from_fence(f); | 494 | struct nouveau_fence *fence = from_fence(f); |
| 464 | struct nouveau_fence_chan *fctx = nouveau_fctx(fence); | 495 | struct nouveau_fence_chan *fctx = nouveau_fctx(fence); |
| 465 | 496 | ||
| 466 | return fence->channel ? fctx->name : "dead channel"; | 497 | return !fctx->dead ? fctx->name : "dead channel"; |
| 467 | } | 498 | } |
| 468 | 499 | ||
| 469 | /* | 500 | /* |
| @@ -476,9 +507,16 @@ static bool nouveau_fence_is_signaled(struct fence *f) | |||
| 476 | { | 507 | { |
| 477 | struct nouveau_fence *fence = from_fence(f); | 508 | struct nouveau_fence *fence = from_fence(f); |
| 478 | struct nouveau_fence_chan *fctx = nouveau_fctx(fence); | 509 | struct nouveau_fence_chan *fctx = nouveau_fctx(fence); |
| 479 | struct nouveau_channel *chan = fence->channel; | 510 | struct nouveau_channel *chan; |
| 511 | bool ret = false; | ||
| 512 | |||
| 513 | rcu_read_lock(); | ||
| 514 | chan = rcu_dereference(fence->channel); | ||
| 515 | if (chan) | ||
| 516 | ret = (int)(fctx->read(chan) - fence->base.seqno) >= 0; | ||
| 517 | rcu_read_unlock(); | ||
| 480 | 518 | ||
| 481 | return (int)(fctx->read(chan) - fence->base.seqno) >= 0; | 519 | return ret; |
| 482 | } | 520 | } |
| 483 | 521 | ||
| 484 | static bool nouveau_fence_no_signaling(struct fence *f) | 522 | static bool nouveau_fence_no_signaling(struct fence *f) |
diff --git a/drivers/gpu/drm/nouveau/nouveau_fence.h b/drivers/gpu/drm/nouveau/nouveau_fence.h index 943b0b17b1fc..96e461c6f68f 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fence.h +++ b/drivers/gpu/drm/nouveau/nouveau_fence.h | |||
| @@ -14,7 +14,7 @@ struct nouveau_fence { | |||
| 14 | 14 | ||
| 15 | bool sysmem; | 15 | bool sysmem; |
| 16 | 16 | ||
| 17 | struct nouveau_channel *channel; | 17 | struct nouveau_channel __rcu *channel; |
| 18 | unsigned long timeout; | 18 | unsigned long timeout; |
| 19 | }; | 19 | }; |
| 20 | 20 | ||
| @@ -47,7 +47,7 @@ struct nouveau_fence_chan { | |||
| 47 | char name[32]; | 47 | char name[32]; |
| 48 | 48 | ||
| 49 | struct nvif_notify notify; | 49 | struct nvif_notify notify; |
| 50 | int notify_ref; | 50 | int notify_ref, dead; |
| 51 | }; | 51 | }; |
| 52 | 52 | ||
| 53 | struct nouveau_fence_priv { | 53 | struct nouveau_fence_priv { |
diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c index ae873d1a8d46..eb8b36714fa1 100644 --- a/drivers/gpu/drm/nouveau/nv50_display.c +++ b/drivers/gpu/drm/nouveau/nv50_display.c | |||
| @@ -791,6 +791,22 @@ nv50_crtc_set_scale(struct nouveau_crtc *nv_crtc, bool update) | |||
| 791 | } | 791 | } |
| 792 | 792 | ||
| 793 | static int | 793 | static int |
| 794 | nv50_crtc_set_raster_vblank_dmi(struct nouveau_crtc *nv_crtc, u32 usec) | ||
| 795 | { | ||
| 796 | struct nv50_mast *mast = nv50_mast(nv_crtc->base.dev); | ||
| 797 | u32 *push; | ||
| 798 | |||
| 799 | push = evo_wait(mast, 8); | ||
| 800 | if (!push) | ||
| 801 | return -ENOMEM; | ||
| 802 | |||
| 803 | evo_mthd(push, 0x0828 + (nv_crtc->index * 0x400), 1); | ||
| 804 | evo_data(push, usec); | ||
| 805 | evo_kick(push, mast); | ||
| 806 | return 0; | ||
| 807 | } | ||
| 808 | |||
| 809 | static int | ||
| 794 | nv50_crtc_set_color_vibrance(struct nouveau_crtc *nv_crtc, bool update) | 810 | nv50_crtc_set_color_vibrance(struct nouveau_crtc *nv_crtc, bool update) |
| 795 | { | 811 | { |
| 796 | struct nv50_mast *mast = nv50_mast(nv_crtc->base.dev); | 812 | struct nv50_mast *mast = nv50_mast(nv_crtc->base.dev); |
| @@ -1104,14 +1120,14 @@ nv50_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode *umode, | |||
| 1104 | evo_mthd(push, 0x0804 + (nv_crtc->index * 0x400), 2); | 1120 | evo_mthd(push, 0x0804 + (nv_crtc->index * 0x400), 2); |
| 1105 | evo_data(push, 0x00800000 | mode->clock); | 1121 | evo_data(push, 0x00800000 | mode->clock); |
| 1106 | evo_data(push, (ilace == 2) ? 2 : 0); | 1122 | evo_data(push, (ilace == 2) ? 2 : 0); |
| 1107 | evo_mthd(push, 0x0810 + (nv_crtc->index * 0x400), 8); | 1123 | evo_mthd(push, 0x0810 + (nv_crtc->index * 0x400), 6); |
| 1108 | evo_data(push, 0x00000000); | 1124 | evo_data(push, 0x00000000); |
| 1109 | evo_data(push, (vactive << 16) | hactive); | 1125 | evo_data(push, (vactive << 16) | hactive); |
| 1110 | evo_data(push, ( vsynce << 16) | hsynce); | 1126 | evo_data(push, ( vsynce << 16) | hsynce); |
| 1111 | evo_data(push, (vblanke << 16) | hblanke); | 1127 | evo_data(push, (vblanke << 16) | hblanke); |
| 1112 | evo_data(push, (vblanks << 16) | hblanks); | 1128 | evo_data(push, (vblanks << 16) | hblanks); |
| 1113 | evo_data(push, (vblan2e << 16) | vblan2s); | 1129 | evo_data(push, (vblan2e << 16) | vblan2s); |
| 1114 | evo_data(push, vblankus); | 1130 | evo_mthd(push, 0x082c + (nv_crtc->index * 0x400), 1); |
| 1115 | evo_data(push, 0x00000000); | 1131 | evo_data(push, 0x00000000); |
| 1116 | evo_mthd(push, 0x0900 + (nv_crtc->index * 0x400), 2); | 1132 | evo_mthd(push, 0x0900 + (nv_crtc->index * 0x400), 2); |
| 1117 | evo_data(push, 0x00000311); | 1133 | evo_data(push, 0x00000311); |
| @@ -1141,6 +1157,11 @@ nv50_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode *umode, | |||
| 1141 | nv_connector = nouveau_crtc_connector_get(nv_crtc); | 1157 | nv_connector = nouveau_crtc_connector_get(nv_crtc); |
| 1142 | nv50_crtc_set_dither(nv_crtc, false); | 1158 | nv50_crtc_set_dither(nv_crtc, false); |
| 1143 | nv50_crtc_set_scale(nv_crtc, false); | 1159 | nv50_crtc_set_scale(nv_crtc, false); |
| 1160 | |||
| 1161 | /* G94 only accepts this after setting scale */ | ||
| 1162 | if (nv50_vers(mast) < GF110_DISP_CORE_CHANNEL_DMA) | ||
| 1163 | nv50_crtc_set_raster_vblank_dmi(nv_crtc, vblankus); | ||
| 1164 | |||
| 1144 | nv50_crtc_set_color_vibrance(nv_crtc, false); | 1165 | nv50_crtc_set_color_vibrance(nv_crtc, false); |
| 1145 | nv50_crtc_set_image(nv_crtc, crtc->primary->fb, x, y, false); | 1166 | nv50_crtc_set_image(nv_crtc, crtc->primary->fb, x, y, false); |
| 1146 | return 0; | 1167 | return 0; |
diff --git a/drivers/gpu/drm/qxl/qxl_display.c b/drivers/gpu/drm/qxl/qxl_display.c index af9e78546688..0d1396266857 100644 --- a/drivers/gpu/drm/qxl/qxl_display.c +++ b/drivers/gpu/drm/qxl/qxl_display.c | |||
| @@ -572,7 +572,6 @@ static int qxl_crtc_mode_set(struct drm_crtc *crtc, | |||
| 572 | struct qxl_framebuffer *qfb; | 572 | struct qxl_framebuffer *qfb; |
| 573 | struct qxl_bo *bo, *old_bo = NULL; | 573 | struct qxl_bo *bo, *old_bo = NULL; |
| 574 | struct qxl_crtc *qcrtc = to_qxl_crtc(crtc); | 574 | struct qxl_crtc *qcrtc = to_qxl_crtc(crtc); |
| 575 | uint32_t width, height, base_offset; | ||
| 576 | bool recreate_primary = false; | 575 | bool recreate_primary = false; |
| 577 | int ret; | 576 | int ret; |
| 578 | int surf_id; | 577 | int surf_id; |
| @@ -602,9 +601,10 @@ static int qxl_crtc_mode_set(struct drm_crtc *crtc, | |||
| 602 | if (qcrtc->index == 0) | 601 | if (qcrtc->index == 0) |
| 603 | recreate_primary = true; | 602 | recreate_primary = true; |
| 604 | 603 | ||
| 605 | width = mode->hdisplay; | 604 | if (bo->surf.stride * bo->surf.height > qdev->vram_size) { |
| 606 | height = mode->vdisplay; | 605 | DRM_ERROR("Mode doesn't fit in vram size (vgamem)"); |
| 607 | base_offset = 0; | 606 | return -EINVAL; |
| 607 | } | ||
| 608 | 608 | ||
| 609 | ret = qxl_bo_reserve(bo, false); | 609 | ret = qxl_bo_reserve(bo, false); |
| 610 | if (ret != 0) | 610 | if (ret != 0) |
| @@ -618,10 +618,10 @@ static int qxl_crtc_mode_set(struct drm_crtc *crtc, | |||
| 618 | if (recreate_primary) { | 618 | if (recreate_primary) { |
| 619 | qxl_io_destroy_primary(qdev); | 619 | qxl_io_destroy_primary(qdev); |
| 620 | qxl_io_log(qdev, | 620 | qxl_io_log(qdev, |
| 621 | "recreate primary: %dx%d (was %dx%d,%d,%d)\n", | 621 | "recreate primary: %dx%d,%d,%d\n", |
| 622 | width, height, bo->surf.width, | 622 | bo->surf.width, bo->surf.height, |
| 623 | bo->surf.height, bo->surf.stride, bo->surf.format); | 623 | bo->surf.stride, bo->surf.format); |
| 624 | qxl_io_create_primary(qdev, base_offset, bo); | 624 | qxl_io_create_primary(qdev, 0, bo); |
| 625 | bo->is_primary = true; | 625 | bo->is_primary = true; |
| 626 | } | 626 | } |
| 627 | 627 | ||
diff --git a/drivers/gpu/drm/radeon/atom.c b/drivers/gpu/drm/radeon/atom.c index 15da7ef344a4..ec1593a6a561 100644 --- a/drivers/gpu/drm/radeon/atom.c +++ b/drivers/gpu/drm/radeon/atom.c | |||
| @@ -1217,7 +1217,7 @@ free: | |||
| 1217 | return ret; | 1217 | return ret; |
| 1218 | } | 1218 | } |
| 1219 | 1219 | ||
| 1220 | int atom_execute_table(struct atom_context *ctx, int index, uint32_t * params) | 1220 | int atom_execute_table_scratch_unlocked(struct atom_context *ctx, int index, uint32_t * params) |
| 1221 | { | 1221 | { |
| 1222 | int r; | 1222 | int r; |
| 1223 | 1223 | ||
| @@ -1238,6 +1238,15 @@ int atom_execute_table(struct atom_context *ctx, int index, uint32_t * params) | |||
| 1238 | return r; | 1238 | return r; |
| 1239 | } | 1239 | } |
| 1240 | 1240 | ||
| 1241 | int atom_execute_table(struct atom_context *ctx, int index, uint32_t * params) | ||
| 1242 | { | ||
| 1243 | int r; | ||
| 1244 | mutex_lock(&ctx->scratch_mutex); | ||
| 1245 | r = atom_execute_table_scratch_unlocked(ctx, index, params); | ||
| 1246 | mutex_unlock(&ctx->scratch_mutex); | ||
| 1247 | return r; | ||
| 1248 | } | ||
| 1249 | |||
| 1241 | static int atom_iio_len[] = { 1, 2, 3, 3, 3, 3, 4, 4, 4, 3 }; | 1250 | static int atom_iio_len[] = { 1, 2, 3, 3, 3, 3, 4, 4, 4, 3 }; |
| 1242 | 1251 | ||
| 1243 | static void atom_index_iio(struct atom_context *ctx, int base) | 1252 | static void atom_index_iio(struct atom_context *ctx, int base) |
diff --git a/drivers/gpu/drm/radeon/atom.h b/drivers/gpu/drm/radeon/atom.h index feba6b8d36b3..6d014ddb6b78 100644 --- a/drivers/gpu/drm/radeon/atom.h +++ b/drivers/gpu/drm/radeon/atom.h | |||
| @@ -125,6 +125,7 @@ struct card_info { | |||
| 125 | struct atom_context { | 125 | struct atom_context { |
| 126 | struct card_info *card; | 126 | struct card_info *card; |
| 127 | struct mutex mutex; | 127 | struct mutex mutex; |
| 128 | struct mutex scratch_mutex; | ||
| 128 | void *bios; | 129 | void *bios; |
| 129 | uint32_t cmd_table, data_table; | 130 | uint32_t cmd_table, data_table; |
| 130 | uint16_t *iio; | 131 | uint16_t *iio; |
| @@ -145,6 +146,7 @@ extern int atom_debug; | |||
| 145 | 146 | ||
| 146 | struct atom_context *atom_parse(struct card_info *, void *); | 147 | struct atom_context *atom_parse(struct card_info *, void *); |
| 147 | int atom_execute_table(struct atom_context *, int, uint32_t *); | 148 | int atom_execute_table(struct atom_context *, int, uint32_t *); |
| 149 | int atom_execute_table_scratch_unlocked(struct atom_context *, int, uint32_t *); | ||
| 148 | int atom_asic_init(struct atom_context *); | 150 | int atom_asic_init(struct atom_context *); |
| 149 | void atom_destroy(struct atom_context *); | 151 | void atom_destroy(struct atom_context *); |
| 150 | bool atom_parse_data_header(struct atom_context *ctx, int index, uint16_t *size, | 152 | bool atom_parse_data_header(struct atom_context *ctx, int index, uint16_t *size, |
diff --git a/drivers/gpu/drm/radeon/atombios_dp.c b/drivers/gpu/drm/radeon/atombios_dp.c index 95d5d4ab3335..11ba9d21b89b 100644 --- a/drivers/gpu/drm/radeon/atombios_dp.c +++ b/drivers/gpu/drm/radeon/atombios_dp.c | |||
| @@ -100,6 +100,7 @@ static int radeon_process_aux_ch(struct radeon_i2c_chan *chan, | |||
| 100 | memset(&args, 0, sizeof(args)); | 100 | memset(&args, 0, sizeof(args)); |
| 101 | 101 | ||
| 102 | mutex_lock(&chan->mutex); | 102 | mutex_lock(&chan->mutex); |
| 103 | mutex_lock(&rdev->mode_info.atom_context->scratch_mutex); | ||
| 103 | 104 | ||
| 104 | base = (unsigned char *)(rdev->mode_info.atom_context->scratch + 1); | 105 | base = (unsigned char *)(rdev->mode_info.atom_context->scratch + 1); |
| 105 | 106 | ||
| @@ -113,7 +114,7 @@ static int radeon_process_aux_ch(struct radeon_i2c_chan *chan, | |||
| 113 | if (ASIC_IS_DCE4(rdev)) | 114 | if (ASIC_IS_DCE4(rdev)) |
| 114 | args.v2.ucHPD_ID = chan->rec.hpd; | 115 | args.v2.ucHPD_ID = chan->rec.hpd; |
| 115 | 116 | ||
| 116 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); | 117 | atom_execute_table_scratch_unlocked(rdev->mode_info.atom_context, index, (uint32_t *)&args); |
| 117 | 118 | ||
| 118 | *ack = args.v1.ucReplyStatus; | 119 | *ack = args.v1.ucReplyStatus; |
| 119 | 120 | ||
| @@ -147,6 +148,7 @@ static int radeon_process_aux_ch(struct radeon_i2c_chan *chan, | |||
| 147 | 148 | ||
| 148 | r = recv_bytes; | 149 | r = recv_bytes; |
| 149 | done: | 150 | done: |
| 151 | mutex_unlock(&rdev->mode_info.atom_context->scratch_mutex); | ||
| 150 | mutex_unlock(&chan->mutex); | 152 | mutex_unlock(&chan->mutex); |
| 151 | 153 | ||
| 152 | return r; | 154 | return r; |
diff --git a/drivers/gpu/drm/radeon/atombios_i2c.c b/drivers/gpu/drm/radeon/atombios_i2c.c index 9c570fb15b8c..4157780585a0 100644 --- a/drivers/gpu/drm/radeon/atombios_i2c.c +++ b/drivers/gpu/drm/radeon/atombios_i2c.c | |||
| @@ -48,6 +48,7 @@ static int radeon_process_i2c_ch(struct radeon_i2c_chan *chan, | |||
| 48 | memset(&args, 0, sizeof(args)); | 48 | memset(&args, 0, sizeof(args)); |
| 49 | 49 | ||
| 50 | mutex_lock(&chan->mutex); | 50 | mutex_lock(&chan->mutex); |
| 51 | mutex_lock(&rdev->mode_info.atom_context->scratch_mutex); | ||
| 51 | 52 | ||
| 52 | base = (unsigned char *)rdev->mode_info.atom_context->scratch; | 53 | base = (unsigned char *)rdev->mode_info.atom_context->scratch; |
| 53 | 54 | ||
| @@ -82,7 +83,7 @@ static int radeon_process_i2c_ch(struct radeon_i2c_chan *chan, | |||
| 82 | args.ucSlaveAddr = slave_addr << 1; | 83 | args.ucSlaveAddr = slave_addr << 1; |
| 83 | args.ucLineNumber = chan->rec.i2c_id; | 84 | args.ucLineNumber = chan->rec.i2c_id; |
| 84 | 85 | ||
| 85 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); | 86 | atom_execute_table_scratch_unlocked(rdev->mode_info.atom_context, index, (uint32_t *)&args); |
| 86 | 87 | ||
| 87 | /* error */ | 88 | /* error */ |
| 88 | if (args.ucStatus != HW_ASSISTED_I2C_STATUS_SUCCESS) { | 89 | if (args.ucStatus != HW_ASSISTED_I2C_STATUS_SUCCESS) { |
| @@ -95,6 +96,7 @@ static int radeon_process_i2c_ch(struct radeon_i2c_chan *chan, | |||
| 95 | radeon_atom_copy_swap(buf, base, num, false); | 96 | radeon_atom_copy_swap(buf, base, num, false); |
| 96 | 97 | ||
| 97 | done: | 98 | done: |
| 99 | mutex_unlock(&rdev->mode_info.atom_context->scratch_mutex); | ||
| 98 | mutex_unlock(&chan->mutex); | 100 | mutex_unlock(&chan->mutex); |
| 99 | 101 | ||
| 100 | return r; | 102 | return r; |
diff --git a/drivers/gpu/drm/radeon/btc_dpm.c b/drivers/gpu/drm/radeon/btc_dpm.c index 300d971187c4..0b2929de9f41 100644 --- a/drivers/gpu/drm/radeon/btc_dpm.c +++ b/drivers/gpu/drm/radeon/btc_dpm.c | |||
| @@ -24,6 +24,7 @@ | |||
| 24 | 24 | ||
| 25 | #include "drmP.h" | 25 | #include "drmP.h" |
| 26 | #include "radeon.h" | 26 | #include "radeon.h" |
| 27 | #include "radeon_asic.h" | ||
| 27 | #include "btcd.h" | 28 | #include "btcd.h" |
| 28 | #include "r600_dpm.h" | 29 | #include "r600_dpm.h" |
| 29 | #include "cypress_dpm.h" | 30 | #include "cypress_dpm.h" |
| @@ -1170,6 +1171,23 @@ static const struct radeon_blacklist_clocks btc_blacklist_clocks[] = | |||
| 1170 | { 25000, 30000, RADEON_SCLK_UP } | 1171 | { 25000, 30000, RADEON_SCLK_UP } |
| 1171 | }; | 1172 | }; |
| 1172 | 1173 | ||
| 1174 | void btc_get_max_clock_from_voltage_dependency_table(struct radeon_clock_voltage_dependency_table *table, | ||
| 1175 | u32 *max_clock) | ||
| 1176 | { | ||
| 1177 | u32 i, clock = 0; | ||
| 1178 | |||
| 1179 | if ((table == NULL) || (table->count == 0)) { | ||
| 1180 | *max_clock = clock; | ||
| 1181 | return; | ||
| 1182 | } | ||
| 1183 | |||
| 1184 | for (i = 0; i < table->count; i++) { | ||
| 1185 | if (clock < table->entries[i].clk) | ||
| 1186 | clock = table->entries[i].clk; | ||
| 1187 | } | ||
| 1188 | *max_clock = clock; | ||
| 1189 | } | ||
| 1190 | |||
| 1173 | void btc_apply_voltage_dependency_rules(struct radeon_clock_voltage_dependency_table *table, | 1191 | void btc_apply_voltage_dependency_rules(struct radeon_clock_voltage_dependency_table *table, |
| 1174 | u32 clock, u16 max_voltage, u16 *voltage) | 1192 | u32 clock, u16 max_voltage, u16 *voltage) |
| 1175 | { | 1193 | { |
diff --git a/drivers/gpu/drm/radeon/btc_dpm.h b/drivers/gpu/drm/radeon/btc_dpm.h index 1a15e0e41950..3b6f12b7760b 100644 --- a/drivers/gpu/drm/radeon/btc_dpm.h +++ b/drivers/gpu/drm/radeon/btc_dpm.h | |||
| @@ -46,6 +46,8 @@ void btc_adjust_clock_combinations(struct radeon_device *rdev, | |||
| 46 | struct rv7xx_pl *pl); | 46 | struct rv7xx_pl *pl); |
| 47 | void btc_apply_voltage_dependency_rules(struct radeon_clock_voltage_dependency_table *table, | 47 | void btc_apply_voltage_dependency_rules(struct radeon_clock_voltage_dependency_table *table, |
| 48 | u32 clock, u16 max_voltage, u16 *voltage); | 48 | u32 clock, u16 max_voltage, u16 *voltage); |
| 49 | void btc_get_max_clock_from_voltage_dependency_table(struct radeon_clock_voltage_dependency_table *table, | ||
| 50 | u32 *max_clock); | ||
| 49 | void btc_apply_voltage_delta_rules(struct radeon_device *rdev, | 51 | void btc_apply_voltage_delta_rules(struct radeon_device *rdev, |
| 50 | u16 max_vddc, u16 max_vddci, | 52 | u16 max_vddc, u16 max_vddci, |
| 51 | u16 *vddc, u16 *vddci); | 53 | u16 *vddc, u16 *vddci); |
diff --git a/drivers/gpu/drm/radeon/ci_dpm.c b/drivers/gpu/drm/radeon/ci_dpm.c index f5c8c0445a94..11a55e9dad7f 100644 --- a/drivers/gpu/drm/radeon/ci_dpm.c +++ b/drivers/gpu/drm/radeon/ci_dpm.c | |||
| @@ -24,6 +24,7 @@ | |||
| 24 | #include <linux/firmware.h> | 24 | #include <linux/firmware.h> |
| 25 | #include "drmP.h" | 25 | #include "drmP.h" |
| 26 | #include "radeon.h" | 26 | #include "radeon.h" |
| 27 | #include "radeon_asic.h" | ||
| 27 | #include "radeon_ucode.h" | 28 | #include "radeon_ucode.h" |
| 28 | #include "cikd.h" | 29 | #include "cikd.h" |
| 29 | #include "r600_dpm.h" | 30 | #include "r600_dpm.h" |
diff --git a/drivers/gpu/drm/radeon/cik.c b/drivers/gpu/drm/radeon/cik.c index 377afa504d2b..89c01fa6dd8e 100644 --- a/drivers/gpu/drm/radeon/cik.c +++ b/drivers/gpu/drm/radeon/cik.c | |||
| @@ -4313,8 +4313,8 @@ static int cik_cp_gfx_start(struct radeon_device *rdev) | |||
| 4313 | /* init the CE partitions. CE only used for gfx on CIK */ | 4313 | /* init the CE partitions. CE only used for gfx on CIK */ |
| 4314 | radeon_ring_write(ring, PACKET3(PACKET3_SET_BASE, 2)); | 4314 | radeon_ring_write(ring, PACKET3(PACKET3_SET_BASE, 2)); |
| 4315 | radeon_ring_write(ring, PACKET3_BASE_INDEX(CE_PARTITION_BASE)); | 4315 | radeon_ring_write(ring, PACKET3_BASE_INDEX(CE_PARTITION_BASE)); |
| 4316 | radeon_ring_write(ring, 0xc000); | 4316 | radeon_ring_write(ring, 0x8000); |
| 4317 | radeon_ring_write(ring, 0xc000); | 4317 | radeon_ring_write(ring, 0x8000); |
| 4318 | 4318 | ||
| 4319 | /* setup clear context state */ | 4319 | /* setup clear context state */ |
| 4320 | radeon_ring_write(ring, PACKET3(PACKET3_PREAMBLE_CNTL, 0)); | 4320 | radeon_ring_write(ring, PACKET3(PACKET3_PREAMBLE_CNTL, 0)); |
| @@ -9447,6 +9447,9 @@ void dce8_bandwidth_update(struct radeon_device *rdev) | |||
| 9447 | u32 num_heads = 0, lb_size; | 9447 | u32 num_heads = 0, lb_size; |
| 9448 | int i; | 9448 | int i; |
| 9449 | 9449 | ||
| 9450 | if (!rdev->mode_info.mode_config_initialized) | ||
| 9451 | return; | ||
| 9452 | |||
| 9450 | radeon_update_display_priority(rdev); | 9453 | radeon_update_display_priority(rdev); |
| 9451 | 9454 | ||
| 9452 | for (i = 0; i < rdev->num_crtc; i++) { | 9455 | for (i = 0; i < rdev->num_crtc; i++) { |
diff --git a/drivers/gpu/drm/radeon/cik_sdma.c b/drivers/gpu/drm/radeon/cik_sdma.c index c77dad1a4576..d748963af08b 100644 --- a/drivers/gpu/drm/radeon/cik_sdma.c +++ b/drivers/gpu/drm/radeon/cik_sdma.c | |||
| @@ -611,16 +611,19 @@ int cik_sdma_ring_test(struct radeon_device *rdev, | |||
| 611 | { | 611 | { |
| 612 | unsigned i; | 612 | unsigned i; |
| 613 | int r; | 613 | int r; |
| 614 | void __iomem *ptr = (void *)rdev->vram_scratch.ptr; | 614 | unsigned index; |
| 615 | u32 tmp; | 615 | u32 tmp; |
| 616 | u64 gpu_addr; | ||
| 616 | 617 | ||
| 617 | if (!ptr) { | 618 | if (ring->idx == R600_RING_TYPE_DMA_INDEX) |
| 618 | DRM_ERROR("invalid vram scratch pointer\n"); | 619 | index = R600_WB_DMA_RING_TEST_OFFSET; |
| 619 | return -EINVAL; | 620 | else |
| 620 | } | 621 | index = CAYMAN_WB_DMA1_RING_TEST_OFFSET; |
| 622 | |||
| 623 | gpu_addr = rdev->wb.gpu_addr + index; | ||
| 621 | 624 | ||
| 622 | tmp = 0xCAFEDEAD; | 625 | tmp = 0xCAFEDEAD; |
| 623 | writel(tmp, ptr); | 626 | rdev->wb.wb[index/4] = cpu_to_le32(tmp); |
| 624 | 627 | ||
| 625 | r = radeon_ring_lock(rdev, ring, 5); | 628 | r = radeon_ring_lock(rdev, ring, 5); |
| 626 | if (r) { | 629 | if (r) { |
| @@ -628,14 +631,14 @@ int cik_sdma_ring_test(struct radeon_device *rdev, | |||
| 628 | return r; | 631 | return r; |
| 629 | } | 632 | } |
| 630 | radeon_ring_write(ring, SDMA_PACKET(SDMA_OPCODE_WRITE, SDMA_WRITE_SUB_OPCODE_LINEAR, 0)); | 633 | radeon_ring_write(ring, SDMA_PACKET(SDMA_OPCODE_WRITE, SDMA_WRITE_SUB_OPCODE_LINEAR, 0)); |
| 631 | radeon_ring_write(ring, rdev->vram_scratch.gpu_addr & 0xfffffffc); | 634 | radeon_ring_write(ring, lower_32_bits(gpu_addr)); |
| 632 | radeon_ring_write(ring, upper_32_bits(rdev->vram_scratch.gpu_addr)); | 635 | radeon_ring_write(ring, upper_32_bits(gpu_addr)); |
| 633 | radeon_ring_write(ring, 1); /* number of DWs to follow */ | 636 | radeon_ring_write(ring, 1); /* number of DWs to follow */ |
| 634 | radeon_ring_write(ring, 0xDEADBEEF); | 637 | radeon_ring_write(ring, 0xDEADBEEF); |
| 635 | radeon_ring_unlock_commit(rdev, ring, false); | 638 | radeon_ring_unlock_commit(rdev, ring, false); |
| 636 | 639 | ||
| 637 | for (i = 0; i < rdev->usec_timeout; i++) { | 640 | for (i = 0; i < rdev->usec_timeout; i++) { |
| 638 | tmp = readl(ptr); | 641 | tmp = le32_to_cpu(rdev->wb.wb[index/4]); |
| 639 | if (tmp == 0xDEADBEEF) | 642 | if (tmp == 0xDEADBEEF) |
| 640 | break; | 643 | break; |
| 641 | DRM_UDELAY(1); | 644 | DRM_UDELAY(1); |
| @@ -664,17 +667,20 @@ int cik_sdma_ib_test(struct radeon_device *rdev, struct radeon_ring *ring) | |||
| 664 | { | 667 | { |
| 665 | struct radeon_ib ib; | 668 | struct radeon_ib ib; |
| 666 | unsigned i; | 669 | unsigned i; |
| 670 | unsigned index; | ||
| 667 | int r; | 671 | int r; |
| 668 | void __iomem *ptr = (void *)rdev->vram_scratch.ptr; | ||
| 669 | u32 tmp = 0; | 672 | u32 tmp = 0; |
| 673 | u64 gpu_addr; | ||
| 670 | 674 | ||
| 671 | if (!ptr) { | 675 | if (ring->idx == R600_RING_TYPE_DMA_INDEX) |
| 672 | DRM_ERROR("invalid vram scratch pointer\n"); | 676 | index = R600_WB_DMA_RING_TEST_OFFSET; |
| 673 | return -EINVAL; | 677 | else |
| 674 | } | 678 | index = CAYMAN_WB_DMA1_RING_TEST_OFFSET; |
| 679 | |||
| 680 | gpu_addr = rdev->wb.gpu_addr + index; | ||
| 675 | 681 | ||
| 676 | tmp = 0xCAFEDEAD; | 682 | tmp = 0xCAFEDEAD; |
| 677 | writel(tmp, ptr); | 683 | rdev->wb.wb[index/4] = cpu_to_le32(tmp); |
| 678 | 684 | ||
| 679 | r = radeon_ib_get(rdev, ring->idx, &ib, NULL, 256); | 685 | r = radeon_ib_get(rdev, ring->idx, &ib, NULL, 256); |
| 680 | if (r) { | 686 | if (r) { |
| @@ -683,8 +689,8 @@ int cik_sdma_ib_test(struct radeon_device *rdev, struct radeon_ring *ring) | |||
| 683 | } | 689 | } |
| 684 | 690 | ||
| 685 | ib.ptr[0] = SDMA_PACKET(SDMA_OPCODE_WRITE, SDMA_WRITE_SUB_OPCODE_LINEAR, 0); | 691 | ib.ptr[0] = SDMA_PACKET(SDMA_OPCODE_WRITE, SDMA_WRITE_SUB_OPCODE_LINEAR, 0); |
| 686 | ib.ptr[1] = rdev->vram_scratch.gpu_addr & 0xfffffffc; | 692 | ib.ptr[1] = lower_32_bits(gpu_addr); |
| 687 | ib.ptr[2] = upper_32_bits(rdev->vram_scratch.gpu_addr); | 693 | ib.ptr[2] = upper_32_bits(gpu_addr); |
| 688 | ib.ptr[3] = 1; | 694 | ib.ptr[3] = 1; |
| 689 | ib.ptr[4] = 0xDEADBEEF; | 695 | ib.ptr[4] = 0xDEADBEEF; |
| 690 | ib.length_dw = 5; | 696 | ib.length_dw = 5; |
| @@ -701,7 +707,7 @@ int cik_sdma_ib_test(struct radeon_device *rdev, struct radeon_ring *ring) | |||
| 701 | return r; | 707 | return r; |
| 702 | } | 708 | } |
| 703 | for (i = 0; i < rdev->usec_timeout; i++) { | 709 | for (i = 0; i < rdev->usec_timeout; i++) { |
| 704 | tmp = readl(ptr); | 710 | tmp = le32_to_cpu(rdev->wb.wb[index/4]); |
| 705 | if (tmp == 0xDEADBEEF) | 711 | if (tmp == 0xDEADBEEF) |
| 706 | break; | 712 | break; |
| 707 | DRM_UDELAY(1); | 713 | DRM_UDELAY(1); |
diff --git a/drivers/gpu/drm/radeon/cypress_dpm.c b/drivers/gpu/drm/radeon/cypress_dpm.c index 47d31e915758..9aad0327e4d1 100644 --- a/drivers/gpu/drm/radeon/cypress_dpm.c +++ b/drivers/gpu/drm/radeon/cypress_dpm.c | |||
| @@ -24,6 +24,7 @@ | |||
| 24 | 24 | ||
| 25 | #include "drmP.h" | 25 | #include "drmP.h" |
| 26 | #include "radeon.h" | 26 | #include "radeon.h" |
| 27 | #include "radeon_asic.h" | ||
| 27 | #include "evergreend.h" | 28 | #include "evergreend.h" |
| 28 | #include "r600_dpm.h" | 29 | #include "r600_dpm.h" |
| 29 | #include "cypress_dpm.h" | 30 | #include "cypress_dpm.h" |
diff --git a/drivers/gpu/drm/radeon/dce3_1_afmt.c b/drivers/gpu/drm/radeon/dce3_1_afmt.c index 950af153f30e..2fe8cfc966d9 100644 --- a/drivers/gpu/drm/radeon/dce3_1_afmt.c +++ b/drivers/gpu/drm/radeon/dce3_1_afmt.c | |||
| @@ -32,7 +32,7 @@ static void dce3_2_afmt_write_speaker_allocation(struct drm_encoder *encoder) | |||
| 32 | struct drm_connector *connector; | 32 | struct drm_connector *connector; |
| 33 | struct radeon_connector *radeon_connector = NULL; | 33 | struct radeon_connector *radeon_connector = NULL; |
| 34 | u32 tmp; | 34 | u32 tmp; |
| 35 | u8 *sadb; | 35 | u8 *sadb = NULL; |
| 36 | int sad_count; | 36 | int sad_count; |
| 37 | 37 | ||
| 38 | list_for_each_entry(connector, &encoder->dev->mode_config.connector_list, head) { | 38 | list_for_each_entry(connector, &encoder->dev->mode_config.connector_list, head) { |
| @@ -49,8 +49,8 @@ static void dce3_2_afmt_write_speaker_allocation(struct drm_encoder *encoder) | |||
| 49 | 49 | ||
| 50 | sad_count = drm_edid_to_speaker_allocation(radeon_connector->edid, &sadb); | 50 | sad_count = drm_edid_to_speaker_allocation(radeon_connector->edid, &sadb); |
| 51 | if (sad_count < 0) { | 51 | if (sad_count < 0) { |
| 52 | DRM_ERROR("Couldn't read Speaker Allocation Data Block: %d\n", sad_count); | 52 | DRM_DEBUG("Couldn't read Speaker Allocation Data Block: %d\n", sad_count); |
| 53 | return; | 53 | sad_count = 0; |
| 54 | } | 54 | } |
| 55 | 55 | ||
| 56 | /* program the speaker allocation */ | 56 | /* program the speaker allocation */ |
diff --git a/drivers/gpu/drm/radeon/dce6_afmt.c b/drivers/gpu/drm/radeon/dce6_afmt.c index c0bbf68dbc27..f312edf4d50e 100644 --- a/drivers/gpu/drm/radeon/dce6_afmt.c +++ b/drivers/gpu/drm/radeon/dce6_afmt.c | |||
| @@ -155,7 +155,7 @@ void dce6_afmt_write_speaker_allocation(struct drm_encoder *encoder) | |||
| 155 | struct drm_connector *connector; | 155 | struct drm_connector *connector; |
| 156 | struct radeon_connector *radeon_connector = NULL; | 156 | struct radeon_connector *radeon_connector = NULL; |
| 157 | u32 offset, tmp; | 157 | u32 offset, tmp; |
| 158 | u8 *sadb; | 158 | u8 *sadb = NULL; |
| 159 | int sad_count; | 159 | int sad_count; |
| 160 | 160 | ||
| 161 | if (!dig || !dig->afmt || !dig->afmt->pin) | 161 | if (!dig || !dig->afmt || !dig->afmt->pin) |
| @@ -176,9 +176,9 @@ void dce6_afmt_write_speaker_allocation(struct drm_encoder *encoder) | |||
| 176 | } | 176 | } |
| 177 | 177 | ||
| 178 | sad_count = drm_edid_to_speaker_allocation(radeon_connector_edid(connector), &sadb); | 178 | sad_count = drm_edid_to_speaker_allocation(radeon_connector_edid(connector), &sadb); |
| 179 | if (sad_count <= 0) { | 179 | if (sad_count < 0) { |
| 180 | DRM_ERROR("Couldn't read Speaker Allocation Data Block: %d\n", sad_count); | 180 | DRM_DEBUG("Couldn't read Speaker Allocation Data Block: %d\n", sad_count); |
| 181 | return; | 181 | sad_count = 0; |
| 182 | } | 182 | } |
| 183 | 183 | ||
| 184 | /* program the speaker allocation */ | 184 | /* program the speaker allocation */ |
diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index a31f1ca40c6a..85995b4e3338 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c | |||
| @@ -2345,6 +2345,9 @@ void evergreen_bandwidth_update(struct radeon_device *rdev) | |||
| 2345 | u32 num_heads = 0, lb_size; | 2345 | u32 num_heads = 0, lb_size; |
| 2346 | int i; | 2346 | int i; |
| 2347 | 2347 | ||
| 2348 | if (!rdev->mode_info.mode_config_initialized) | ||
| 2349 | return; | ||
| 2350 | |||
| 2348 | radeon_update_display_priority(rdev); | 2351 | radeon_update_display_priority(rdev); |
| 2349 | 2352 | ||
| 2350 | for (i = 0; i < rdev->num_crtc; i++) { | 2353 | for (i = 0; i < rdev->num_crtc; i++) { |
| @@ -2552,6 +2555,7 @@ void evergreen_mc_stop(struct radeon_device *rdev, struct evergreen_mc_save *sav | |||
| 2552 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + crtc_offsets[i], 1); | 2555 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + crtc_offsets[i], 1); |
| 2553 | tmp |= EVERGREEN_CRTC_BLANK_DATA_EN; | 2556 | tmp |= EVERGREEN_CRTC_BLANK_DATA_EN; |
| 2554 | WREG32(EVERGREEN_CRTC_BLANK_CONTROL + crtc_offsets[i], tmp); | 2557 | WREG32(EVERGREEN_CRTC_BLANK_CONTROL + crtc_offsets[i], tmp); |
| 2558 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + crtc_offsets[i], 0); | ||
| 2555 | } | 2559 | } |
| 2556 | } else { | 2560 | } else { |
| 2557 | tmp = RREG32(EVERGREEN_CRTC_CONTROL + crtc_offsets[i]); | 2561 | tmp = RREG32(EVERGREEN_CRTC_CONTROL + crtc_offsets[i]); |
| @@ -3005,7 +3009,7 @@ static void evergreen_gpu_init(struct radeon_device *rdev) | |||
| 3005 | u32 vgt_cache_invalidation; | 3009 | u32 vgt_cache_invalidation; |
| 3006 | u32 hdp_host_path_cntl, tmp; | 3010 | u32 hdp_host_path_cntl, tmp; |
| 3007 | u32 disabled_rb_mask; | 3011 | u32 disabled_rb_mask; |
| 3008 | int i, j, num_shader_engines, ps_thread_count; | 3012 | int i, j, ps_thread_count; |
| 3009 | 3013 | ||
| 3010 | switch (rdev->family) { | 3014 | switch (rdev->family) { |
| 3011 | case CHIP_CYPRESS: | 3015 | case CHIP_CYPRESS: |
| @@ -3303,8 +3307,6 @@ static void evergreen_gpu_init(struct radeon_device *rdev) | |||
| 3303 | rdev->config.evergreen.tile_config |= | 3307 | rdev->config.evergreen.tile_config |= |
| 3304 | ((gb_addr_config & 0x30000000) >> 28) << 12; | 3308 | ((gb_addr_config & 0x30000000) >> 28) << 12; |
| 3305 | 3309 | ||
| 3306 | num_shader_engines = (gb_addr_config & NUM_SHADER_ENGINES(3) >> 12) + 1; | ||
| 3307 | |||
| 3308 | if ((rdev->family >= CHIP_CEDAR) && (rdev->family <= CHIP_HEMLOCK)) { | 3310 | if ((rdev->family >= CHIP_CEDAR) && (rdev->family <= CHIP_HEMLOCK)) { |
| 3309 | u32 efuse_straps_4; | 3311 | u32 efuse_straps_4; |
| 3310 | u32 efuse_straps_3; | 3312 | u32 efuse_straps_3; |
diff --git a/drivers/gpu/drm/radeon/evergreen_hdmi.c b/drivers/gpu/drm/radeon/evergreen_hdmi.c index 2514d659b1ba..53abd9b17a50 100644 --- a/drivers/gpu/drm/radeon/evergreen_hdmi.c +++ b/drivers/gpu/drm/radeon/evergreen_hdmi.c | |||
| @@ -133,7 +133,7 @@ static void dce4_afmt_write_speaker_allocation(struct drm_encoder *encoder) | |||
| 133 | struct drm_connector *connector; | 133 | struct drm_connector *connector; |
| 134 | struct radeon_connector *radeon_connector = NULL; | 134 | struct radeon_connector *radeon_connector = NULL; |
| 135 | u32 tmp; | 135 | u32 tmp; |
| 136 | u8 *sadb; | 136 | u8 *sadb = NULL; |
| 137 | int sad_count; | 137 | int sad_count; |
| 138 | 138 | ||
| 139 | list_for_each_entry(connector, &encoder->dev->mode_config.connector_list, head) { | 139 | list_for_each_entry(connector, &encoder->dev->mode_config.connector_list, head) { |
| @@ -149,9 +149,9 @@ static void dce4_afmt_write_speaker_allocation(struct drm_encoder *encoder) | |||
| 149 | } | 149 | } |
| 150 | 150 | ||
| 151 | sad_count = drm_edid_to_speaker_allocation(radeon_connector_edid(connector), &sadb); | 151 | sad_count = drm_edid_to_speaker_allocation(radeon_connector_edid(connector), &sadb); |
| 152 | if (sad_count <= 0) { | 152 | if (sad_count < 0) { |
| 153 | DRM_ERROR("Couldn't read Speaker Allocation Data Block: %d\n", sad_count); | 153 | DRM_DEBUG("Couldn't read Speaker Allocation Data Block: %d\n", sad_count); |
| 154 | return; | 154 | sad_count = 0; |
| 155 | } | 155 | } |
| 156 | 156 | ||
| 157 | /* program the speaker allocation */ | 157 | /* program the speaker allocation */ |
diff --git a/drivers/gpu/drm/radeon/kv_dpm.c b/drivers/gpu/drm/radeon/kv_dpm.c index 1dd976f447fa..9b42001295ba 100644 --- a/drivers/gpu/drm/radeon/kv_dpm.c +++ b/drivers/gpu/drm/radeon/kv_dpm.c | |||
| @@ -2725,7 +2725,11 @@ int kv_dpm_init(struct radeon_device *rdev) | |||
| 2725 | 2725 | ||
| 2726 | pi->sram_end = SMC_RAM_END; | 2726 | pi->sram_end = SMC_RAM_END; |
| 2727 | 2727 | ||
| 2728 | pi->enable_nb_dpm = true; | 2728 | /* Enabling nb dpm on an asrock system prevents dpm from working */ |
| 2729 | if (rdev->pdev->subsystem_vendor == 0x1849) | ||
| 2730 | pi->enable_nb_dpm = false; | ||
| 2731 | else | ||
| 2732 | pi->enable_nb_dpm = true; | ||
| 2729 | 2733 | ||
| 2730 | pi->caps_power_containment = true; | 2734 | pi->caps_power_containment = true; |
| 2731 | pi->caps_cac = true; | 2735 | pi->caps_cac = true; |
| @@ -2740,10 +2744,19 @@ int kv_dpm_init(struct radeon_device *rdev) | |||
| 2740 | pi->caps_sclk_ds = true; | 2744 | pi->caps_sclk_ds = true; |
| 2741 | pi->enable_auto_thermal_throttling = true; | 2745 | pi->enable_auto_thermal_throttling = true; |
| 2742 | pi->disable_nb_ps3_in_battery = false; | 2746 | pi->disable_nb_ps3_in_battery = false; |
| 2743 | if (radeon_bapm == 0) | 2747 | if (radeon_bapm == -1) { |
| 2748 | /* There are stability issues reported on with | ||
| 2749 | * bapm enabled on an asrock system. | ||
| 2750 | */ | ||
| 2751 | if (rdev->pdev->subsystem_vendor == 0x1849) | ||
| 2752 | pi->bapm_enable = false; | ||
| 2753 | else | ||
| 2754 | pi->bapm_enable = true; | ||
| 2755 | } else if (radeon_bapm == 0) { | ||
| 2744 | pi->bapm_enable = false; | 2756 | pi->bapm_enable = false; |
| 2745 | else | 2757 | } else { |
| 2746 | pi->bapm_enable = true; | 2758 | pi->bapm_enable = true; |
| 2759 | } | ||
| 2747 | pi->voltage_drop_t = 0; | 2760 | pi->voltage_drop_t = 0; |
| 2748 | pi->caps_sclk_throttle_low_notification = false; | 2761 | pi->caps_sclk_throttle_low_notification = false; |
| 2749 | pi->caps_fps = false; /* true? */ | 2762 | pi->caps_fps = false; /* true? */ |
diff --git a/drivers/gpu/drm/radeon/ni_dpm.c b/drivers/gpu/drm/radeon/ni_dpm.c index 715b181c6243..6d2f16cf2c1c 100644 --- a/drivers/gpu/drm/radeon/ni_dpm.c +++ b/drivers/gpu/drm/radeon/ni_dpm.c | |||
| @@ -23,6 +23,7 @@ | |||
| 23 | 23 | ||
| 24 | #include "drmP.h" | 24 | #include "drmP.h" |
| 25 | #include "radeon.h" | 25 | #include "radeon.h" |
| 26 | #include "radeon_asic.h" | ||
| 26 | #include "nid.h" | 27 | #include "nid.h" |
| 27 | #include "r600_dpm.h" | 28 | #include "r600_dpm.h" |
| 28 | #include "ni_dpm.h" | 29 | #include "ni_dpm.h" |
diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c index 10f8be0ee173..b53b31a7b76f 100644 --- a/drivers/gpu/drm/radeon/r100.c +++ b/drivers/gpu/drm/radeon/r100.c | |||
| @@ -3207,6 +3207,9 @@ void r100_bandwidth_update(struct radeon_device *rdev) | |||
| 3207 | uint32_t pixel_bytes1 = 0; | 3207 | uint32_t pixel_bytes1 = 0; |
| 3208 | uint32_t pixel_bytes2 = 0; | 3208 | uint32_t pixel_bytes2 = 0; |
| 3209 | 3209 | ||
| 3210 | if (!rdev->mode_info.mode_config_initialized) | ||
| 3211 | return; | ||
| 3212 | |||
| 3210 | radeon_update_display_priority(rdev); | 3213 | radeon_update_display_priority(rdev); |
| 3211 | 3214 | ||
| 3212 | if (rdev->mode_info.crtcs[0]->base.enabled) { | 3215 | if (rdev->mode_info.crtcs[0]->base.enabled) { |
diff --git a/drivers/gpu/drm/radeon/r600_dma.c b/drivers/gpu/drm/radeon/r600_dma.c index 100189ec5fa8..cf0df45d455e 100644 --- a/drivers/gpu/drm/radeon/r600_dma.c +++ b/drivers/gpu/drm/radeon/r600_dma.c | |||
| @@ -232,16 +232,19 @@ int r600_dma_ring_test(struct radeon_device *rdev, | |||
| 232 | { | 232 | { |
| 233 | unsigned i; | 233 | unsigned i; |
| 234 | int r; | 234 | int r; |
| 235 | void __iomem *ptr = (void *)rdev->vram_scratch.ptr; | 235 | unsigned index; |
| 236 | u32 tmp; | 236 | u32 tmp; |
| 237 | u64 gpu_addr; | ||
| 237 | 238 | ||
| 238 | if (!ptr) { | 239 | if (ring->idx == R600_RING_TYPE_DMA_INDEX) |
| 239 | DRM_ERROR("invalid vram scratch pointer\n"); | 240 | index = R600_WB_DMA_RING_TEST_OFFSET; |
| 240 | return -EINVAL; | 241 | else |
| 241 | } | 242 | index = CAYMAN_WB_DMA1_RING_TEST_OFFSET; |
| 243 | |||
| 244 | gpu_addr = rdev->wb.gpu_addr + index; | ||
| 242 | 245 | ||
| 243 | tmp = 0xCAFEDEAD; | 246 | tmp = 0xCAFEDEAD; |
| 244 | writel(tmp, ptr); | 247 | rdev->wb.wb[index/4] = cpu_to_le32(tmp); |
| 245 | 248 | ||
| 246 | r = radeon_ring_lock(rdev, ring, 4); | 249 | r = radeon_ring_lock(rdev, ring, 4); |
| 247 | if (r) { | 250 | if (r) { |
| @@ -249,13 +252,13 @@ int r600_dma_ring_test(struct radeon_device *rdev, | |||
| 249 | return r; | 252 | return r; |
| 250 | } | 253 | } |
| 251 | radeon_ring_write(ring, DMA_PACKET(DMA_PACKET_WRITE, 0, 0, 1)); | 254 | radeon_ring_write(ring, DMA_PACKET(DMA_PACKET_WRITE, 0, 0, 1)); |
| 252 | radeon_ring_write(ring, rdev->vram_scratch.gpu_addr & 0xfffffffc); | 255 | radeon_ring_write(ring, lower_32_bits(gpu_addr)); |
| 253 | radeon_ring_write(ring, upper_32_bits(rdev->vram_scratch.gpu_addr) & 0xff); | 256 | radeon_ring_write(ring, upper_32_bits(gpu_addr) & 0xff); |
| 254 | radeon_ring_write(ring, 0xDEADBEEF); | 257 | radeon_ring_write(ring, 0xDEADBEEF); |
| 255 | radeon_ring_unlock_commit(rdev, ring, false); | 258 | radeon_ring_unlock_commit(rdev, ring, false); |
| 256 | 259 | ||
| 257 | for (i = 0; i < rdev->usec_timeout; i++) { | 260 | for (i = 0; i < rdev->usec_timeout; i++) { |
| 258 | tmp = readl(ptr); | 261 | tmp = le32_to_cpu(rdev->wb.wb[index/4]); |
| 259 | if (tmp == 0xDEADBEEF) | 262 | if (tmp == 0xDEADBEEF) |
| 260 | break; | 263 | break; |
| 261 | DRM_UDELAY(1); | 264 | DRM_UDELAY(1); |
| @@ -335,17 +338,17 @@ int r600_dma_ib_test(struct radeon_device *rdev, struct radeon_ring *ring) | |||
| 335 | { | 338 | { |
| 336 | struct radeon_ib ib; | 339 | struct radeon_ib ib; |
| 337 | unsigned i; | 340 | unsigned i; |
| 341 | unsigned index; | ||
| 338 | int r; | 342 | int r; |
| 339 | void __iomem *ptr = (void *)rdev->vram_scratch.ptr; | ||
| 340 | u32 tmp = 0; | 343 | u32 tmp = 0; |
| 344 | u64 gpu_addr; | ||
| 341 | 345 | ||
| 342 | if (!ptr) { | 346 | if (ring->idx == R600_RING_TYPE_DMA_INDEX) |
| 343 | DRM_ERROR("invalid vram scratch pointer\n"); | 347 | index = R600_WB_DMA_RING_TEST_OFFSET; |
| 344 | return -EINVAL; | 348 | else |
| 345 | } | 349 | index = CAYMAN_WB_DMA1_RING_TEST_OFFSET; |
| 346 | 350 | ||
| 347 | tmp = 0xCAFEDEAD; | 351 | gpu_addr = rdev->wb.gpu_addr + index; |
| 348 | writel(tmp, ptr); | ||
| 349 | 352 | ||
| 350 | r = radeon_ib_get(rdev, ring->idx, &ib, NULL, 256); | 353 | r = radeon_ib_get(rdev, ring->idx, &ib, NULL, 256); |
| 351 | if (r) { | 354 | if (r) { |
| @@ -354,8 +357,8 @@ int r600_dma_ib_test(struct radeon_device *rdev, struct radeon_ring *ring) | |||
| 354 | } | 357 | } |
| 355 | 358 | ||
| 356 | ib.ptr[0] = DMA_PACKET(DMA_PACKET_WRITE, 0, 0, 1); | 359 | ib.ptr[0] = DMA_PACKET(DMA_PACKET_WRITE, 0, 0, 1); |
| 357 | ib.ptr[1] = rdev->vram_scratch.gpu_addr & 0xfffffffc; | 360 | ib.ptr[1] = lower_32_bits(gpu_addr); |
| 358 | ib.ptr[2] = upper_32_bits(rdev->vram_scratch.gpu_addr) & 0xff; | 361 | ib.ptr[2] = upper_32_bits(gpu_addr) & 0xff; |
| 359 | ib.ptr[3] = 0xDEADBEEF; | 362 | ib.ptr[3] = 0xDEADBEEF; |
| 360 | ib.length_dw = 4; | 363 | ib.length_dw = 4; |
| 361 | 364 | ||
| @@ -371,7 +374,7 @@ int r600_dma_ib_test(struct radeon_device *rdev, struct radeon_ring *ring) | |||
| 371 | return r; | 374 | return r; |
| 372 | } | 375 | } |
| 373 | for (i = 0; i < rdev->usec_timeout; i++) { | 376 | for (i = 0; i < rdev->usec_timeout; i++) { |
| 374 | tmp = readl(ptr); | 377 | tmp = le32_to_cpu(rdev->wb.wb[index/4]); |
| 375 | if (tmp == 0xDEADBEEF) | 378 | if (tmp == 0xDEADBEEF) |
| 376 | break; | 379 | break; |
| 377 | DRM_UDELAY(1); | 380 | DRM_UDELAY(1); |
diff --git a/drivers/gpu/drm/radeon/r600_dpm.c b/drivers/gpu/drm/radeon/r600_dpm.c index 9c61b74ef441..b5c73df8e202 100644 --- a/drivers/gpu/drm/radeon/r600_dpm.c +++ b/drivers/gpu/drm/radeon/r600_dpm.c | |||
| @@ -24,6 +24,7 @@ | |||
| 24 | 24 | ||
| 25 | #include "drmP.h" | 25 | #include "drmP.h" |
| 26 | #include "radeon.h" | 26 | #include "radeon.h" |
| 27 | #include "radeon_asic.h" | ||
| 27 | #include "r600d.h" | 28 | #include "r600d.h" |
| 28 | #include "r600_dpm.h" | 29 | #include "r600_dpm.h" |
| 29 | #include "atom.h" | 30 | #include "atom.h" |
| @@ -1255,7 +1256,7 @@ int r600_parse_extended_power_table(struct radeon_device *rdev) | |||
| 1255 | (mode_info->atom_context->bios + data_offset + | 1256 | (mode_info->atom_context->bios + data_offset + |
| 1256 | le16_to_cpu(ext_hdr->usPowerTuneTableOffset)); | 1257 | le16_to_cpu(ext_hdr->usPowerTuneTableOffset)); |
| 1257 | rdev->pm.dpm.dyn_state.cac_tdp_table->maximum_power_delivery_limit = | 1258 | rdev->pm.dpm.dyn_state.cac_tdp_table->maximum_power_delivery_limit = |
| 1258 | ppt->usMaximumPowerDeliveryLimit; | 1259 | le16_to_cpu(ppt->usMaximumPowerDeliveryLimit); |
| 1259 | pt = &ppt->power_tune_table; | 1260 | pt = &ppt->power_tune_table; |
| 1260 | } else { | 1261 | } else { |
| 1261 | ATOM_PPLIB_POWERTUNE_Table *ppt = (ATOM_PPLIB_POWERTUNE_Table *) | 1262 | ATOM_PPLIB_POWERTUNE_Table *ppt = (ATOM_PPLIB_POWERTUNE_Table *) |
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index f7c4b226a284..a9717b3fbf1b 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h | |||
| @@ -1133,6 +1133,8 @@ struct radeon_wb { | |||
| 1133 | #define R600_WB_EVENT_OFFSET 3072 | 1133 | #define R600_WB_EVENT_OFFSET 3072 |
| 1134 | #define CIK_WB_CP1_WPTR_OFFSET 3328 | 1134 | #define CIK_WB_CP1_WPTR_OFFSET 3328 |
| 1135 | #define CIK_WB_CP2_WPTR_OFFSET 3584 | 1135 | #define CIK_WB_CP2_WPTR_OFFSET 3584 |
| 1136 | #define R600_WB_DMA_RING_TEST_OFFSET 3588 | ||
| 1137 | #define CAYMAN_WB_DMA1_RING_TEST_OFFSET 3592 | ||
| 1136 | 1138 | ||
| 1137 | /** | 1139 | /** |
| 1138 | * struct radeon_pm - power management datas | 1140 | * struct radeon_pm - power management datas |
diff --git a/drivers/gpu/drm/radeon/radeon_bios.c b/drivers/gpu/drm/radeon/radeon_bios.c index 6a03624fadaa..63ccb8fa799c 100644 --- a/drivers/gpu/drm/radeon/radeon_bios.c +++ b/drivers/gpu/drm/radeon/radeon_bios.c | |||
| @@ -658,12 +658,10 @@ bool radeon_get_bios(struct radeon_device *rdev) | |||
| 658 | r = igp_read_bios_from_vram(rdev); | 658 | r = igp_read_bios_from_vram(rdev); |
| 659 | if (r == false) | 659 | if (r == false) |
| 660 | r = radeon_read_bios(rdev); | 660 | r = radeon_read_bios(rdev); |
| 661 | if (r == false) { | 661 | if (r == false) |
| 662 | r = radeon_read_disabled_bios(rdev); | 662 | r = radeon_read_disabled_bios(rdev); |
| 663 | } | 663 | if (r == false) |
| 664 | if (r == false) { | ||
| 665 | r = radeon_read_platform_bios(rdev); | 664 | r = radeon_read_platform_bios(rdev); |
| 666 | } | ||
| 667 | if (r == false || rdev->bios == NULL) { | 665 | if (r == false || rdev->bios == NULL) { |
| 668 | DRM_ERROR("Unable to locate a BIOS ROM\n"); | 666 | DRM_ERROR("Unable to locate a BIOS ROM\n"); |
| 669 | rdev->bios = NULL; | 667 | rdev->bios = NULL; |
diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c index 300c4b3d4669..26baa9c05f6c 100644 --- a/drivers/gpu/drm/radeon/radeon_connectors.c +++ b/drivers/gpu/drm/radeon/radeon_connectors.c | |||
| @@ -322,6 +322,12 @@ static void radeon_connector_get_edid(struct drm_connector *connector) | |||
| 322 | } | 322 | } |
| 323 | 323 | ||
| 324 | if (!radeon_connector->edid) { | 324 | if (!radeon_connector->edid) { |
| 325 | /* don't fetch the edid from the vbios if ddc fails and runpm is | ||
| 326 | * enabled so we report disconnected. | ||
| 327 | */ | ||
| 328 | if ((rdev->flags & RADEON_IS_PX) && (radeon_runtime_pm != 0)) | ||
| 329 | return; | ||
| 330 | |||
| 325 | if (rdev->is_atom_bios) { | 331 | if (rdev->is_atom_bios) { |
| 326 | /* some laptops provide a hardcoded edid in rom for LCDs */ | 332 | /* some laptops provide a hardcoded edid in rom for LCDs */ |
| 327 | if (((connector->connector_type == DRM_MODE_CONNECTOR_LVDS) || | 333 | if (((connector->connector_type == DRM_MODE_CONNECTOR_LVDS) || |
| @@ -826,6 +832,8 @@ static int radeon_lvds_mode_valid(struct drm_connector *connector, | |||
| 826 | static enum drm_connector_status | 832 | static enum drm_connector_status |
| 827 | radeon_lvds_detect(struct drm_connector *connector, bool force) | 833 | radeon_lvds_detect(struct drm_connector *connector, bool force) |
| 828 | { | 834 | { |
| 835 | struct drm_device *dev = connector->dev; | ||
| 836 | struct radeon_device *rdev = dev->dev_private; | ||
| 829 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | 837 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); |
| 830 | struct drm_encoder *encoder = radeon_best_single_encoder(connector); | 838 | struct drm_encoder *encoder = radeon_best_single_encoder(connector); |
| 831 | enum drm_connector_status ret = connector_status_disconnected; | 839 | enum drm_connector_status ret = connector_status_disconnected; |
| @@ -842,7 +850,11 @@ radeon_lvds_detect(struct drm_connector *connector, bool force) | |||
| 842 | /* check if panel is valid */ | 850 | /* check if panel is valid */ |
| 843 | if (native_mode->hdisplay >= 320 && native_mode->vdisplay >= 240) | 851 | if (native_mode->hdisplay >= 320 && native_mode->vdisplay >= 240) |
| 844 | ret = connector_status_connected; | 852 | ret = connector_status_connected; |
| 845 | 853 | /* don't fetch the edid from the vbios if ddc fails and runpm is | |
| 854 | * enabled so we report disconnected. | ||
| 855 | */ | ||
| 856 | if ((rdev->flags & RADEON_IS_PX) && (radeon_runtime_pm != 0)) | ||
| 857 | ret = connector_status_disconnected; | ||
| 846 | } | 858 | } |
| 847 | 859 | ||
| 848 | /* check for edid as well */ | 860 | /* check for edid as well */ |
| @@ -1589,6 +1601,11 @@ radeon_dp_detect(struct drm_connector *connector, bool force) | |||
| 1589 | /* check if panel is valid */ | 1601 | /* check if panel is valid */ |
| 1590 | if (native_mode->hdisplay >= 320 && native_mode->vdisplay >= 240) | 1602 | if (native_mode->hdisplay >= 320 && native_mode->vdisplay >= 240) |
| 1591 | ret = connector_status_connected; | 1603 | ret = connector_status_connected; |
| 1604 | /* don't fetch the edid from the vbios if ddc fails and runpm is | ||
| 1605 | * enabled so we report disconnected. | ||
| 1606 | */ | ||
| 1607 | if ((rdev->flags & RADEON_IS_PX) && (radeon_runtime_pm != 0)) | ||
| 1608 | ret = connector_status_disconnected; | ||
| 1592 | } | 1609 | } |
| 1593 | /* eDP is always DP */ | 1610 | /* eDP is always DP */ |
| 1594 | radeon_dig_connector->dp_sink_type = CONNECTOR_OBJECT_ID_DISPLAYPORT; | 1611 | radeon_dig_connector->dp_sink_type = CONNECTOR_OBJECT_ID_DISPLAYPORT; |
diff --git a/drivers/gpu/drm/radeon/radeon_cs.c b/drivers/gpu/drm/radeon/radeon_cs.c index 1c893447d7cd..6f377de099f9 100644 --- a/drivers/gpu/drm/radeon/radeon_cs.c +++ b/drivers/gpu/drm/radeon/radeon_cs.c | |||
| @@ -251,22 +251,19 @@ static int radeon_cs_get_ring(struct radeon_cs_parser *p, u32 ring, s32 priority | |||
| 251 | 251 | ||
| 252 | static int radeon_cs_sync_rings(struct radeon_cs_parser *p) | 252 | static int radeon_cs_sync_rings(struct radeon_cs_parser *p) |
| 253 | { | 253 | { |
| 254 | int i, r = 0; | 254 | struct radeon_cs_reloc *reloc; |
| 255 | int r; | ||
| 255 | 256 | ||
| 256 | for (i = 0; i < p->nrelocs; i++) { | 257 | list_for_each_entry(reloc, &p->validated, tv.head) { |
| 257 | struct reservation_object *resv; | 258 | struct reservation_object *resv; |
| 258 | 259 | ||
| 259 | if (!p->relocs[i].robj) | 260 | resv = reloc->robj->tbo.resv; |
| 260 | continue; | ||
| 261 | |||
| 262 | resv = p->relocs[i].robj->tbo.resv; | ||
| 263 | r = radeon_semaphore_sync_resv(p->rdev, p->ib.semaphore, resv, | 261 | r = radeon_semaphore_sync_resv(p->rdev, p->ib.semaphore, resv, |
| 264 | p->relocs[i].tv.shared); | 262 | reloc->tv.shared); |
| 265 | |||
| 266 | if (r) | 263 | if (r) |
| 267 | break; | 264 | return r; |
| 268 | } | 265 | } |
| 269 | return r; | 266 | return 0; |
| 270 | } | 267 | } |
| 271 | 268 | ||
| 272 | /* XXX: note that this is called from the legacy UMS CS ioctl as well */ | 269 | /* XXX: note that this is called from the legacy UMS CS ioctl as well */ |
| @@ -450,7 +447,7 @@ static void radeon_cs_parser_fini(struct radeon_cs_parser *parser, int error, bo | |||
| 450 | kfree(parser->track); | 447 | kfree(parser->track); |
| 451 | kfree(parser->relocs); | 448 | kfree(parser->relocs); |
| 452 | kfree(parser->relocs_ptr); | 449 | kfree(parser->relocs_ptr); |
| 453 | kfree(parser->vm_bos); | 450 | drm_free_large(parser->vm_bos); |
| 454 | for (i = 0; i < parser->nchunks; i++) | 451 | for (i = 0; i < parser->nchunks; i++) |
| 455 | drm_free_large(parser->chunks[i].kdata); | 452 | drm_free_large(parser->chunks[i].kdata); |
| 456 | kfree(parser->chunks); | 453 | kfree(parser->chunks); |
diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index f41cc1538e48..995a8b1770dd 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c | |||
| @@ -952,6 +952,7 @@ int radeon_atombios_init(struct radeon_device *rdev) | |||
| 952 | } | 952 | } |
| 953 | 953 | ||
| 954 | mutex_init(&rdev->mode_info.atom_context->mutex); | 954 | mutex_init(&rdev->mode_info.atom_context->mutex); |
| 955 | mutex_init(&rdev->mode_info.atom_context->scratch_mutex); | ||
| 955 | radeon_atom_initialize_bios_scratch_regs(rdev->ddev); | 956 | radeon_atom_initialize_bios_scratch_regs(rdev->ddev); |
| 956 | atom_allocate_fb_scratch(rdev->mode_info.atom_context); | 957 | atom_allocate_fb_scratch(rdev->mode_info.atom_context); |
| 957 | return 0; | 958 | return 0; |
| @@ -1130,7 +1131,7 @@ static void radeon_check_arguments(struct radeon_device *rdev) | |||
| 1130 | if (radeon_vm_block_size == -1) { | 1131 | if (radeon_vm_block_size == -1) { |
| 1131 | 1132 | ||
| 1132 | /* Total bits covered by PD + PTs */ | 1133 | /* Total bits covered by PD + PTs */ |
| 1133 | unsigned bits = ilog2(radeon_vm_size) + 17; | 1134 | unsigned bits = ilog2(radeon_vm_size) + 18; |
| 1134 | 1135 | ||
| 1135 | /* Make sure the PD is 4K in size up to 8GB address space. | 1136 | /* Make sure the PD is 4K in size up to 8GB address space. |
| 1136 | Above that split equal between PD and PTs */ | 1137 | Above that split equal between PD and PTs */ |
diff --git a/drivers/gpu/drm/radeon/radeon_encoders.c b/drivers/gpu/drm/radeon/radeon_encoders.c index 9a19e52cc655..6b670b0bc47b 100644 --- a/drivers/gpu/drm/radeon/radeon_encoders.c +++ b/drivers/gpu/drm/radeon/radeon_encoders.c | |||
| @@ -179,6 +179,9 @@ static void radeon_encoder_add_backlight(struct radeon_encoder *radeon_encoder, | |||
| 179 | (rdev->pdev->subsystem_vendor == 0x1734) && | 179 | (rdev->pdev->subsystem_vendor == 0x1734) && |
| 180 | (rdev->pdev->subsystem_device == 0x1107)) | 180 | (rdev->pdev->subsystem_device == 0x1107)) |
| 181 | use_bl = false; | 181 | use_bl = false; |
| 182 | /* disable native backlight control on older asics */ | ||
| 183 | else if (rdev->family < CHIP_R600) | ||
| 184 | use_bl = false; | ||
| 182 | else | 185 | else |
| 183 | use_bl = true; | 186 | use_bl = true; |
| 184 | } | 187 | } |
diff --git a/drivers/gpu/drm/radeon/radeon_irq_kms.c b/drivers/gpu/drm/radeon/radeon_irq_kms.c index 7784911d78ef..00fc59762e0d 100644 --- a/drivers/gpu/drm/radeon/radeon_irq_kms.c +++ b/drivers/gpu/drm/radeon/radeon_irq_kms.c | |||
| @@ -185,6 +185,16 @@ static bool radeon_msi_ok(struct radeon_device *rdev) | |||
| 185 | if (rdev->flags & RADEON_IS_AGP) | 185 | if (rdev->flags & RADEON_IS_AGP) |
| 186 | return false; | 186 | return false; |
| 187 | 187 | ||
| 188 | /* | ||
| 189 | * Older chips have a HW limitation, they can only generate 40 bits | ||
| 190 | * of address for "64-bit" MSIs which breaks on some platforms, notably | ||
| 191 | * IBM POWER servers, so we limit them | ||
| 192 | */ | ||
| 193 | if (rdev->family < CHIP_BONAIRE) { | ||
| 194 | dev_info(rdev->dev, "radeon: MSI limited to 32-bit\n"); | ||
| 195 | rdev->pdev->no_64bit_msi = 1; | ||
| 196 | } | ||
| 197 | |||
| 188 | /* force MSI on */ | 198 | /* force MSI on */ |
| 189 | if (radeon_msi == 1) | 199 | if (radeon_msi == 1) |
| 190 | return true; | 200 | return true; |
diff --git a/drivers/gpu/drm/radeon/radeon_kms.c b/drivers/gpu/drm/radeon/radeon_kms.c index 8309b11e674d..03586763ee86 100644 --- a/drivers/gpu/drm/radeon/radeon_kms.c +++ b/drivers/gpu/drm/radeon/radeon_kms.c | |||
| @@ -795,6 +795,8 @@ int radeon_get_vblank_timestamp_kms(struct drm_device *dev, int crtc, | |||
| 795 | 795 | ||
| 796 | /* Get associated drm_crtc: */ | 796 | /* Get associated drm_crtc: */ |
| 797 | drmcrtc = &rdev->mode_info.crtcs[crtc]->base; | 797 | drmcrtc = &rdev->mode_info.crtcs[crtc]->base; |
| 798 | if (!drmcrtc) | ||
| 799 | return -EINVAL; | ||
| 798 | 800 | ||
| 799 | /* Helper routine in DRM core does all the work: */ | 801 | /* Helper routine in DRM core does all the work: */ |
| 800 | return drm_calc_vbltimestamp_from_scanoutpos(dev, crtc, max_error, | 802 | return drm_calc_vbltimestamp_from_scanoutpos(dev, crtc, max_error, |
diff --git a/drivers/gpu/drm/radeon/radeon_object.c b/drivers/gpu/drm/radeon/radeon_object.c index 99a960a4f302..4c0d786d5c7a 100644 --- a/drivers/gpu/drm/radeon/radeon_object.c +++ b/drivers/gpu/drm/radeon/radeon_object.c | |||
| @@ -213,6 +213,13 @@ int radeon_bo_create(struct radeon_device *rdev, | |||
| 213 | if (!(rdev->flags & RADEON_IS_PCIE)) | 213 | if (!(rdev->flags & RADEON_IS_PCIE)) |
| 214 | bo->flags &= ~(RADEON_GEM_GTT_WC | RADEON_GEM_GTT_UC); | 214 | bo->flags &= ~(RADEON_GEM_GTT_WC | RADEON_GEM_GTT_UC); |
| 215 | 215 | ||
| 216 | #ifdef CONFIG_X86_32 | ||
| 217 | /* XXX: Write-combined CPU mappings of GTT seem broken on 32-bit | ||
| 218 | * See https://bugs.freedesktop.org/show_bug.cgi?id=84627 | ||
| 219 | */ | ||
| 220 | bo->flags &= ~RADEON_GEM_GTT_WC; | ||
| 221 | #endif | ||
| 222 | |||
| 216 | radeon_ttm_placement_from_domain(bo, domain); | 223 | radeon_ttm_placement_from_domain(bo, domain); |
| 217 | /* Kernel allocation are uninterruptible */ | 224 | /* Kernel allocation are uninterruptible */ |
| 218 | down_read(&rdev->pm.mclk_lock); | 225 | down_read(&rdev->pm.mclk_lock); |
diff --git a/drivers/gpu/drm/radeon/radeon_ring.c b/drivers/gpu/drm/radeon/radeon_ring.c index 3d17af34afa7..2456f69efd23 100644 --- a/drivers/gpu/drm/radeon/radeon_ring.c +++ b/drivers/gpu/drm/radeon/radeon_ring.c | |||
| @@ -314,7 +314,7 @@ unsigned radeon_ring_backup(struct radeon_device *rdev, struct radeon_ring *ring | |||
| 314 | } | 314 | } |
| 315 | 315 | ||
| 316 | /* and then save the content of the ring */ | 316 | /* and then save the content of the ring */ |
| 317 | *data = kmalloc_array(size, sizeof(uint32_t), GFP_KERNEL); | 317 | *data = drm_malloc_ab(size, sizeof(uint32_t)); |
| 318 | if (!*data) { | 318 | if (!*data) { |
| 319 | mutex_unlock(&rdev->ring_lock); | 319 | mutex_unlock(&rdev->ring_lock); |
| 320 | return 0; | 320 | return 0; |
| @@ -356,7 +356,7 @@ int radeon_ring_restore(struct radeon_device *rdev, struct radeon_ring *ring, | |||
| 356 | } | 356 | } |
| 357 | 357 | ||
| 358 | radeon_ring_unlock_commit(rdev, ring, false); | 358 | radeon_ring_unlock_commit(rdev, ring, false); |
| 359 | kfree(data); | 359 | drm_free_large(data); |
| 360 | return 0; | 360 | return 0; |
| 361 | } | 361 | } |
| 362 | 362 | ||
diff --git a/drivers/gpu/drm/radeon/radeon_vm.c b/drivers/gpu/drm/radeon/radeon_vm.c index 4532cc76a0a6..dfde266529e2 100644 --- a/drivers/gpu/drm/radeon/radeon_vm.c +++ b/drivers/gpu/drm/radeon/radeon_vm.c | |||
| @@ -132,8 +132,8 @@ struct radeon_cs_reloc *radeon_vm_get_bos(struct radeon_device *rdev, | |||
| 132 | struct radeon_cs_reloc *list; | 132 | struct radeon_cs_reloc *list; |
| 133 | unsigned i, idx; | 133 | unsigned i, idx; |
| 134 | 134 | ||
| 135 | list = kmalloc_array(vm->max_pde_used + 2, | 135 | list = drm_malloc_ab(vm->max_pde_used + 2, |
| 136 | sizeof(struct radeon_cs_reloc), GFP_KERNEL); | 136 | sizeof(struct radeon_cs_reloc)); |
| 137 | if (!list) | 137 | if (!list) |
| 138 | return NULL; | 138 | return NULL; |
| 139 | 139 | ||
diff --git a/drivers/gpu/drm/radeon/rs600.c b/drivers/gpu/drm/radeon/rs600.c index 5f6db4629aaa..9acb1c3c005b 100644 --- a/drivers/gpu/drm/radeon/rs600.c +++ b/drivers/gpu/drm/radeon/rs600.c | |||
| @@ -879,6 +879,9 @@ void rs600_bandwidth_update(struct radeon_device *rdev) | |||
| 879 | u32 d1mode_priority_a_cnt, d2mode_priority_a_cnt; | 879 | u32 d1mode_priority_a_cnt, d2mode_priority_a_cnt; |
| 880 | /* FIXME: implement full support */ | 880 | /* FIXME: implement full support */ |
| 881 | 881 | ||
| 882 | if (!rdev->mode_info.mode_config_initialized) | ||
| 883 | return; | ||
| 884 | |||
| 882 | radeon_update_display_priority(rdev); | 885 | radeon_update_display_priority(rdev); |
| 883 | 886 | ||
| 884 | if (rdev->mode_info.crtcs[0]->base.enabled) | 887 | if (rdev->mode_info.crtcs[0]->base.enabled) |
diff --git a/drivers/gpu/drm/radeon/rs690.c b/drivers/gpu/drm/radeon/rs690.c index 3462b64369bf..0a2d36e81108 100644 --- a/drivers/gpu/drm/radeon/rs690.c +++ b/drivers/gpu/drm/radeon/rs690.c | |||
| @@ -579,6 +579,9 @@ void rs690_bandwidth_update(struct radeon_device *rdev) | |||
| 579 | u32 d1mode_priority_a_cnt, d1mode_priority_b_cnt; | 579 | u32 d1mode_priority_a_cnt, d1mode_priority_b_cnt; |
| 580 | u32 d2mode_priority_a_cnt, d2mode_priority_b_cnt; | 580 | u32 d2mode_priority_a_cnt, d2mode_priority_b_cnt; |
| 581 | 581 | ||
| 582 | if (!rdev->mode_info.mode_config_initialized) | ||
| 583 | return; | ||
| 584 | |||
| 582 | radeon_update_display_priority(rdev); | 585 | radeon_update_display_priority(rdev); |
| 583 | 586 | ||
| 584 | if (rdev->mode_info.crtcs[0]->base.enabled) | 587 | if (rdev->mode_info.crtcs[0]->base.enabled) |
diff --git a/drivers/gpu/drm/radeon/rs780_dpm.c b/drivers/gpu/drm/radeon/rs780_dpm.c index 02f7710de470..9031f4b69824 100644 --- a/drivers/gpu/drm/radeon/rs780_dpm.c +++ b/drivers/gpu/drm/radeon/rs780_dpm.c | |||
| @@ -24,6 +24,7 @@ | |||
| 24 | 24 | ||
| 25 | #include "drmP.h" | 25 | #include "drmP.h" |
| 26 | #include "radeon.h" | 26 | #include "radeon.h" |
| 27 | #include "radeon_asic.h" | ||
| 27 | #include "rs780d.h" | 28 | #include "rs780d.h" |
| 28 | #include "r600_dpm.h" | 29 | #include "r600_dpm.h" |
| 29 | #include "rs780_dpm.h" | 30 | #include "rs780_dpm.h" |
diff --git a/drivers/gpu/drm/radeon/rv515.c b/drivers/gpu/drm/radeon/rv515.c index 8a477bf1fdb3..c55d653aaf5f 100644 --- a/drivers/gpu/drm/radeon/rv515.c +++ b/drivers/gpu/drm/radeon/rv515.c | |||
| @@ -1277,6 +1277,9 @@ void rv515_bandwidth_update(struct radeon_device *rdev) | |||
| 1277 | struct drm_display_mode *mode0 = NULL; | 1277 | struct drm_display_mode *mode0 = NULL; |
| 1278 | struct drm_display_mode *mode1 = NULL; | 1278 | struct drm_display_mode *mode1 = NULL; |
| 1279 | 1279 | ||
| 1280 | if (!rdev->mode_info.mode_config_initialized) | ||
| 1281 | return; | ||
| 1282 | |||
| 1280 | radeon_update_display_priority(rdev); | 1283 | radeon_update_display_priority(rdev); |
| 1281 | 1284 | ||
| 1282 | if (rdev->mode_info.crtcs[0]->base.enabled) | 1285 | if (rdev->mode_info.crtcs[0]->base.enabled) |
diff --git a/drivers/gpu/drm/radeon/rv6xx_dpm.c b/drivers/gpu/drm/radeon/rv6xx_dpm.c index e7045b085715..6a5c233361e9 100644 --- a/drivers/gpu/drm/radeon/rv6xx_dpm.c +++ b/drivers/gpu/drm/radeon/rv6xx_dpm.c | |||
| @@ -24,6 +24,7 @@ | |||
| 24 | 24 | ||
| 25 | #include "drmP.h" | 25 | #include "drmP.h" |
| 26 | #include "radeon.h" | 26 | #include "radeon.h" |
| 27 | #include "radeon_asic.h" | ||
| 27 | #include "rv6xxd.h" | 28 | #include "rv6xxd.h" |
| 28 | #include "r600_dpm.h" | 29 | #include "r600_dpm.h" |
| 29 | #include "rv6xx_dpm.h" | 30 | #include "rv6xx_dpm.h" |
diff --git a/drivers/gpu/drm/radeon/rv770_dpm.c b/drivers/gpu/drm/radeon/rv770_dpm.c index 3c76e1dcdf04..755a8f96fe46 100644 --- a/drivers/gpu/drm/radeon/rv770_dpm.c +++ b/drivers/gpu/drm/radeon/rv770_dpm.c | |||
| @@ -24,6 +24,7 @@ | |||
| 24 | 24 | ||
| 25 | #include "drmP.h" | 25 | #include "drmP.h" |
| 26 | #include "radeon.h" | 26 | #include "radeon.h" |
| 27 | #include "radeon_asic.h" | ||
| 27 | #include "rv770d.h" | 28 | #include "rv770d.h" |
| 28 | #include "r600_dpm.h" | 29 | #include "r600_dpm.h" |
| 29 | #include "rv770_dpm.h" | 30 | #include "rv770_dpm.h" |
diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c index eeea5b6a1775..7d5083dc4acb 100644 --- a/drivers/gpu/drm/radeon/si.c +++ b/drivers/gpu/drm/radeon/si.c | |||
| @@ -2384,6 +2384,9 @@ void dce6_bandwidth_update(struct radeon_device *rdev) | |||
| 2384 | u32 num_heads = 0, lb_size; | 2384 | u32 num_heads = 0, lb_size; |
| 2385 | int i; | 2385 | int i; |
| 2386 | 2386 | ||
| 2387 | if (!rdev->mode_info.mode_config_initialized) | ||
| 2388 | return; | ||
| 2389 | |||
| 2387 | radeon_update_display_priority(rdev); | 2390 | radeon_update_display_priority(rdev); |
| 2388 | 2391 | ||
| 2389 | for (i = 0; i < rdev->num_crtc; i++) { | 2392 | for (i = 0; i < rdev->num_crtc; i++) { |
diff --git a/drivers/gpu/drm/radeon/si_dpm.c b/drivers/gpu/drm/radeon/si_dpm.c index 9e4d5d7d348f..676e6c2ba90a 100644 --- a/drivers/gpu/drm/radeon/si_dpm.c +++ b/drivers/gpu/drm/radeon/si_dpm.c | |||
| @@ -23,6 +23,7 @@ | |||
| 23 | 23 | ||
| 24 | #include "drmP.h" | 24 | #include "drmP.h" |
| 25 | #include "radeon.h" | 25 | #include "radeon.h" |
| 26 | #include "radeon_asic.h" | ||
| 26 | #include "sid.h" | 27 | #include "sid.h" |
| 27 | #include "r600_dpm.h" | 28 | #include "r600_dpm.h" |
| 28 | #include "si_dpm.h" | 29 | #include "si_dpm.h" |
| @@ -2916,6 +2917,7 @@ static void si_apply_state_adjust_rules(struct radeon_device *rdev, | |||
| 2916 | bool disable_sclk_switching = false; | 2917 | bool disable_sclk_switching = false; |
| 2917 | u32 mclk, sclk; | 2918 | u32 mclk, sclk; |
| 2918 | u16 vddc, vddci; | 2919 | u16 vddc, vddci; |
| 2920 | u32 max_sclk_vddc, max_mclk_vddci, max_mclk_vddc; | ||
| 2919 | int i; | 2921 | int i; |
| 2920 | 2922 | ||
| 2921 | if ((rdev->pm.dpm.new_active_crtc_count > 1) || | 2923 | if ((rdev->pm.dpm.new_active_crtc_count > 1) || |
| @@ -2949,6 +2951,29 @@ static void si_apply_state_adjust_rules(struct radeon_device *rdev, | |||
| 2949 | } | 2951 | } |
| 2950 | } | 2952 | } |
| 2951 | 2953 | ||
| 2954 | /* limit clocks to max supported clocks based on voltage dependency tables */ | ||
| 2955 | btc_get_max_clock_from_voltage_dependency_table(&rdev->pm.dpm.dyn_state.vddc_dependency_on_sclk, | ||
| 2956 | &max_sclk_vddc); | ||
| 2957 | btc_get_max_clock_from_voltage_dependency_table(&rdev->pm.dpm.dyn_state.vddci_dependency_on_mclk, | ||
| 2958 | &max_mclk_vddci); | ||
| 2959 | btc_get_max_clock_from_voltage_dependency_table(&rdev->pm.dpm.dyn_state.vddc_dependency_on_mclk, | ||
| 2960 | &max_mclk_vddc); | ||
| 2961 | |||
| 2962 | for (i = 0; i < ps->performance_level_count; i++) { | ||
| 2963 | if (max_sclk_vddc) { | ||
| 2964 | if (ps->performance_levels[i].sclk > max_sclk_vddc) | ||
| 2965 | ps->performance_levels[i].sclk = max_sclk_vddc; | ||
| 2966 | } | ||
| 2967 | if (max_mclk_vddci) { | ||
| 2968 | if (ps->performance_levels[i].mclk > max_mclk_vddci) | ||
| 2969 | ps->performance_levels[i].mclk = max_mclk_vddci; | ||
| 2970 | } | ||
| 2971 | if (max_mclk_vddc) { | ||
| 2972 | if (ps->performance_levels[i].mclk > max_mclk_vddc) | ||
| 2973 | ps->performance_levels[i].mclk = max_mclk_vddc; | ||
| 2974 | } | ||
| 2975 | } | ||
| 2976 | |||
| 2952 | /* XXX validate the min clocks required for display */ | 2977 | /* XXX validate the min clocks required for display */ |
| 2953 | 2978 | ||
| 2954 | if (disable_mclk_switching) { | 2979 | if (disable_mclk_switching) { |
| @@ -6231,7 +6256,7 @@ static void si_parse_pplib_clock_info(struct radeon_device *rdev, | |||
| 6231 | if ((rps->class2 & ATOM_PPLIB_CLASSIFICATION2_ULV) && | 6256 | if ((rps->class2 & ATOM_PPLIB_CLASSIFICATION2_ULV) && |
| 6232 | index == 0) { | 6257 | index == 0) { |
| 6233 | /* XXX disable for A0 tahiti */ | 6258 | /* XXX disable for A0 tahiti */ |
| 6234 | si_pi->ulv.supported = true; | 6259 | si_pi->ulv.supported = false; |
| 6235 | si_pi->ulv.pl = *pl; | 6260 | si_pi->ulv.pl = *pl; |
| 6236 | si_pi->ulv.one_pcie_lane_in_ulv = false; | 6261 | si_pi->ulv.one_pcie_lane_in_ulv = false; |
| 6237 | si_pi->ulv.volt_change_delay = SISLANDS_ULVVOLTAGECHANGEDELAY_DFLT; | 6262 | si_pi->ulv.volt_change_delay = SISLANDS_ULVVOLTAGECHANGEDELAY_DFLT; |
diff --git a/drivers/gpu/drm/radeon/sumo_dpm.c b/drivers/gpu/drm/radeon/sumo_dpm.c index 3f0e8d7b8dbe..1f8a8833e1be 100644 --- a/drivers/gpu/drm/radeon/sumo_dpm.c +++ b/drivers/gpu/drm/radeon/sumo_dpm.c | |||
| @@ -23,6 +23,7 @@ | |||
| 23 | 23 | ||
| 24 | #include "drmP.h" | 24 | #include "drmP.h" |
| 25 | #include "radeon.h" | 25 | #include "radeon.h" |
| 26 | #include "radeon_asic.h" | ||
| 26 | #include "sumod.h" | 27 | #include "sumod.h" |
| 27 | #include "r600_dpm.h" | 28 | #include "r600_dpm.h" |
| 28 | #include "cypress_dpm.h" | 29 | #include "cypress_dpm.h" |
diff --git a/drivers/gpu/drm/radeon/trinity_dpm.c b/drivers/gpu/drm/radeon/trinity_dpm.c index 57f780053b3e..b4ec5c4e7969 100644 --- a/drivers/gpu/drm/radeon/trinity_dpm.c +++ b/drivers/gpu/drm/radeon/trinity_dpm.c | |||
| @@ -23,6 +23,7 @@ | |||
| 23 | 23 | ||
| 24 | #include "drmP.h" | 24 | #include "drmP.h" |
| 25 | #include "radeon.h" | 25 | #include "radeon.h" |
| 26 | #include "radeon_asic.h" | ||
| 26 | #include "trinityd.h" | 27 | #include "trinityd.h" |
| 27 | #include "r600_dpm.h" | 28 | #include "r600_dpm.h" |
| 28 | #include "trinity_dpm.h" | 29 | #include "trinity_dpm.h" |
diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c index 6553fd238685..054a79f143ae 100644 --- a/drivers/gpu/drm/tegra/dc.c +++ b/drivers/gpu/drm/tegra/dc.c | |||
| @@ -736,7 +736,6 @@ static const struct drm_crtc_funcs tegra_crtc_funcs = { | |||
| 736 | 736 | ||
| 737 | static void tegra_crtc_disable(struct drm_crtc *crtc) | 737 | static void tegra_crtc_disable(struct drm_crtc *crtc) |
| 738 | { | 738 | { |
| 739 | struct tegra_dc *dc = to_tegra_dc(crtc); | ||
| 740 | struct drm_device *drm = crtc->dev; | 739 | struct drm_device *drm = crtc->dev; |
| 741 | struct drm_plane *plane; | 740 | struct drm_plane *plane; |
| 742 | 741 | ||
| @@ -752,7 +751,7 @@ static void tegra_crtc_disable(struct drm_crtc *crtc) | |||
| 752 | } | 751 | } |
| 753 | } | 752 | } |
| 754 | 753 | ||
| 755 | drm_vblank_off(drm, dc->pipe); | 754 | drm_crtc_vblank_off(crtc); |
| 756 | } | 755 | } |
| 757 | 756 | ||
| 758 | static bool tegra_crtc_mode_fixup(struct drm_crtc *crtc, | 757 | static bool tegra_crtc_mode_fixup(struct drm_crtc *crtc, |
| @@ -841,8 +840,6 @@ static int tegra_crtc_mode_set(struct drm_crtc *crtc, | |||
| 841 | u32 value; | 840 | u32 value; |
| 842 | int err; | 841 | int err; |
| 843 | 842 | ||
| 844 | drm_vblank_pre_modeset(crtc->dev, dc->pipe); | ||
| 845 | |||
| 846 | err = tegra_crtc_setup_clk(crtc, mode); | 843 | err = tegra_crtc_setup_clk(crtc, mode); |
| 847 | if (err) { | 844 | if (err) { |
| 848 | dev_err(dc->dev, "failed to setup clock for CRTC: %d\n", err); | 845 | dev_err(dc->dev, "failed to setup clock for CRTC: %d\n", err); |
| @@ -896,6 +893,8 @@ static void tegra_crtc_prepare(struct drm_crtc *crtc) | |||
| 896 | unsigned int syncpt; | 893 | unsigned int syncpt; |
| 897 | unsigned long value; | 894 | unsigned long value; |
| 898 | 895 | ||
| 896 | drm_crtc_vblank_off(crtc); | ||
| 897 | |||
| 899 | /* hardware initialization */ | 898 | /* hardware initialization */ |
| 900 | reset_control_deassert(dc->rst); | 899 | reset_control_deassert(dc->rst); |
| 901 | usleep_range(10000, 20000); | 900 | usleep_range(10000, 20000); |
| @@ -943,7 +942,7 @@ static void tegra_crtc_commit(struct drm_crtc *crtc) | |||
| 943 | value = GENERAL_ACT_REQ | WIN_A_ACT_REQ; | 942 | value = GENERAL_ACT_REQ | WIN_A_ACT_REQ; |
| 944 | tegra_dc_writel(dc, value, DC_CMD_STATE_CONTROL); | 943 | tegra_dc_writel(dc, value, DC_CMD_STATE_CONTROL); |
| 945 | 944 | ||
| 946 | drm_vblank_post_modeset(crtc->dev, dc->pipe); | 945 | drm_crtc_vblank_on(crtc); |
| 947 | } | 946 | } |
| 948 | 947 | ||
| 949 | static void tegra_crtc_load_lut(struct drm_crtc *crtc) | 948 | static void tegra_crtc_load_lut(struct drm_crtc *crtc) |
diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c index 8f5cec67c47d..d395b0bef73b 100644 --- a/drivers/gpu/drm/ttm/ttm_bo.c +++ b/drivers/gpu/drm/ttm/ttm_bo.c | |||
| @@ -709,6 +709,7 @@ out: | |||
| 709 | 709 | ||
| 710 | static int ttm_mem_evict_first(struct ttm_bo_device *bdev, | 710 | static int ttm_mem_evict_first(struct ttm_bo_device *bdev, |
| 711 | uint32_t mem_type, | 711 | uint32_t mem_type, |
| 712 | const struct ttm_place *place, | ||
| 712 | bool interruptible, | 713 | bool interruptible, |
| 713 | bool no_wait_gpu) | 714 | bool no_wait_gpu) |
| 714 | { | 715 | { |
| @@ -720,8 +721,21 @@ static int ttm_mem_evict_first(struct ttm_bo_device *bdev, | |||
| 720 | spin_lock(&glob->lru_lock); | 721 | spin_lock(&glob->lru_lock); |
| 721 | list_for_each_entry(bo, &man->lru, lru) { | 722 | list_for_each_entry(bo, &man->lru, lru) { |
| 722 | ret = __ttm_bo_reserve(bo, false, true, false, NULL); | 723 | ret = __ttm_bo_reserve(bo, false, true, false, NULL); |
| 723 | if (!ret) | 724 | if (!ret) { |
| 725 | if (place && (place->fpfn || place->lpfn)) { | ||
| 726 | /* Don't evict this BO if it's outside of the | ||
| 727 | * requested placement range | ||
| 728 | */ | ||
| 729 | if (place->fpfn >= (bo->mem.start + bo->mem.size) || | ||
| 730 | (place->lpfn && place->lpfn <= bo->mem.start)) { | ||
| 731 | __ttm_bo_unreserve(bo); | ||
| 732 | ret = -EBUSY; | ||
| 733 | continue; | ||
| 734 | } | ||
| 735 | } | ||
| 736 | |||
| 724 | break; | 737 | break; |
| 738 | } | ||
| 725 | } | 739 | } |
| 726 | 740 | ||
| 727 | if (ret) { | 741 | if (ret) { |
| @@ -782,7 +796,7 @@ static int ttm_bo_mem_force_space(struct ttm_buffer_object *bo, | |||
| 782 | return ret; | 796 | return ret; |
| 783 | if (mem->mm_node) | 797 | if (mem->mm_node) |
| 784 | break; | 798 | break; |
| 785 | ret = ttm_mem_evict_first(bdev, mem_type, | 799 | ret = ttm_mem_evict_first(bdev, mem_type, place, |
| 786 | interruptible, no_wait_gpu); | 800 | interruptible, no_wait_gpu); |
| 787 | if (unlikely(ret != 0)) | 801 | if (unlikely(ret != 0)) |
| 788 | return ret; | 802 | return ret; |
| @@ -994,9 +1008,9 @@ static bool ttm_bo_mem_compat(struct ttm_placement *placement, | |||
| 994 | 1008 | ||
| 995 | for (i = 0; i < placement->num_placement; i++) { | 1009 | for (i = 0; i < placement->num_placement; i++) { |
| 996 | const struct ttm_place *heap = &placement->placement[i]; | 1010 | const struct ttm_place *heap = &placement->placement[i]; |
| 997 | if (mem->mm_node && heap->lpfn != 0 && | 1011 | if (mem->mm_node && |
| 998 | (mem->start < heap->fpfn || | 1012 | (mem->start < heap->fpfn || |
| 999 | mem->start + mem->num_pages > heap->lpfn)) | 1013 | (heap->lpfn != 0 && (mem->start + mem->num_pages) > heap->lpfn))) |
| 1000 | continue; | 1014 | continue; |
| 1001 | 1015 | ||
| 1002 | *new_flags = heap->flags; | 1016 | *new_flags = heap->flags; |
| @@ -1007,9 +1021,9 @@ static bool ttm_bo_mem_compat(struct ttm_placement *placement, | |||
| 1007 | 1021 | ||
| 1008 | for (i = 0; i < placement->num_busy_placement; i++) { | 1022 | for (i = 0; i < placement->num_busy_placement; i++) { |
| 1009 | const struct ttm_place *heap = &placement->busy_placement[i]; | 1023 | const struct ttm_place *heap = &placement->busy_placement[i]; |
| 1010 | if (mem->mm_node && heap->lpfn != 0 && | 1024 | if (mem->mm_node && |
| 1011 | (mem->start < heap->fpfn || | 1025 | (mem->start < heap->fpfn || |
| 1012 | mem->start + mem->num_pages > heap->lpfn)) | 1026 | (heap->lpfn != 0 && (mem->start + mem->num_pages) > heap->lpfn))) |
| 1013 | continue; | 1027 | continue; |
| 1014 | 1028 | ||
| 1015 | *new_flags = heap->flags; | 1029 | *new_flags = heap->flags; |
| @@ -1233,7 +1247,7 @@ static int ttm_bo_force_list_clean(struct ttm_bo_device *bdev, | |||
| 1233 | spin_lock(&glob->lru_lock); | 1247 | spin_lock(&glob->lru_lock); |
| 1234 | while (!list_empty(&man->lru)) { | 1248 | while (!list_empty(&man->lru)) { |
| 1235 | spin_unlock(&glob->lru_lock); | 1249 | spin_unlock(&glob->lru_lock); |
| 1236 | ret = ttm_mem_evict_first(bdev, mem_type, false, false); | 1250 | ret = ttm_mem_evict_first(bdev, mem_type, NULL, false, false); |
| 1237 | if (ret) { | 1251 | if (ret) { |
| 1238 | if (allow_errors) { | 1252 | if (allow_errors) { |
| 1239 | return ret; | 1253 | return ret; |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf_res.c b/drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf_res.c index bfeb4b1f2acf..21e9b7f8dad0 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf_res.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf_res.c | |||
| @@ -246,7 +246,8 @@ int vmw_cmdbuf_res_remove(struct vmw_cmdbuf_res_manager *man, | |||
| 246 | struct drm_hash_item *hash; | 246 | struct drm_hash_item *hash; |
| 247 | int ret; | 247 | int ret; |
| 248 | 248 | ||
| 249 | ret = drm_ht_find_item(&man->resources, user_key, &hash); | 249 | ret = drm_ht_find_item(&man->resources, user_key | (res_type << 24), |
| 250 | &hash); | ||
| 250 | if (likely(ret != 0)) | 251 | if (likely(ret != 0)) |
| 251 | return -EINVAL; | 252 | return -EINVAL; |
| 252 | 253 | ||
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c index 7197af157313..25f3c250fd98 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c | |||
| @@ -688,7 +688,11 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset) | |||
| 688 | goto out_err0; | 688 | goto out_err0; |
| 689 | } | 689 | } |
| 690 | 690 | ||
| 691 | if (unlikely(dev_priv->prim_bb_mem < dev_priv->vram_size)) | 691 | /* |
| 692 | * Limit back buffer size to VRAM size. Remove this once | ||
| 693 | * screen targets are implemented. | ||
| 694 | */ | ||
| 695 | if (dev_priv->prim_bb_mem > dev_priv->vram_size) | ||
| 692 | dev_priv->prim_bb_mem = dev_priv->vram_size; | 696 | dev_priv->prim_bb_mem = dev_priv->vram_size; |
| 693 | 697 | ||
| 694 | mutex_unlock(&dev_priv->hw_mutex); | 698 | mutex_unlock(&dev_priv->hw_mutex); |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c index d2bc2b03d4c6..941a7bc0b791 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | |||
| @@ -187,7 +187,7 @@ int vmw_du_crtc_cursor_set(struct drm_crtc *crtc, struct drm_file *file_priv, | |||
| 187 | * can do this since the caller in the drm core doesn't check anything | 187 | * can do this since the caller in the drm core doesn't check anything |
| 188 | * which is protected by any looks. | 188 | * which is protected by any looks. |
| 189 | */ | 189 | */ |
| 190 | drm_modeset_unlock(&crtc->mutex); | 190 | drm_modeset_unlock_crtc(crtc); |
| 191 | drm_modeset_lock_all(dev_priv->dev); | 191 | drm_modeset_lock_all(dev_priv->dev); |
| 192 | 192 | ||
| 193 | /* A lot of the code assumes this */ | 193 | /* A lot of the code assumes this */ |
| @@ -252,7 +252,7 @@ int vmw_du_crtc_cursor_set(struct drm_crtc *crtc, struct drm_file *file_priv, | |||
| 252 | ret = 0; | 252 | ret = 0; |
| 253 | out: | 253 | out: |
| 254 | drm_modeset_unlock_all(dev_priv->dev); | 254 | drm_modeset_unlock_all(dev_priv->dev); |
| 255 | drm_modeset_lock(&crtc->mutex, NULL); | 255 | drm_modeset_lock_crtc(crtc); |
| 256 | 256 | ||
| 257 | return ret; | 257 | return ret; |
| 258 | } | 258 | } |
| @@ -273,7 +273,7 @@ int vmw_du_crtc_cursor_move(struct drm_crtc *crtc, int x, int y) | |||
| 273 | * can do this since the caller in the drm core doesn't check anything | 273 | * can do this since the caller in the drm core doesn't check anything |
| 274 | * which is protected by any looks. | 274 | * which is protected by any looks. |
| 275 | */ | 275 | */ |
| 276 | drm_modeset_unlock(&crtc->mutex); | 276 | drm_modeset_unlock_crtc(crtc); |
| 277 | drm_modeset_lock_all(dev_priv->dev); | 277 | drm_modeset_lock_all(dev_priv->dev); |
| 278 | 278 | ||
| 279 | vmw_cursor_update_position(dev_priv, shown, | 279 | vmw_cursor_update_position(dev_priv, shown, |
| @@ -281,7 +281,7 @@ int vmw_du_crtc_cursor_move(struct drm_crtc *crtc, int x, int y) | |||
| 281 | du->cursor_y + du->hotspot_y); | 281 | du->cursor_y + du->hotspot_y); |
| 282 | 282 | ||
| 283 | drm_modeset_unlock_all(dev_priv->dev); | 283 | drm_modeset_unlock_all(dev_priv->dev); |
| 284 | drm_modeset_lock(&crtc->mutex, NULL); | 284 | drm_modeset_lock_crtc(crtc); |
| 285 | 285 | ||
| 286 | return 0; | 286 | return 0; |
| 287 | } | 287 | } |
| @@ -1950,6 +1950,14 @@ int vmw_du_connector_fill_modes(struct drm_connector *connector, | |||
| 1950 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) | 1950 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) |
| 1951 | }; | 1951 | }; |
| 1952 | int i; | 1952 | int i; |
| 1953 | u32 assumed_bpp = 2; | ||
| 1954 | |||
| 1955 | /* | ||
| 1956 | * If using screen objects, then assume 32-bpp because that's what the | ||
| 1957 | * SVGA device is assuming | ||
| 1958 | */ | ||
| 1959 | if (dev_priv->sou_priv) | ||
| 1960 | assumed_bpp = 4; | ||
| 1953 | 1961 | ||
| 1954 | /* Add preferred mode */ | 1962 | /* Add preferred mode */ |
| 1955 | { | 1963 | { |
| @@ -1960,8 +1968,9 @@ int vmw_du_connector_fill_modes(struct drm_connector *connector, | |||
| 1960 | mode->vdisplay = du->pref_height; | 1968 | mode->vdisplay = du->pref_height; |
| 1961 | vmw_guess_mode_timing(mode); | 1969 | vmw_guess_mode_timing(mode); |
| 1962 | 1970 | ||
| 1963 | if (vmw_kms_validate_mode_vram(dev_priv, mode->hdisplay * 2, | 1971 | if (vmw_kms_validate_mode_vram(dev_priv, |
| 1964 | mode->vdisplay)) { | 1972 | mode->hdisplay * assumed_bpp, |
| 1973 | mode->vdisplay)) { | ||
| 1965 | drm_mode_probed_add(connector, mode); | 1974 | drm_mode_probed_add(connector, mode); |
| 1966 | } else { | 1975 | } else { |
| 1967 | drm_mode_destroy(dev, mode); | 1976 | drm_mode_destroy(dev, mode); |
| @@ -1983,7 +1992,8 @@ int vmw_du_connector_fill_modes(struct drm_connector *connector, | |||
| 1983 | bmode->vdisplay > max_height) | 1992 | bmode->vdisplay > max_height) |
| 1984 | continue; | 1993 | continue; |
| 1985 | 1994 | ||
| 1986 | if (!vmw_kms_validate_mode_vram(dev_priv, bmode->hdisplay * 2, | 1995 | if (!vmw_kms_validate_mode_vram(dev_priv, |
| 1996 | bmode->hdisplay * assumed_bpp, | ||
| 1987 | bmode->vdisplay)) | 1997 | bmode->vdisplay)) |
| 1988 | continue; | 1998 | continue; |
| 1989 | 1999 | ||
