diff options
Diffstat (limited to 'drivers/gpu')
79 files changed, 624 insertions, 297 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/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 | ||