|
1 | 1 | // SPDX-License-Identifier: GPL-2.0-only OR MIT |
2 | | -/* Copyright 2021 Alyssa Rosenzweig */ |
| 2 | +/* Copyright 2021 Alyssa Rosenzweig <alyssa@rosenzweig.io> */ |
3 | 3 | /* Based on meson driver which is |
4 | 4 | * Copyright (C) 2016 BayLibre, SAS |
5 | 5 | * Author: Neil Armstrong <narmstrong@baylibre.com> |
|
38 | 38 | #include <drm/drm_vblank.h> |
39 | 39 | #include <drm/drm_fixed.h> |
40 | 40 |
|
| 41 | +#include <linux/soc/apple/rtkit.h> |
| 42 | + |
41 | 43 | #include "dcp.h" |
| 44 | +#include "dcp-internal.h" |
| 45 | +#include "connector.h" |
42 | 46 | #include "plane.h" |
43 | 47 |
|
44 | 48 | #define DRIVER_NAME "apple" |
@@ -109,8 +113,6 @@ static void apple_crtc_atomic_enable(struct drm_crtc *crtc, |
109 | 113 | if (crtc_state->active_changed && crtc_state->active) { |
110 | 114 | struct apple_crtc *apple_crtc = to_apple_crtc(crtc); |
111 | 115 | dcp_poweron(apple_crtc->dcp); |
112 | | - /* Force the CTM to be set on first swap */ |
113 | | - crtc_state->color_mgmt_changed = true; |
114 | 116 | } |
115 | 117 |
|
116 | 118 | if (crtc_state->active) |
@@ -439,8 +441,9 @@ static int apple_drm_init_dcp(struct device *dev) |
439 | 441 | * (successfully). Ignoring it should not do any harm now. |
440 | 442 | * Needs to reevaluated when adding dcpext support. |
441 | 443 | */ |
442 | | - if (ret) |
| 444 | + if (ret) { |
443 | 445 | dev_warn(dev, "DCP[%d] not ready: %d\n", i, ret); |
| 446 | + } |
444 | 447 | } |
445 | 448 | /* HACK: Wait for dcp* to settle before a modeset */ |
446 | 449 | msleep(100); |
@@ -627,19 +630,50 @@ MODULE_DEVICE_TABLE(of, of_match); |
627 | 630 | static int apple_platform_suspend(struct device *dev) |
628 | 631 | { |
629 | 632 | struct apple_drm_private *apple = dev_get_drvdata(dev); |
| 633 | + struct drm_crtc *crtc; |
| 634 | + int ret; |
630 | 635 |
|
631 | | - if (apple) |
632 | | - return drm_mode_config_helper_suspend(&apple->drm); |
| 636 | + if (apple) { |
| 637 | + ret = drm_mode_config_helper_suspend(&apple->drm); |
| 638 | + if (ret) { |
| 639 | + dev_warn(dev, "drm suspend helper failed: %d, quiescing inactive DCPs\n", ret); |
| 640 | + drm_for_each_crtc(crtc, &apple->drm) { |
| 641 | + struct apple_crtc *acrtc = to_apple_crtc(crtc); |
| 642 | + struct apple_dcp *dcp = platform_get_drvdata(acrtc->dcp); |
| 643 | + |
| 644 | + if (dcp && dcp->connector && !dcp->connector->connected && dcp->rtk) { |
| 645 | + dev_info(dev, "quiescing disconnected DCP %d\n", dcp->index); |
| 646 | + apple_rtkit_quiesce(dcp->rtk); |
| 647 | + } |
| 648 | + } |
| 649 | + } |
| 650 | + } |
633 | 651 |
|
634 | 652 | return 0; |
635 | 653 | } |
636 | 654 |
|
637 | 655 | static int apple_platform_resume(struct device *dev) |
638 | 656 | { |
639 | 657 | struct apple_drm_private *apple = dev_get_drvdata(dev); |
| 658 | + struct drm_crtc *crtc; |
640 | 659 |
|
641 | | - if (apple) |
| 660 | + if (!apple) |
| 661 | + return 0; |
| 662 | + |
| 663 | + if (apple->drm.mode_config.suspend_state) { |
642 | 664 | drm_mode_config_helper_resume(&apple->drm); |
| 665 | + } else { |
| 666 | + drm_for_each_crtc(crtc, &apple->drm) { |
| 667 | + struct apple_crtc *acrtc = to_apple_crtc(crtc); |
| 668 | + struct apple_dcp *dcp = platform_get_drvdata(acrtc->dcp); |
| 669 | + |
| 670 | + if (dcp && dcp->connector && !dcp->connector->connected && dcp->rtk) { |
| 671 | + dev_info(dev, "re-booting DCP %d after quiesce\n", dcp->index); |
| 672 | + apple_rtkit_boot(dcp->rtk); |
| 673 | + } |
| 674 | + } |
| 675 | + drm_kms_helper_hotplug_event(&apple->drm); |
| 676 | + } |
643 | 677 |
|
644 | 678 | return 0; |
645 | 679 | } |
@@ -690,6 +724,6 @@ static void __exit appledrm_unregister(void) |
690 | 724 | module_init(appledrm_register); |
691 | 725 | module_exit(appledrm_unregister); |
692 | 726 |
|
693 | | -MODULE_AUTHOR("Asahi Linux contributors"); |
| 727 | +MODULE_AUTHOR("Alyssa Rosenzweig <alyssa@rosenzweig.io>"); |
694 | 728 | MODULE_DESCRIPTION(DRIVER_DESC); |
695 | 729 | MODULE_LICENSE("Dual MIT/GPL"); |
0 commit comments