diff options
author | Dave Airlie <airlied@redhat.com> | 2013-11-05 01:22:08 -0500 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2013-11-05 01:22:08 -0500 |
commit | bbf1f8bfef7fbe1ea5634d7559770b805510ad8d (patch) | |
tree | f3c8ee9642cec7d1508c422292f8bdf0aa37a7f4 /drivers/gpu/drm/radeon/radeon_connectors.c | |
parent | 90c37067b70d6090a316227698a0cba40f8003bd (diff) | |
parent | 70471860ff9f335c60c004d42ebd48945bfa5403 (diff) |
Merge branch 'drm-next-3.13' of git://people.freedesktop.org/~agd5f/linux into drm-next
Initial pull request for radeon drm-next 3.13. Highlights:
- Enable DPM on a number of asics by default
- Enable audio by default
- Dynamically power down dGPUs on PowerXpress systems
- Lots of bug fixes
* 'drm-next-3.13' of git://people.freedesktop.org/~agd5f/linux: (36 commits)
drm/radeon: don't share PPLLs on DCE4.1
drm/radeon/dpm: fix typo in setting smc flag
drm/radeon: fixup locking inversion between, mmap_sem and reservations
drm/radeon: clear the page directory using the DMA
drm/radeon: initially clear page tables
drm/radeon: drop CP page table updates & cleanup v2
drm/radeon: add vm_set_page tracepoint
drm/radeon: rework and fix reset detection v2
drm/radeon: don't use PACKET2 on CIK
drm/radeon: fix UVD destroy IB size
drm/radeon: activate UVD clocks before sending the destroy msg
drm/radeon/si: fix define for MC_SEQ_TRAIN_WAKEUP_CNTL
drm/radeon: fix endian handling in rlc buffer setup
drm/radeon/dpm: retain user selected performance level across state changes
drm/radeon: disable force performance state when thermal state is active
drm/radeon: enable DPM by default on r7xx asics
drm/radeon: enable DPM by default on evergreen asics
drm/radeon: enable DPM by default on BTC asics
drm/radeon: enable DPM by default on SI asics
drm/radeon: enable DPM by default on SUMO/PALM APUs
...
Diffstat (limited to 'drivers/gpu/drm/radeon/radeon_connectors.c')
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_connectors.c | 104 |
1 files changed, 92 insertions, 12 deletions
diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c index 79159b5da05b..e972143e5a36 100644 --- a/drivers/gpu/drm/radeon/radeon_connectors.c +++ b/drivers/gpu/drm/radeon/radeon_connectors.c | |||
@@ -31,6 +31,8 @@ | |||
31 | #include "radeon.h" | 31 | #include "radeon.h" |
32 | #include "atom.h" | 32 | #include "atom.h" |
33 | 33 | ||
34 | #include <linux/pm_runtime.h> | ||
35 | |||
34 | extern void | 36 | extern void |
35 | radeon_combios_connected_scratch_regs(struct drm_connector *connector, | 37 | radeon_combios_connected_scratch_regs(struct drm_connector *connector, |
36 | struct drm_encoder *encoder, | 38 | struct drm_encoder *encoder, |
@@ -411,6 +413,21 @@ static int radeon_connector_set_property(struct drm_connector *connector, struct | |||
411 | } | 413 | } |
412 | } | 414 | } |
413 | 415 | ||
416 | if (property == rdev->mode_info.dither_property) { | ||
417 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | ||
418 | /* need to find digital encoder on connector */ | ||
419 | encoder = radeon_find_encoder(connector, DRM_MODE_ENCODER_TMDS); | ||
420 | if (!encoder) | ||
421 | return 0; | ||
422 | |||
423 | radeon_encoder = to_radeon_encoder(encoder); | ||
424 | |||
425 | if (radeon_connector->dither != val) { | ||
426 | radeon_connector->dither = val; | ||
427 | radeon_property_change_mode(&radeon_encoder->base); | ||
428 | } | ||
429 | } | ||
430 | |||
414 | if (property == rdev->mode_info.underscan_property) { | 431 | if (property == rdev->mode_info.underscan_property) { |
415 | /* need to find digital encoder on connector */ | 432 | /* need to find digital encoder on connector */ |
416 | encoder = radeon_find_encoder(connector, DRM_MODE_ENCODER_TMDS); | 433 | encoder = radeon_find_encoder(connector, DRM_MODE_ENCODER_TMDS); |
@@ -626,6 +643,11 @@ radeon_lvds_detect(struct drm_connector *connector, bool force) | |||
626 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | 643 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); |
627 | struct drm_encoder *encoder = radeon_best_single_encoder(connector); | 644 | struct drm_encoder *encoder = radeon_best_single_encoder(connector); |
628 | enum drm_connector_status ret = connector_status_disconnected; | 645 | enum drm_connector_status ret = connector_status_disconnected; |
646 | int r; | ||
647 | |||
648 | r = pm_runtime_get_sync(connector->dev->dev); | ||
649 | if (r < 0) | ||
650 | return connector_status_disconnected; | ||
629 | 651 | ||
630 | if (encoder) { | 652 | if (encoder) { |
631 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | 653 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
@@ -651,6 +673,8 @@ radeon_lvds_detect(struct drm_connector *connector, bool force) | |||
651 | /* check acpi lid status ??? */ | 673 | /* check acpi lid status ??? */ |
652 | 674 | ||
653 | radeon_connector_update_scratch_regs(connector, ret); | 675 | radeon_connector_update_scratch_regs(connector, ret); |
676 | pm_runtime_mark_last_busy(connector->dev->dev); | ||
677 | pm_runtime_put_autosuspend(connector->dev->dev); | ||
654 | return ret; | 678 | return ret; |
655 | } | 679 | } |
656 | 680 | ||
@@ -750,6 +774,11 @@ radeon_vga_detect(struct drm_connector *connector, bool force) | |||
750 | struct drm_encoder_helper_funcs *encoder_funcs; | 774 | struct drm_encoder_helper_funcs *encoder_funcs; |
751 | bool dret = false; | 775 | bool dret = false; |
752 | enum drm_connector_status ret = connector_status_disconnected; | 776 | enum drm_connector_status ret = connector_status_disconnected; |
777 | int r; | ||
778 | |||
779 | r = pm_runtime_get_sync(connector->dev->dev); | ||
780 | if (r < 0) | ||
781 | return connector_status_disconnected; | ||
753 | 782 | ||
754 | encoder = radeon_best_single_encoder(connector); | 783 | encoder = radeon_best_single_encoder(connector); |
755 | if (!encoder) | 784 | if (!encoder) |
@@ -790,9 +819,8 @@ radeon_vga_detect(struct drm_connector *connector, bool force) | |||
790 | * detected a monitor via load. | 819 | * detected a monitor via load. |
791 | */ | 820 | */ |
792 | if (radeon_connector->detected_by_load) | 821 | if (radeon_connector->detected_by_load) |
793 | return connector->status; | 822 | ret = connector->status; |
794 | else | 823 | goto out; |
795 | return ret; | ||
796 | } | 824 | } |
797 | 825 | ||
798 | if (radeon_connector->dac_load_detect && encoder) { | 826 | if (radeon_connector->dac_load_detect && encoder) { |
@@ -817,6 +845,11 @@ radeon_vga_detect(struct drm_connector *connector, bool force) | |||
817 | } | 845 | } |
818 | 846 | ||
819 | radeon_connector_update_scratch_regs(connector, ret); | 847 | radeon_connector_update_scratch_regs(connector, ret); |
848 | |||
849 | out: | ||
850 | pm_runtime_mark_last_busy(connector->dev->dev); | ||
851 | pm_runtime_put_autosuspend(connector->dev->dev); | ||
852 | |||
820 | return ret; | 853 | return ret; |
821 | } | 854 | } |
822 | 855 | ||
@@ -873,10 +906,15 @@ radeon_tv_detect(struct drm_connector *connector, bool force) | |||
873 | struct drm_encoder_helper_funcs *encoder_funcs; | 906 | struct drm_encoder_helper_funcs *encoder_funcs; |
874 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | 907 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); |
875 | enum drm_connector_status ret = connector_status_disconnected; | 908 | enum drm_connector_status ret = connector_status_disconnected; |
909 | int r; | ||
876 | 910 | ||
877 | if (!radeon_connector->dac_load_detect) | 911 | if (!radeon_connector->dac_load_detect) |
878 | return ret; | 912 | return ret; |
879 | 913 | ||
914 | r = pm_runtime_get_sync(connector->dev->dev); | ||
915 | if (r < 0) | ||
916 | return connector_status_disconnected; | ||
917 | |||
880 | encoder = radeon_best_single_encoder(connector); | 918 | encoder = radeon_best_single_encoder(connector); |
881 | if (!encoder) | 919 | if (!encoder) |
882 | ret = connector_status_disconnected; | 920 | ret = connector_status_disconnected; |
@@ -887,6 +925,8 @@ radeon_tv_detect(struct drm_connector *connector, bool force) | |||
887 | if (ret == connector_status_connected) | 925 | if (ret == connector_status_connected) |
888 | ret = radeon_connector_analog_encoder_conflict_solve(connector, encoder, ret, false); | 926 | ret = radeon_connector_analog_encoder_conflict_solve(connector, encoder, ret, false); |
889 | radeon_connector_update_scratch_regs(connector, ret); | 927 | radeon_connector_update_scratch_regs(connector, ret); |
928 | pm_runtime_mark_last_busy(connector->dev->dev); | ||
929 | pm_runtime_put_autosuspend(connector->dev->dev); | ||
890 | return ret; | 930 | return ret; |
891 | } | 931 | } |
892 | 932 | ||
@@ -954,12 +994,18 @@ radeon_dvi_detect(struct drm_connector *connector, bool force) | |||
954 | struct drm_encoder *encoder = NULL; | 994 | struct drm_encoder *encoder = NULL; |
955 | struct drm_encoder_helper_funcs *encoder_funcs; | 995 | struct drm_encoder_helper_funcs *encoder_funcs; |
956 | struct drm_mode_object *obj; | 996 | struct drm_mode_object *obj; |
957 | int i; | 997 | int i, r; |
958 | enum drm_connector_status ret = connector_status_disconnected; | 998 | enum drm_connector_status ret = connector_status_disconnected; |
959 | bool dret = false, broken_edid = false; | 999 | bool dret = false, broken_edid = false; |
960 | 1000 | ||
961 | if (!force && radeon_check_hpd_status_unchanged(connector)) | 1001 | r = pm_runtime_get_sync(connector->dev->dev); |
962 | return connector->status; | 1002 | if (r < 0) |
1003 | return connector_status_disconnected; | ||
1004 | |||
1005 | if (!force && radeon_check_hpd_status_unchanged(connector)) { | ||
1006 | ret = connector->status; | ||
1007 | goto exit; | ||
1008 | } | ||
963 | 1009 | ||
964 | if (radeon_connector->ddc_bus) | 1010 | if (radeon_connector->ddc_bus) |
965 | dret = radeon_ddc_probe(radeon_connector, false); | 1011 | dret = radeon_ddc_probe(radeon_connector, false); |
@@ -1110,6 +1156,11 @@ out: | |||
1110 | 1156 | ||
1111 | /* updated in get modes as well since we need to know if it's analog or digital */ | 1157 | /* updated in get modes as well since we need to know if it's analog or digital */ |
1112 | radeon_connector_update_scratch_regs(connector, ret); | 1158 | radeon_connector_update_scratch_regs(connector, ret); |
1159 | |||
1160 | exit: | ||
1161 | pm_runtime_mark_last_busy(connector->dev->dev); | ||
1162 | pm_runtime_put_autosuspend(connector->dev->dev); | ||
1163 | |||
1113 | return ret; | 1164 | return ret; |
1114 | } | 1165 | } |
1115 | 1166 | ||
@@ -1377,9 +1428,16 @@ radeon_dp_detect(struct drm_connector *connector, bool force) | |||
1377 | enum drm_connector_status ret = connector_status_disconnected; | 1428 | enum drm_connector_status ret = connector_status_disconnected; |
1378 | struct radeon_connector_atom_dig *radeon_dig_connector = radeon_connector->con_priv; | 1429 | struct radeon_connector_atom_dig *radeon_dig_connector = radeon_connector->con_priv; |
1379 | struct drm_encoder *encoder = radeon_best_single_encoder(connector); | 1430 | struct drm_encoder *encoder = radeon_best_single_encoder(connector); |
1431 | int r; | ||
1380 | 1432 | ||
1381 | if (!force && radeon_check_hpd_status_unchanged(connector)) | 1433 | r = pm_runtime_get_sync(connector->dev->dev); |
1382 | return connector->status; | 1434 | if (r < 0) |
1435 | return connector_status_disconnected; | ||
1436 | |||
1437 | if (!force && radeon_check_hpd_status_unchanged(connector)) { | ||
1438 | ret = connector->status; | ||
1439 | goto out; | ||
1440 | } | ||
1383 | 1441 | ||
1384 | if (radeon_connector->edid) { | 1442 | if (radeon_connector->edid) { |
1385 | kfree(radeon_connector->edid); | 1443 | kfree(radeon_connector->edid); |
@@ -1443,6 +1501,10 @@ radeon_dp_detect(struct drm_connector *connector, bool force) | |||
1443 | } | 1501 | } |
1444 | 1502 | ||
1445 | radeon_connector_update_scratch_regs(connector, ret); | 1503 | radeon_connector_update_scratch_regs(connector, ret); |
1504 | out: | ||
1505 | pm_runtime_mark_last_busy(connector->dev->dev); | ||
1506 | pm_runtime_put_autosuspend(connector->dev->dev); | ||
1507 | |||
1446 | return ret; | 1508 | return ret; |
1447 | } | 1509 | } |
1448 | 1510 | ||
@@ -1660,7 +1722,10 @@ radeon_add_atom_connector(struct drm_device *dev, | |||
1660 | 0); | 1722 | 0); |
1661 | drm_object_attach_property(&radeon_connector->base.base, | 1723 | drm_object_attach_property(&radeon_connector->base.base, |
1662 | rdev->mode_info.audio_property, | 1724 | rdev->mode_info.audio_property, |
1663 | RADEON_AUDIO_DISABLE); | 1725 | RADEON_AUDIO_AUTO); |
1726 | drm_object_attach_property(&radeon_connector->base.base, | ||
1727 | rdev->mode_info.dither_property, | ||
1728 | RADEON_FMT_DITHER_DISABLE); | ||
1664 | subpixel_order = SubPixelHorizontalRGB; | 1729 | subpixel_order = SubPixelHorizontalRGB; |
1665 | connector->interlace_allowed = true; | 1730 | connector->interlace_allowed = true; |
1666 | if (connector_type == DRM_MODE_CONNECTOR_HDMIB) | 1731 | if (connector_type == DRM_MODE_CONNECTOR_HDMIB) |
@@ -1757,7 +1822,12 @@ radeon_add_atom_connector(struct drm_device *dev, | |||
1757 | if (ASIC_IS_DCE2(rdev)) { | 1822 | if (ASIC_IS_DCE2(rdev)) { |
1758 | drm_object_attach_property(&radeon_connector->base.base, | 1823 | drm_object_attach_property(&radeon_connector->base.base, |
1759 | rdev->mode_info.audio_property, | 1824 | rdev->mode_info.audio_property, |
1760 | RADEON_AUDIO_DISABLE); | 1825 | RADEON_AUDIO_AUTO); |
1826 | } | ||
1827 | if (ASIC_IS_AVIVO(rdev)) { | ||
1828 | drm_object_attach_property(&radeon_connector->base.base, | ||
1829 | rdev->mode_info.dither_property, | ||
1830 | RADEON_FMT_DITHER_DISABLE); | ||
1761 | } | 1831 | } |
1762 | if (connector_type == DRM_MODE_CONNECTOR_DVII) { | 1832 | if (connector_type == DRM_MODE_CONNECTOR_DVII) { |
1763 | radeon_connector->dac_load_detect = true; | 1833 | radeon_connector->dac_load_detect = true; |
@@ -1802,7 +1872,12 @@ radeon_add_atom_connector(struct drm_device *dev, | |||
1802 | if (ASIC_IS_DCE2(rdev)) { | 1872 | if (ASIC_IS_DCE2(rdev)) { |
1803 | drm_object_attach_property(&radeon_connector->base.base, | 1873 | drm_object_attach_property(&radeon_connector->base.base, |
1804 | rdev->mode_info.audio_property, | 1874 | rdev->mode_info.audio_property, |
1805 | RADEON_AUDIO_DISABLE); | 1875 | RADEON_AUDIO_AUTO); |
1876 | } | ||
1877 | if (ASIC_IS_AVIVO(rdev)) { | ||
1878 | drm_object_attach_property(&radeon_connector->base.base, | ||
1879 | rdev->mode_info.dither_property, | ||
1880 | RADEON_FMT_DITHER_DISABLE); | ||
1806 | } | 1881 | } |
1807 | subpixel_order = SubPixelHorizontalRGB; | 1882 | subpixel_order = SubPixelHorizontalRGB; |
1808 | connector->interlace_allowed = true; | 1883 | connector->interlace_allowed = true; |
@@ -1846,7 +1921,12 @@ radeon_add_atom_connector(struct drm_device *dev, | |||
1846 | if (ASIC_IS_DCE2(rdev)) { | 1921 | if (ASIC_IS_DCE2(rdev)) { |
1847 | drm_object_attach_property(&radeon_connector->base.base, | 1922 | drm_object_attach_property(&radeon_connector->base.base, |
1848 | rdev->mode_info.audio_property, | 1923 | rdev->mode_info.audio_property, |
1849 | RADEON_AUDIO_DISABLE); | 1924 | RADEON_AUDIO_AUTO); |
1925 | } | ||
1926 | if (ASIC_IS_AVIVO(rdev)) { | ||
1927 | drm_object_attach_property(&radeon_connector->base.base, | ||
1928 | rdev->mode_info.dither_property, | ||
1929 | RADEON_FMT_DITHER_DISABLE); | ||
1850 | } | 1930 | } |
1851 | connector->interlace_allowed = true; | 1931 | connector->interlace_allowed = true; |
1852 | /* in theory with a DP to VGA converter... */ | 1932 | /* in theory with a DP to VGA converter... */ |