diff options
33 files changed, 2948 insertions, 2657 deletions
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index 711d9653abd0..9a2e2a14b3bb 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c | |||
@@ -163,6 +163,7 @@ static struct drm_conn_prop_enum_list drm_connector_enum_list[] = | |||
163 | { DRM_MODE_CONNECTOR_HDMIB, "HDMI-B", 0 }, | 163 | { DRM_MODE_CONNECTOR_HDMIB, "HDMI-B", 0 }, |
164 | { DRM_MODE_CONNECTOR_TV, "TV", 0 }, | 164 | { DRM_MODE_CONNECTOR_TV, "TV", 0 }, |
165 | { DRM_MODE_CONNECTOR_eDP, "eDP", 0 }, | 165 | { DRM_MODE_CONNECTOR_eDP, "eDP", 0 }, |
166 | { DRM_MODE_CONNECTOR_VIRTUAL, "Virtual", 0}, | ||
166 | }; | 167 | }; |
167 | 168 | ||
168 | static struct drm_prop_enum_list drm_encoder_enum_list[] = | 169 | static struct drm_prop_enum_list drm_encoder_enum_list[] = |
@@ -171,6 +172,7 @@ static struct drm_prop_enum_list drm_encoder_enum_list[] = | |||
171 | { DRM_MODE_ENCODER_TMDS, "TMDS" }, | 172 | { DRM_MODE_ENCODER_TMDS, "TMDS" }, |
172 | { DRM_MODE_ENCODER_LVDS, "LVDS" }, | 173 | { DRM_MODE_ENCODER_LVDS, "LVDS" }, |
173 | { DRM_MODE_ENCODER_TVDAC, "TV" }, | 174 | { DRM_MODE_ENCODER_TVDAC, "TV" }, |
175 | { DRM_MODE_ENCODER_VIRTUAL, "Virtual" }, | ||
174 | }; | 176 | }; |
175 | 177 | ||
176 | char *drm_get_encoder_name(struct drm_encoder *encoder) | 178 | char *drm_get_encoder_name(struct drm_encoder *encoder) |
@@ -464,8 +466,10 @@ void drm_connector_init(struct drm_device *dev, | |||
464 | list_add_tail(&connector->head, &dev->mode_config.connector_list); | 466 | list_add_tail(&connector->head, &dev->mode_config.connector_list); |
465 | dev->mode_config.num_connector++; | 467 | dev->mode_config.num_connector++; |
466 | 468 | ||
467 | drm_connector_attach_property(connector, | 469 | if (connector_type != DRM_MODE_CONNECTOR_VIRTUAL) |
468 | dev->mode_config.edid_property, 0); | 470 | drm_connector_attach_property(connector, |
471 | dev->mode_config.edid_property, | ||
472 | 0); | ||
469 | 473 | ||
470 | drm_connector_attach_property(connector, | 474 | drm_connector_attach_property(connector, |
471 | dev->mode_config.dpms_property, 0); | 475 | dev->mode_config.dpms_property, 0); |
diff --git a/drivers/gpu/drm/radeon/Makefile b/drivers/gpu/drm/radeon/Makefile index 9f363e0c4b60..cf8b4bc3e73d 100644 --- a/drivers/gpu/drm/radeon/Makefile +++ b/drivers/gpu/drm/radeon/Makefile | |||
@@ -70,7 +70,7 @@ radeon-y += radeon_device.o radeon_asic.o radeon_kms.o \ | |||
70 | r200.o radeon_legacy_tv.o r600_cs.o r600_blit.o r600_blit_shaders.o \ | 70 | r200.o radeon_legacy_tv.o r600_cs.o r600_blit.o r600_blit_shaders.o \ |
71 | r600_blit_kms.o radeon_pm.o atombios_dp.o r600_audio.o r600_hdmi.o \ | 71 | r600_blit_kms.o radeon_pm.o atombios_dp.o r600_audio.o r600_hdmi.o \ |
72 | evergreen.o evergreen_cs.o evergreen_blit_shaders.o evergreen_blit_kms.o \ | 72 | evergreen.o evergreen_cs.o evergreen_blit_shaders.o evergreen_blit_kms.o \ |
73 | radeon_trace_points.o ni.o cayman_blit_shaders.o | 73 | radeon_trace_points.o ni.o cayman_blit_shaders.o atombios_encoders.o |
74 | 74 | ||
75 | radeon-$(CONFIG_COMPAT) += radeon_ioc32.o | 75 | radeon-$(CONFIG_COMPAT) += radeon_ioc32.o |
76 | radeon-$(CONFIG_VGA_SWITCHEROO) += radeon_atpx_handler.o | 76 | radeon-$(CONFIG_VGA_SWITCHEROO) += radeon_atpx_handler.o |
diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c index a515b2a09d85..87921c88a95c 100644 --- a/drivers/gpu/drm/radeon/atombios_crtc.c +++ b/drivers/gpu/drm/radeon/atombios_crtc.c | |||
@@ -558,7 +558,7 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc, | |||
558 | bpc = connector->display_info.bpc; | 558 | bpc = connector->display_info.bpc; |
559 | encoder_mode = atombios_get_encoder_mode(encoder); | 559 | encoder_mode = atombios_get_encoder_mode(encoder); |
560 | if ((radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT | ATOM_DEVICE_DFP_SUPPORT)) || | 560 | if ((radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT | ATOM_DEVICE_DFP_SUPPORT)) || |
561 | radeon_encoder_is_dp_bridge(encoder)) { | 561 | (radeon_encoder_get_dp_bridge_encoder_id(encoder) != ENCODER_OBJECT_ID_NONE)) { |
562 | if (connector) { | 562 | if (connector) { |
563 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | 563 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); |
564 | struct radeon_connector_atom_dig *dig_connector = | 564 | struct radeon_connector_atom_dig *dig_connector = |
@@ -638,44 +638,29 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc, | |||
638 | if (ss_enabled && ss->percentage) | 638 | if (ss_enabled && ss->percentage) |
639 | args.v3.sInput.ucDispPllConfig |= | 639 | args.v3.sInput.ucDispPllConfig |= |
640 | DISPPLL_CONFIG_SS_ENABLE; | 640 | DISPPLL_CONFIG_SS_ENABLE; |
641 | if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT) || | 641 | if (ENCODER_MODE_IS_DP(encoder_mode)) { |
642 | radeon_encoder_is_dp_bridge(encoder)) { | 642 | args.v3.sInput.ucDispPllConfig |= |
643 | DISPPLL_CONFIG_COHERENT_MODE; | ||
644 | /* 16200 or 27000 */ | ||
645 | args.v3.sInput.usPixelClock = cpu_to_le16(dp_clock / 10); | ||
646 | } else if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) { | ||
643 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; | 647 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; |
644 | if (encoder_mode == ATOM_ENCODER_MODE_DP) { | 648 | if (encoder_mode == ATOM_ENCODER_MODE_HDMI) |
649 | /* deep color support */ | ||
650 | args.v3.sInput.usPixelClock = | ||
651 | cpu_to_le16((mode->clock * bpc / 8) / 10); | ||
652 | if (dig->coherent_mode) | ||
645 | args.v3.sInput.ucDispPllConfig |= | 653 | args.v3.sInput.ucDispPllConfig |= |
646 | DISPPLL_CONFIG_COHERENT_MODE; | 654 | DISPPLL_CONFIG_COHERENT_MODE; |
647 | /* 16200 or 27000 */ | 655 | if (mode->clock > 165000) |
648 | args.v3.sInput.usPixelClock = cpu_to_le16(dp_clock / 10); | ||
649 | } else { | ||
650 | if (encoder_mode == ATOM_ENCODER_MODE_HDMI) { | ||
651 | /* deep color support */ | ||
652 | args.v3.sInput.usPixelClock = | ||
653 | cpu_to_le16((mode->clock * bpc / 8) / 10); | ||
654 | } | ||
655 | if (dig->coherent_mode) | ||
656 | args.v3.sInput.ucDispPllConfig |= | ||
657 | DISPPLL_CONFIG_COHERENT_MODE; | ||
658 | if (mode->clock > 165000) | ||
659 | args.v3.sInput.ucDispPllConfig |= | ||
660 | DISPPLL_CONFIG_DUAL_LINK; | ||
661 | } | ||
662 | } else if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) { | ||
663 | if (encoder_mode == ATOM_ENCODER_MODE_DP) { | ||
664 | args.v3.sInput.ucDispPllConfig |= | 656 | args.v3.sInput.ucDispPllConfig |= |
665 | DISPPLL_CONFIG_COHERENT_MODE; | 657 | DISPPLL_CONFIG_DUAL_LINK; |
666 | /* 16200 or 27000 */ | ||
667 | args.v3.sInput.usPixelClock = cpu_to_le16(dp_clock / 10); | ||
668 | } else if (encoder_mode != ATOM_ENCODER_MODE_LVDS) { | ||
669 | if (mode->clock > 165000) | ||
670 | args.v3.sInput.ucDispPllConfig |= | ||
671 | DISPPLL_CONFIG_DUAL_LINK; | ||
672 | } | ||
673 | } | 658 | } |
674 | if (radeon_encoder_is_dp_bridge(encoder)) { | 659 | if (radeon_encoder_get_dp_bridge_encoder_id(encoder) != |
675 | struct drm_encoder *ext_encoder = radeon_atom_get_external_encoder(encoder); | 660 | ENCODER_OBJECT_ID_NONE) |
676 | struct radeon_encoder *ext_radeon_encoder = to_radeon_encoder(ext_encoder); | 661 | args.v3.sInput.ucExtTransmitterID = |
677 | args.v3.sInput.ucExtTransmitterID = ext_radeon_encoder->encoder_id; | 662 | radeon_encoder_get_dp_bridge_encoder_id(encoder); |
678 | } else | 663 | else |
679 | args.v3.sInput.ucExtTransmitterID = 0; | 664 | args.v3.sInput.ucExtTransmitterID = 0; |
680 | 665 | ||
681 | atom_execute_table(rdev->mode_info.atom_context, | 666 | atom_execute_table(rdev->mode_info.atom_context, |
@@ -945,6 +930,7 @@ static void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode | |||
945 | bpc = connector->display_info.bpc; | 930 | bpc = connector->display_info.bpc; |
946 | 931 | ||
947 | switch (encoder_mode) { | 932 | switch (encoder_mode) { |
933 | case ATOM_ENCODER_MODE_DP_MST: | ||
948 | case ATOM_ENCODER_MODE_DP: | 934 | case ATOM_ENCODER_MODE_DP: |
949 | /* DP/eDP */ | 935 | /* DP/eDP */ |
950 | dp_clock = dig_connector->dp_clock / 10; | 936 | dp_clock = dig_connector->dp_clock / 10; |
@@ -1450,7 +1436,7 @@ static int radeon_atom_pick_pll(struct drm_crtc *crtc) | |||
1450 | * PPLL/DCPLL programming and only program the DP DTO for the | 1436 | * PPLL/DCPLL programming and only program the DP DTO for the |
1451 | * crtc virtual pixel clock. | 1437 | * crtc virtual pixel clock. |
1452 | */ | 1438 | */ |
1453 | if (atombios_get_encoder_mode(test_encoder) == ATOM_ENCODER_MODE_DP) { | 1439 | if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(test_encoder))) { |
1454 | if (ASIC_IS_DCE5(rdev) || rdev->clock.dp_extclk) | 1440 | if (ASIC_IS_DCE5(rdev) || rdev->clock.dp_extclk) |
1455 | return ATOM_PPLL_INVALID; | 1441 | return ATOM_PPLL_INVALID; |
1456 | } | 1442 | } |
diff --git a/drivers/gpu/drm/radeon/atombios_dp.c b/drivers/gpu/drm/radeon/atombios_dp.c index 79e8ebc05307..a0de48542f71 100644 --- a/drivers/gpu/drm/radeon/atombios_dp.c +++ b/drivers/gpu/drm/radeon/atombios_dp.c | |||
@@ -482,7 +482,8 @@ static int radeon_dp_get_dp_link_clock(struct drm_connector *connector, | |||
482 | int bpp = convert_bpc_to_bpp(connector->display_info.bpc); | 482 | int bpp = convert_bpc_to_bpp(connector->display_info.bpc); |
483 | int lane_num, max_pix_clock; | 483 | int lane_num, max_pix_clock; |
484 | 484 | ||
485 | if (radeon_connector_encoder_is_dp_bridge(connector)) | 485 | if (radeon_connector_encoder_get_dp_bridge_encoder_id(connector) == |
486 | ENCODER_OBJECT_ID_NUTMEG) | ||
486 | return 270000; | 487 | return 270000; |
487 | 488 | ||
488 | lane_num = radeon_dp_get_dp_lane_number(connector, dpcd, pix_clock); | 489 | lane_num = radeon_dp_get_dp_lane_number(connector, dpcd, pix_clock); |
@@ -553,17 +554,32 @@ static void radeon_dp_set_panel_mode(struct drm_encoder *encoder, | |||
553 | { | 554 | { |
554 | struct drm_device *dev = encoder->dev; | 555 | struct drm_device *dev = encoder->dev; |
555 | struct radeon_device *rdev = dev->dev_private; | 556 | struct radeon_device *rdev = dev->dev_private; |
557 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | ||
556 | int panel_mode = DP_PANEL_MODE_EXTERNAL_DP_MODE; | 558 | int panel_mode = DP_PANEL_MODE_EXTERNAL_DP_MODE; |
557 | 559 | ||
558 | if (!ASIC_IS_DCE4(rdev)) | 560 | if (!ASIC_IS_DCE4(rdev)) |
559 | return; | 561 | return; |
560 | 562 | ||
561 | if (radeon_connector_encoder_is_dp_bridge(connector)) | 563 | if (radeon_connector_encoder_get_dp_bridge_encoder_id(connector) == |
564 | ENCODER_OBJECT_ID_NUTMEG) | ||
562 | panel_mode = DP_PANEL_MODE_INTERNAL_DP1_MODE; | 565 | panel_mode = DP_PANEL_MODE_INTERNAL_DP1_MODE; |
566 | else if (radeon_connector_encoder_get_dp_bridge_encoder_id(connector) == | ||
567 | ENCODER_OBJECT_ID_TRAVIS) | ||
568 | panel_mode = DP_PANEL_MODE_INTERNAL_DP2_MODE; | ||
569 | else if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) { | ||
570 | u8 tmp = radeon_read_dpcd_reg(radeon_connector, DP_EDP_CONFIGURATION_CAP); | ||
571 | if (tmp & 1) | ||
572 | panel_mode = DP_PANEL_MODE_INTERNAL_DP2_MODE; | ||
573 | } | ||
563 | 574 | ||
564 | atombios_dig_encoder_setup(encoder, | 575 | atombios_dig_encoder_setup(encoder, |
565 | ATOM_ENCODER_CMD_SETUP_PANEL_MODE, | 576 | ATOM_ENCODER_CMD_SETUP_PANEL_MODE, |
566 | panel_mode); | 577 | panel_mode); |
578 | |||
579 | if ((connector->connector_type == DRM_MODE_CONNECTOR_eDP) && | ||
580 | (panel_mode == DP_PANEL_MODE_INTERNAL_DP2_MODE)) { | ||
581 | radeon_write_dpcd_reg(radeon_connector, DP_EDP_CONFIGURATION_SET, 1); | ||
582 | } | ||
567 | } | 583 | } |
568 | 584 | ||
569 | void radeon_dp_set_link_config(struct drm_connector *connector, | 585 | void radeon_dp_set_link_config(struct drm_connector *connector, |
diff --git a/drivers/gpu/drm/radeon/atombios_encoders.c b/drivers/gpu/drm/radeon/atombios_encoders.c new file mode 100644 index 000000000000..39c04c1b8472 --- /dev/null +++ b/drivers/gpu/drm/radeon/atombios_encoders.c | |||
@@ -0,0 +1,2369 @@ | |||
1 | /* | ||
2 | * Copyright 2007-11 Advanced Micro Devices, Inc. | ||
3 | * Copyright 2008 Red Hat Inc. | ||
4 | * | ||
5 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
6 | * copy of this software and associated documentation files (the "Software"), | ||
7 | * to deal in the Software without restriction, including without limitation | ||
8 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
9 | * and/or sell copies of the Software, and to permit persons to whom the | ||
10 | * Software is furnished to do so, subject to the following conditions: | ||
11 | * | ||
12 | * The above copyright notice and this permission notice shall be included in | ||
13 | * all copies or substantial portions of the Software. | ||
14 | * | ||
15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
18 | * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR | ||
19 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | ||
20 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | ||
21 | * OTHER DEALINGS IN THE SOFTWARE. | ||
22 | * | ||
23 | * Authors: Dave Airlie | ||
24 | * Alex Deucher | ||
25 | */ | ||
26 | #include "drmP.h" | ||
27 | #include "drm_crtc_helper.h" | ||
28 | #include "radeon_drm.h" | ||
29 | #include "radeon.h" | ||
30 | #include "atom.h" | ||
31 | |||
32 | extern int atom_debug; | ||
33 | |||
34 | /* evil but including atombios.h is much worse */ | ||
35 | bool radeon_atom_get_tv_timings(struct radeon_device *rdev, int index, | ||
36 | struct drm_display_mode *mode); | ||
37 | |||
38 | |||
39 | static inline bool radeon_encoder_is_digital(struct drm_encoder *encoder) | ||
40 | { | ||
41 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
42 | switch (radeon_encoder->encoder_id) { | ||
43 | case ENCODER_OBJECT_ID_INTERNAL_LVDS: | ||
44 | case ENCODER_OBJECT_ID_INTERNAL_TMDS1: | ||
45 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1: | ||
46 | case ENCODER_OBJECT_ID_INTERNAL_LVTM1: | ||
47 | case ENCODER_OBJECT_ID_INTERNAL_DVO1: | ||
48 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1: | ||
49 | case ENCODER_OBJECT_ID_INTERNAL_DDI: | ||
50 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: | ||
51 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: | ||
52 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: | ||
53 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: | ||
54 | return true; | ||
55 | default: | ||
56 | return false; | ||
57 | } | ||
58 | } | ||
59 | |||
60 | static struct drm_connector * | ||
61 | radeon_get_connector_for_encoder_init(struct drm_encoder *encoder) | ||
62 | { | ||
63 | struct drm_device *dev = encoder->dev; | ||
64 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
65 | struct drm_connector *connector; | ||
66 | struct radeon_connector *radeon_connector; | ||
67 | |||
68 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { | ||
69 | radeon_connector = to_radeon_connector(connector); | ||
70 | if (radeon_encoder->devices & radeon_connector->devices) | ||
71 | return connector; | ||
72 | } | ||
73 | return NULL; | ||
74 | } | ||
75 | |||
76 | static bool radeon_atom_mode_fixup(struct drm_encoder *encoder, | ||
77 | struct drm_display_mode *mode, | ||
78 | struct drm_display_mode *adjusted_mode) | ||
79 | { | ||
80 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
81 | struct drm_device *dev = encoder->dev; | ||
82 | struct radeon_device *rdev = dev->dev_private; | ||
83 | |||
84 | /* set the active encoder to connector routing */ | ||
85 | radeon_encoder_set_active_device(encoder); | ||
86 | drm_mode_set_crtcinfo(adjusted_mode, 0); | ||
87 | |||
88 | /* hw bug */ | ||
89 | if ((mode->flags & DRM_MODE_FLAG_INTERLACE) | ||
90 | && (mode->crtc_vsync_start < (mode->crtc_vdisplay + 2))) | ||
91 | adjusted_mode->crtc_vsync_start = adjusted_mode->crtc_vdisplay + 2; | ||
92 | |||
93 | /* get the native mode for LVDS */ | ||
94 | if (radeon_encoder->active_device & (ATOM_DEVICE_LCD_SUPPORT)) | ||
95 | radeon_panel_mode_fixup(encoder, adjusted_mode); | ||
96 | |||
97 | /* get the native mode for TV */ | ||
98 | if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT)) { | ||
99 | struct radeon_encoder_atom_dac *tv_dac = radeon_encoder->enc_priv; | ||
100 | if (tv_dac) { | ||
101 | if (tv_dac->tv_std == TV_STD_NTSC || | ||
102 | tv_dac->tv_std == TV_STD_NTSC_J || | ||
103 | tv_dac->tv_std == TV_STD_PAL_M) | ||
104 | radeon_atom_get_tv_timings(rdev, 0, adjusted_mode); | ||
105 | else | ||
106 | radeon_atom_get_tv_timings(rdev, 1, adjusted_mode); | ||
107 | } | ||
108 | } | ||
109 | |||
110 | if (ASIC_IS_DCE3(rdev) && | ||
111 | ((radeon_encoder->active_device & (ATOM_DEVICE_DFP_SUPPORT | ATOM_DEVICE_LCD_SUPPORT)) || | ||
112 | (radeon_encoder_get_dp_bridge_encoder_id(encoder) != ENCODER_OBJECT_ID_NONE))) { | ||
113 | struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); | ||
114 | radeon_dp_set_link_config(connector, mode); | ||
115 | } | ||
116 | |||
117 | return true; | ||
118 | } | ||
119 | |||
120 | static void | ||
121 | atombios_dac_setup(struct drm_encoder *encoder, int action) | ||
122 | { | ||
123 | struct drm_device *dev = encoder->dev; | ||
124 | struct radeon_device *rdev = dev->dev_private; | ||
125 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
126 | DAC_ENCODER_CONTROL_PS_ALLOCATION args; | ||
127 | int index = 0; | ||
128 | struct radeon_encoder_atom_dac *dac_info = radeon_encoder->enc_priv; | ||
129 | |||
130 | memset(&args, 0, sizeof(args)); | ||
131 | |||
132 | switch (radeon_encoder->encoder_id) { | ||
133 | case ENCODER_OBJECT_ID_INTERNAL_DAC1: | ||
134 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1: | ||
135 | index = GetIndexIntoMasterTable(COMMAND, DAC1EncoderControl); | ||
136 | break; | ||
137 | case ENCODER_OBJECT_ID_INTERNAL_DAC2: | ||
138 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2: | ||
139 | index = GetIndexIntoMasterTable(COMMAND, DAC2EncoderControl); | ||
140 | break; | ||
141 | } | ||
142 | |||
143 | args.ucAction = action; | ||
144 | |||
145 | if (radeon_encoder->active_device & (ATOM_DEVICE_CRT_SUPPORT)) | ||
146 | args.ucDacStandard = ATOM_DAC1_PS2; | ||
147 | else if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT)) | ||
148 | args.ucDacStandard = ATOM_DAC1_CV; | ||
149 | else { | ||
150 | switch (dac_info->tv_std) { | ||
151 | case TV_STD_PAL: | ||
152 | case TV_STD_PAL_M: | ||
153 | case TV_STD_SCART_PAL: | ||
154 | case TV_STD_SECAM: | ||
155 | case TV_STD_PAL_CN: | ||
156 | args.ucDacStandard = ATOM_DAC1_PAL; | ||
157 | break; | ||
158 | case TV_STD_NTSC: | ||
159 | case TV_STD_NTSC_J: | ||
160 | case TV_STD_PAL_60: | ||
161 | default: | ||
162 | args.ucDacStandard = ATOM_DAC1_NTSC; | ||
163 | break; | ||
164 | } | ||
165 | } | ||
166 | args.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); | ||
167 | |||
168 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); | ||
169 | |||
170 | } | ||
171 | |||
172 | static void | ||
173 | atombios_tv_setup(struct drm_encoder *encoder, int action) | ||
174 | { | ||
175 | struct drm_device *dev = encoder->dev; | ||
176 | struct radeon_device *rdev = dev->dev_private; | ||
177 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
178 | TV_ENCODER_CONTROL_PS_ALLOCATION args; | ||
179 | int index = 0; | ||
180 | struct radeon_encoder_atom_dac *dac_info = radeon_encoder->enc_priv; | ||
181 | |||
182 | memset(&args, 0, sizeof(args)); | ||
183 | |||
184 | index = GetIndexIntoMasterTable(COMMAND, TVEncoderControl); | ||
185 | |||
186 | args.sTVEncoder.ucAction = action; | ||
187 | |||
188 | if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT)) | ||
189 | args.sTVEncoder.ucTvStandard = ATOM_TV_CV; | ||
190 | else { | ||
191 | switch (dac_info->tv_std) { | ||
192 | case TV_STD_NTSC: | ||
193 | args.sTVEncoder.ucTvStandard = ATOM_TV_NTSC; | ||
194 | break; | ||
195 | case TV_STD_PAL: | ||
196 | args.sTVEncoder.ucTvStandard = ATOM_TV_PAL; | ||
197 | break; | ||
198 | case TV_STD_PAL_M: | ||
199 | args.sTVEncoder.ucTvStandard = ATOM_TV_PALM; | ||
200 | break; | ||
201 | case TV_STD_PAL_60: | ||
202 | args.sTVEncoder.ucTvStandard = ATOM_TV_PAL60; | ||
203 | break; | ||
204 | case TV_STD_NTSC_J: | ||
205 | args.sTVEncoder.ucTvStandard = ATOM_TV_NTSCJ; | ||
206 | break; | ||
207 | case TV_STD_SCART_PAL: | ||
208 | args.sTVEncoder.ucTvStandard = ATOM_TV_PAL; /* ??? */ | ||
209 | break; | ||
210 | case TV_STD_SECAM: | ||
211 | args.sTVEncoder.ucTvStandard = ATOM_TV_SECAM; | ||
212 | break; | ||
213 | case TV_STD_PAL_CN: | ||
214 | args.sTVEncoder.ucTvStandard = ATOM_TV_PALCN; | ||
215 | break; | ||
216 | default: | ||
217 | args.sTVEncoder.ucTvStandard = ATOM_TV_NTSC; | ||
218 | break; | ||
219 | } | ||
220 | } | ||
221 | |||
222 | args.sTVEncoder.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); | ||
223 | |||
224 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); | ||
225 | |||
226 | } | ||
227 | |||
228 | union dvo_encoder_control { | ||
229 | ENABLE_EXTERNAL_TMDS_ENCODER_PS_ALLOCATION ext_tmds; | ||
230 | DVO_ENCODER_CONTROL_PS_ALLOCATION dvo; | ||
231 | DVO_ENCODER_CONTROL_PS_ALLOCATION_V3 dvo_v3; | ||
232 | }; | ||
233 | |||
234 | void | ||
235 | atombios_dvo_setup(struct drm_encoder *encoder, int action) | ||
236 | { | ||
237 | struct drm_device *dev = encoder->dev; | ||
238 | struct radeon_device *rdev = dev->dev_private; | ||
239 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
240 | union dvo_encoder_control args; | ||
241 | int index = GetIndexIntoMasterTable(COMMAND, DVOEncoderControl); | ||
242 | uint8_t frev, crev; | ||
243 | |||
244 | memset(&args, 0, sizeof(args)); | ||
245 | |||
246 | if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev)) | ||
247 | return; | ||
248 | |||
249 | switch (frev) { | ||
250 | case 1: | ||
251 | switch (crev) { | ||
252 | case 1: | ||
253 | /* R4xx, R5xx */ | ||
254 | args.ext_tmds.sXTmdsEncoder.ucEnable = action; | ||
255 | |||
256 | if (radeon_encoder->pixel_clock > 165000) | ||
257 | args.ext_tmds.sXTmdsEncoder.ucMisc |= PANEL_ENCODER_MISC_DUAL; | ||
258 | |||
259 | args.ext_tmds.sXTmdsEncoder.ucMisc |= ATOM_PANEL_MISC_888RGB; | ||
260 | break; | ||
261 | case 2: | ||
262 | /* RS600/690/740 */ | ||
263 | args.dvo.sDVOEncoder.ucAction = action; | ||
264 | args.dvo.sDVOEncoder.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); | ||
265 | /* DFP1, CRT1, TV1 depending on the type of port */ | ||
266 | args.dvo.sDVOEncoder.ucDeviceType = ATOM_DEVICE_DFP1_INDEX; | ||
267 | |||
268 | if (radeon_encoder->pixel_clock > 165000) | ||
269 | args.dvo.sDVOEncoder.usDevAttr.sDigAttrib.ucAttribute |= PANEL_ENCODER_MISC_DUAL; | ||
270 | break; | ||
271 | case 3: | ||
272 | /* R6xx */ | ||
273 | args.dvo_v3.ucAction = action; | ||
274 | args.dvo_v3.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); | ||
275 | args.dvo_v3.ucDVOConfig = 0; /* XXX */ | ||
276 | break; | ||
277 | default: | ||
278 | DRM_ERROR("Unknown table version %d, %d\n", frev, crev); | ||
279 | break; | ||
280 | } | ||
281 | break; | ||
282 | default: | ||
283 | DRM_ERROR("Unknown table version %d, %d\n", frev, crev); | ||
284 | break; | ||
285 | } | ||
286 | |||
287 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); | ||
288 | } | ||
289 | |||
290 | union lvds_encoder_control { | ||
291 | LVDS_ENCODER_CONTROL_PS_ALLOCATION v1; | ||
292 | LVDS_ENCODER_CONTROL_PS_ALLOCATION_V2 v2; | ||
293 | }; | ||
294 | |||
295 | void | ||
296 | atombios_digital_setup(struct drm_encoder *encoder, int action) | ||
297 | { | ||
298 | struct drm_device *dev = encoder->dev; | ||
299 | struct radeon_device *rdev = dev->dev_private; | ||
300 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
301 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; | ||
302 | union lvds_encoder_control args; | ||
303 | int index = 0; | ||
304 | int hdmi_detected = 0; | ||
305 | uint8_t frev, crev; | ||
306 | |||
307 | if (!dig) | ||
308 | return; | ||
309 | |||
310 | if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_HDMI) | ||
311 | hdmi_detected = 1; | ||
312 | |||
313 | memset(&args, 0, sizeof(args)); | ||
314 | |||
315 | switch (radeon_encoder->encoder_id) { | ||
316 | case ENCODER_OBJECT_ID_INTERNAL_LVDS: | ||
317 | index = GetIndexIntoMasterTable(COMMAND, LVDSEncoderControl); | ||
318 | break; | ||
319 | case ENCODER_OBJECT_ID_INTERNAL_TMDS1: | ||
320 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1: | ||
321 | index = GetIndexIntoMasterTable(COMMAND, TMDS1EncoderControl); | ||
322 | break; | ||
323 | case ENCODER_OBJECT_ID_INTERNAL_LVTM1: | ||
324 | if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) | ||
325 | index = GetIndexIntoMasterTable(COMMAND, LVDSEncoderControl); | ||
326 | else | ||
327 | index = GetIndexIntoMasterTable(COMMAND, TMDS2EncoderControl); | ||
328 | break; | ||
329 | } | ||
330 | |||
331 | if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev)) | ||
332 | return; | ||
333 | |||
334 | switch (frev) { | ||
335 | case 1: | ||
336 | case 2: | ||
337 | switch (crev) { | ||
338 | case 1: | ||
339 | args.v1.ucMisc = 0; | ||
340 | args.v1.ucAction = action; | ||
341 | if (hdmi_detected) | ||
342 | args.v1.ucMisc |= PANEL_ENCODER_MISC_HDMI_TYPE; | ||
343 | args.v1.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); | ||
344 | if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) { | ||
345 | if (dig->lcd_misc & ATOM_PANEL_MISC_DUAL) | ||
346 | args.v1.ucMisc |= PANEL_ENCODER_MISC_DUAL; | ||
347 | if (dig->lcd_misc & ATOM_PANEL_MISC_888RGB) | ||
348 | args.v1.ucMisc |= ATOM_PANEL_MISC_888RGB; | ||
349 | } else { | ||
350 | if (dig->linkb) | ||
351 | args.v1.ucMisc |= PANEL_ENCODER_MISC_TMDS_LINKB; | ||
352 | if (radeon_encoder->pixel_clock > 165000) | ||
353 | args.v1.ucMisc |= PANEL_ENCODER_MISC_DUAL; | ||
354 | /*if (pScrn->rgbBits == 8) */ | ||
355 | args.v1.ucMisc |= ATOM_PANEL_MISC_888RGB; | ||
356 | } | ||
357 | break; | ||
358 | case 2: | ||
359 | case 3: | ||
360 | args.v2.ucMisc = 0; | ||
361 | args.v2.ucAction = action; | ||
362 | if (crev == 3) { | ||
363 | if (dig->coherent_mode) | ||
364 | args.v2.ucMisc |= PANEL_ENCODER_MISC_COHERENT; | ||
365 | } | ||
366 | if (hdmi_detected) | ||
367 | args.v2.ucMisc |= PANEL_ENCODER_MISC_HDMI_TYPE; | ||
368 | args.v2.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); | ||
369 | args.v2.ucTruncate = 0; | ||
370 | args.v2.ucSpatial = 0; | ||
371 | args.v2.ucTemporal = 0; | ||
372 | args.v2.ucFRC = 0; | ||
373 | if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) { | ||
374 | if (dig->lcd_misc & ATOM_PANEL_MISC_DUAL) | ||
375 | args.v2.ucMisc |= PANEL_ENCODER_MISC_DUAL; | ||
376 | if (dig->lcd_misc & ATOM_PANEL_MISC_SPATIAL) { | ||
377 | args.v2.ucSpatial = PANEL_ENCODER_SPATIAL_DITHER_EN; | ||
378 | if (dig->lcd_misc & ATOM_PANEL_MISC_888RGB) | ||
379 | args.v2.ucSpatial |= PANEL_ENCODER_SPATIAL_DITHER_DEPTH; | ||
380 | } | ||
381 | if (dig->lcd_misc & ATOM_PANEL_MISC_TEMPORAL) { | ||
382 | args.v2.ucTemporal = PANEL_ENCODER_TEMPORAL_DITHER_EN; | ||
383 | if (dig->lcd_misc & ATOM_PANEL_MISC_888RGB) | ||
384 | args.v2.ucTemporal |= PANEL_ENCODER_TEMPORAL_DITHER_DEPTH; | ||
385 | if (((dig->lcd_misc >> ATOM_PANEL_MISC_GREY_LEVEL_SHIFT) & 0x3) == 2) | ||
386 | args.v2.ucTemporal |= PANEL_ENCODER_TEMPORAL_LEVEL_4; | ||
387 | } | ||
388 | } else { | ||
389 | if (dig->linkb) | ||
390 | args.v2.ucMisc |= PANEL_ENCODER_MISC_TMDS_LINKB; | ||
391 | if (radeon_encoder->pixel_clock > 165000) | ||
392 | args.v2.ucMisc |= PANEL_ENCODER_MISC_DUAL; | ||
393 | } | ||
394 | break; | ||
395 | default: | ||
396 | DRM_ERROR("Unknown table version %d, %d\n", frev, crev); | ||
397 | break; | ||
398 | } | ||
399 | break; | ||
400 | default: | ||
401 | DRM_ERROR("Unknown table version %d, %d\n", frev, crev); | ||
402 | break; | ||
403 | } | ||
404 | |||
405 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); | ||
406 | } | ||
407 | |||
408 | int | ||
409 | atombios_get_encoder_mode(struct drm_encoder *encoder) | ||
410 | { | ||
411 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
412 | struct drm_device *dev = encoder->dev; | ||
413 | struct radeon_device *rdev = dev->dev_private; | ||
414 | struct drm_connector *connector; | ||
415 | struct radeon_connector *radeon_connector; | ||
416 | struct radeon_connector_atom_dig *dig_connector; | ||
417 | |||
418 | /* dp bridges are always DP */ | ||
419 | if (radeon_encoder_get_dp_bridge_encoder_id(encoder) != ENCODER_OBJECT_ID_NONE) | ||
420 | return ATOM_ENCODER_MODE_DP; | ||
421 | |||
422 | /* DVO is always DVO */ | ||
423 | if (radeon_encoder->encoder_id == ATOM_ENCODER_MODE_DVO) | ||
424 | return ATOM_ENCODER_MODE_DVO; | ||
425 | |||
426 | connector = radeon_get_connector_for_encoder(encoder); | ||
427 | /* if we don't have an active device yet, just use one of | ||
428 | * the connectors tied to the encoder. | ||
429 | */ | ||
430 | if (!connector) | ||
431 | connector = radeon_get_connector_for_encoder_init(encoder); | ||
432 | radeon_connector = to_radeon_connector(connector); | ||
433 | |||
434 | switch (connector->connector_type) { | ||
435 | case DRM_MODE_CONNECTOR_DVII: | ||
436 | case DRM_MODE_CONNECTOR_HDMIB: /* HDMI-B is basically DL-DVI; analog works fine */ | ||
437 | if (drm_detect_monitor_audio(radeon_connector->edid) && radeon_audio) { | ||
438 | /* fix me */ | ||
439 | if (ASIC_IS_DCE4(rdev)) | ||
440 | return ATOM_ENCODER_MODE_DVI; | ||
441 | else | ||
442 | return ATOM_ENCODER_MODE_HDMI; | ||
443 | } else if (radeon_connector->use_digital) | ||
444 | return ATOM_ENCODER_MODE_DVI; | ||
445 | else | ||
446 | return ATOM_ENCODER_MODE_CRT; | ||
447 | break; | ||
448 | case DRM_MODE_CONNECTOR_DVID: | ||
449 | case DRM_MODE_CONNECTOR_HDMIA: | ||
450 | default: | ||
451 | if (drm_detect_monitor_audio(radeon_connector->edid) && radeon_audio) { | ||
452 | /* fix me */ | ||
453 | if (ASIC_IS_DCE4(rdev)) | ||
454 | return ATOM_ENCODER_MODE_DVI; | ||
455 | else | ||
456 | return ATOM_ENCODER_MODE_HDMI; | ||
457 | } else | ||
458 | return ATOM_ENCODER_MODE_DVI; | ||
459 | break; | ||
460 | case DRM_MODE_CONNECTOR_LVDS: | ||
461 | return ATOM_ENCODER_MODE_LVDS; | ||
462 | break; | ||
463 | case DRM_MODE_CONNECTOR_DisplayPort: | ||
464 | dig_connector = radeon_connector->con_priv; | ||
465 | if ((dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) || | ||
466 | (dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_eDP)) | ||
467 | return ATOM_ENCODER_MODE_DP; | ||
468 | else if (drm_detect_monitor_audio(radeon_connector->edid) && radeon_audio) { | ||
469 | /* fix me */ | ||
470 | if (ASIC_IS_DCE4(rdev)) | ||
471 | return ATOM_ENCODER_MODE_DVI; | ||
472 | else | ||
473 | return ATOM_ENCODER_MODE_HDMI; | ||
474 | } else | ||
475 | return ATOM_ENCODER_MODE_DVI; | ||
476 | break; | ||
477 | case DRM_MODE_CONNECTOR_eDP: | ||
478 | return ATOM_ENCODER_MODE_DP; | ||
479 | case DRM_MODE_CONNECTOR_DVIA: | ||
480 | case DRM_MODE_CONNECTOR_VGA: | ||
481 | return ATOM_ENCODER_MODE_CRT; | ||
482 | break; | ||
483 | case DRM_MODE_CONNECTOR_Composite: | ||
484 | case DRM_MODE_CONNECTOR_SVIDEO: | ||
485 | case DRM_MODE_CONNECTOR_9PinDIN: | ||
486 | /* fix me */ | ||
487 | return ATOM_ENCODER_MODE_TV; | ||
488 | /*return ATOM_ENCODER_MODE_CV;*/ | ||
489 | break; | ||
490 | } | ||
491 | } | ||
492 | |||
493 | /* | ||
494 | * DIG Encoder/Transmitter Setup | ||
495 | * | ||
496 | * DCE 3.0/3.1 | ||
497 | * - 2 DIG transmitter blocks. UNIPHY (links A and B) and LVTMA. | ||
498 | * Supports up to 3 digital outputs | ||
499 | * - 2 DIG encoder blocks. | ||
500 | * DIG1 can drive UNIPHY link A or link B | ||
501 | * DIG2 can drive UNIPHY link B or LVTMA | ||
502 | * | ||
503 | * DCE 3.2 | ||
504 | * - 3 DIG transmitter blocks. UNIPHY0/1/2 (links A and B). | ||
505 | * Supports up to 5 digital outputs | ||
506 | * - 2 DIG encoder blocks. | ||
507 | * DIG1/2 can drive UNIPHY0/1/2 link A or link B | ||
508 | * | ||
509 | * DCE 4.0/5.0 | ||
510 | * - 3 DIG transmitter blocks UNIPHY0/1/2 (links A and B). | ||
511 | * Supports up to 6 digital outputs | ||
512 | * - 6 DIG encoder blocks. | ||
513 | * - DIG to PHY mapping is hardcoded | ||
514 | * DIG1 drives UNIPHY0 link A, A+B | ||
515 | * DIG2 drives UNIPHY0 link B | ||
516 | * DIG3 drives UNIPHY1 link A, A+B | ||
517 | * DIG4 drives UNIPHY1 link B | ||
518 | * DIG5 drives UNIPHY2 link A, A+B | ||
519 | * DIG6 drives UNIPHY2 link B | ||
520 | * | ||
521 | * DCE 4.1 | ||
522 | * - 3 DIG transmitter blocks UNIPHY0/1/2 (links A and B). | ||
523 | * Supports up to 6 digital outputs | ||
524 | * - 2 DIG encoder blocks. | ||
525 | * DIG1/2 can drive UNIPHY0/1/2 link A or link B | ||
526 | * | ||
527 | * Routing | ||
528 | * crtc -> dig encoder -> UNIPHY/LVTMA (1 or 2 links) | ||
529 | * Examples: | ||
530 | * crtc0 -> dig2 -> LVTMA links A+B -> TMDS/HDMI | ||
531 | * crtc1 -> dig1 -> UNIPHY0 link B -> DP | ||
532 | * crtc0 -> dig1 -> UNIPHY2 link A -> LVDS | ||
533 | * crtc1 -> dig2 -> UNIPHY1 link B+A -> TMDS/HDMI | ||
534 | */ | ||
535 | |||
536 | union dig_encoder_control { | ||
537 | DIG_ENCODER_CONTROL_PS_ALLOCATION v1; | ||
538 | DIG_ENCODER_CONTROL_PARAMETERS_V2 v2; | ||
539 | DIG_ENCODER_CONTROL_PARAMETERS_V3 v3; | ||
540 | DIG_ENCODER_CONTROL_PARAMETERS_V4 v4; | ||
541 | }; | ||
542 | |||
543 | void | ||
544 | atombios_dig_encoder_setup(struct drm_encoder *encoder, int action, int panel_mode) | ||
545 | { | ||
546 | struct drm_device *dev = encoder->dev; | ||
547 | struct radeon_device *rdev = dev->dev_private; | ||
548 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
549 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; | ||
550 | struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); | ||
551 | union dig_encoder_control args; | ||
552 | int index = 0; | ||
553 | uint8_t frev, crev; | ||
554 | int dp_clock = 0; | ||
555 | int dp_lane_count = 0; | ||
556 | int hpd_id = RADEON_HPD_NONE; | ||
557 | int bpc = 8; | ||
558 | |||
559 | if (connector) { | ||
560 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | ||
561 | struct radeon_connector_atom_dig *dig_connector = | ||
562 | radeon_connector->con_priv; | ||
563 | |||
564 | dp_clock = dig_connector->dp_clock; | ||
565 | dp_lane_count = dig_connector->dp_lane_count; | ||
566 | hpd_id = radeon_connector->hpd.hpd; | ||
567 | bpc = connector->display_info.bpc; | ||
568 | } | ||
569 | |||
570 | /* no dig encoder assigned */ | ||
571 | if (dig->dig_encoder == -1) | ||
572 | return; | ||
573 | |||
574 | memset(&args, 0, sizeof(args)); | ||
575 | |||
576 | if (ASIC_IS_DCE4(rdev)) | ||
577 | index = GetIndexIntoMasterTable(COMMAND, DIGxEncoderControl); | ||
578 | else { | ||
579 | if (dig->dig_encoder) | ||
580 | index = GetIndexIntoMasterTable(COMMAND, DIG2EncoderControl); | ||
581 | else | ||
582 | index = GetIndexIntoMasterTable(COMMAND, DIG1EncoderControl); | ||
583 | } | ||
584 | |||
585 | if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev)) | ||
586 | return; | ||
587 | |||
588 | switch (frev) { | ||
589 | case 1: | ||
590 | switch (crev) { | ||
591 | case 1: | ||
592 | args.v1.ucAction = action; | ||
593 | args.v1.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); | ||
594 | if (action == ATOM_ENCODER_CMD_SETUP_PANEL_MODE) | ||
595 | args.v3.ucPanelMode = panel_mode; | ||
596 | else | ||
597 | args.v1.ucEncoderMode = atombios_get_encoder_mode(encoder); | ||
598 | |||
599 | if (ENCODER_MODE_IS_DP(args.v1.ucEncoderMode)) | ||
600 | args.v1.ucLaneNum = dp_lane_count; | ||
601 | else if (radeon_encoder->pixel_clock > 165000) | ||
602 | args.v1.ucLaneNum = 8; | ||
603 | else | ||
604 | args.v1.ucLaneNum = 4; | ||
605 | |||
606 | if (ENCODER_MODE_IS_DP(args.v1.ucEncoderMode) && (dp_clock == 270000)) | ||
607 | args.v1.ucConfig |= ATOM_ENCODER_CONFIG_DPLINKRATE_2_70GHZ; | ||
608 | switch (radeon_encoder->encoder_id) { | ||
609 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: | ||
610 | args.v1.ucConfig = ATOM_ENCODER_CONFIG_V2_TRANSMITTER1; | ||
611 | break; | ||
612 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: | ||
613 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: | ||
614 | args.v1.ucConfig = ATOM_ENCODER_CONFIG_V2_TRANSMITTER2; | ||
615 | break; | ||
616 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: | ||
617 | args.v1.ucConfig = ATOM_ENCODER_CONFIG_V2_TRANSMITTER3; | ||
618 | break; | ||
619 | } | ||
620 | if (dig->linkb) | ||
621 | args.v1.ucConfig |= ATOM_ENCODER_CONFIG_LINKB; | ||
622 | else | ||
623 | args.v1.ucConfig |= ATOM_ENCODER_CONFIG_LINKA; | ||
624 | break; | ||
625 | case 2: | ||
626 | case 3: | ||
627 | args.v3.ucAction = action; | ||
628 | args.v3.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); | ||
629 | if (action == ATOM_ENCODER_CMD_SETUP_PANEL_MODE) | ||
630 | args.v3.ucPanelMode = panel_mode; | ||
631 | else | ||
632 | args.v3.ucEncoderMode = atombios_get_encoder_mode(encoder); | ||
633 | |||
634 | if (ENCODER_MODE_IS_DP(args.v1.ucEncoderMode)) | ||
635 | args.v3.ucLaneNum = dp_lane_count; | ||
636 | else if (radeon_encoder->pixel_clock > 165000) | ||
637 | args.v3.ucLaneNum = 8; | ||
638 | else | ||
639 | args.v3.ucLaneNum = 4; | ||
640 | |||
641 | if (ENCODER_MODE_IS_DP(args.v1.ucEncoderMode) && (dp_clock == 270000)) | ||
642 | args.v1.ucConfig |= ATOM_ENCODER_CONFIG_V3_DPLINKRATE_2_70GHZ; | ||
643 | args.v3.acConfig.ucDigSel = dig->dig_encoder; | ||
644 | switch (bpc) { | ||
645 | case 0: | ||
646 | args.v3.ucBitPerColor = PANEL_BPC_UNDEFINE; | ||
647 | break; | ||
648 | case 6: | ||
649 | args.v3.ucBitPerColor = PANEL_6BIT_PER_COLOR; | ||
650 | break; | ||
651 | case 8: | ||
652 | default: | ||
653 | args.v3.ucBitPerColor = PANEL_8BIT_PER_COLOR; | ||
654 | break; | ||
655 | case 10: | ||
656 | args.v3.ucBitPerColor = PANEL_10BIT_PER_COLOR; | ||
657 | break; | ||
658 | case 12: | ||
659 | args.v3.ucBitPerColor = PANEL_12BIT_PER_COLOR; | ||
660 | break; | ||
661 | case 16: | ||
662 | args.v3.ucBitPerColor = PANEL_16BIT_PER_COLOR; | ||
663 | break; | ||
664 | } | ||
665 | break; | ||
666 | case 4: | ||
667 | args.v4.ucAction = action; | ||
668 | args.v4.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); | ||
669 | if (action == ATOM_ENCODER_CMD_SETUP_PANEL_MODE) | ||
670 | args.v4.ucPanelMode = panel_mode; | ||
671 | else | ||
672 | args.v4.ucEncoderMode = atombios_get_encoder_mode(encoder); | ||
673 | |||
674 | if (ENCODER_MODE_IS_DP(args.v1.ucEncoderMode)) | ||
675 | args.v4.ucLaneNum = dp_lane_count; | ||
676 | else if (radeon_encoder->pixel_clock > 165000) | ||
677 | args.v4.ucLaneNum = 8; | ||
678 | else | ||
679 | args.v4.ucLaneNum = 4; | ||
680 | |||
681 | if (ENCODER_MODE_IS_DP(args.v1.ucEncoderMode)) { | ||
682 | if (dp_clock == 270000) | ||
683 | args.v1.ucConfig |= ATOM_ENCODER_CONFIG_V4_DPLINKRATE_2_70GHZ; | ||
684 | else if (dp_clock == 540000) | ||
685 | args.v1.ucConfig |= ATOM_ENCODER_CONFIG_V4_DPLINKRATE_5_40GHZ; | ||
686 | } | ||
687 | args.v4.acConfig.ucDigSel = dig->dig_encoder; | ||
688 | switch (bpc) { | ||
689 | case 0: | ||
690 | args.v4.ucBitPerColor = PANEL_BPC_UNDEFINE; | ||
691 | break; | ||
692 | case 6: | ||
693 | args.v4.ucBitPerColor = PANEL_6BIT_PER_COLOR; | ||
694 | break; | ||
695 | case 8: | ||
696 | default: | ||
697 | args.v4.ucBitPerColor = PANEL_8BIT_PER_COLOR; | ||
698 | break; | ||
699 | case 10: | ||
700 | args.v4.ucBitPerColor = PANEL_10BIT_PER_COLOR; | ||
701 | break; | ||
702 | case 12: | ||
703 | args.v4.ucBitPerColor = PANEL_12BIT_PER_COLOR; | ||
704 | break; | ||
705 | case 16: | ||
706 | args.v4.ucBitPerColor = PANEL_16BIT_PER_COLOR; | ||
707 | break; | ||
708 | } | ||
709 | if (hpd_id == RADEON_HPD_NONE) | ||
710 | args.v4.ucHPD_ID = 0; | ||
711 | else | ||
712 | args.v4.ucHPD_ID = hpd_id + 1; | ||
713 | break; | ||
714 | default: | ||
715 | DRM_ERROR("Unknown table version %d, %d\n", frev, crev); | ||
716 | break; | ||
717 | } | ||
718 | break; | ||
719 | default: | ||
720 | DRM_ERROR("Unknown table version %d, %d\n", frev, crev); | ||
721 | break; | ||
722 | } | ||
723 | |||
724 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); | ||
725 | |||
726 | } | ||
727 | |||
728 | union dig_transmitter_control { | ||
729 | DIG_TRANSMITTER_CONTROL_PS_ALLOCATION v1; | ||
730 | DIG_TRANSMITTER_CONTROL_PARAMETERS_V2 v2; | ||
731 | DIG_TRANSMITTER_CONTROL_PARAMETERS_V3 v3; | ||
732 | DIG_TRANSMITTER_CONTROL_PARAMETERS_V4 v4; | ||
733 | }; | ||
734 | |||
735 | void | ||
736 | atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t lane_num, uint8_t lane_set) | ||
737 | { | ||
738 | struct drm_device *dev = encoder->dev; | ||
739 | struct radeon_device *rdev = dev->dev_private; | ||
740 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
741 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; | ||
742 | struct drm_connector *connector; | ||
743 | union dig_transmitter_control args; | ||
744 | int index = 0; | ||
745 | uint8_t frev, crev; | ||
746 | bool is_dp = false; | ||
747 | int pll_id = 0; | ||
748 | int dp_clock = 0; | ||
749 | int dp_lane_count = 0; | ||
750 | int connector_object_id = 0; | ||
751 | int igp_lane_info = 0; | ||
752 | int dig_encoder = dig->dig_encoder; | ||
753 | |||
754 | if (action == ATOM_TRANSMITTER_ACTION_INIT) { | ||
755 | connector = radeon_get_connector_for_encoder_init(encoder); | ||
756 | /* just needed to avoid bailing in the encoder check. the encoder | ||
757 | * isn't used for init | ||
758 | */ | ||
759 | dig_encoder = 0; | ||
760 | } else | ||
761 | connector = radeon_get_connector_for_encoder(encoder); | ||
762 | |||
763 | if (connector) { | ||
764 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | ||
765 | struct radeon_connector_atom_dig *dig_connector = | ||
766 | radeon_connector->con_priv; | ||
767 | |||
768 | dp_clock = dig_connector->dp_clock; | ||
769 | dp_lane_count = dig_connector->dp_lane_count; | ||
770 | connector_object_id = | ||
771 | (radeon_connector->connector_object_id & OBJECT_ID_MASK) >> OBJECT_ID_SHIFT; | ||
772 | igp_lane_info = dig_connector->igp_lane_info; | ||
773 | } | ||
774 | |||
775 | if (encoder->crtc) { | ||
776 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc); | ||
777 | pll_id = radeon_crtc->pll_id; | ||
778 | } | ||
779 | |||
780 | /* no dig encoder assigned */ | ||
781 | if (dig_encoder == -1) | ||
782 | return; | ||
783 | |||
784 | if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(encoder))) | ||
785 | is_dp = true; | ||
786 | |||
787 | memset(&args, 0, sizeof(args)); | ||
788 | |||
789 | switch (radeon_encoder->encoder_id) { | ||
790 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1: | ||
791 | index = GetIndexIntoMasterTable(COMMAND, DVOOutputControl); | ||
792 | break; | ||
793 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: | ||
794 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: | ||
795 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: | ||
796 | index = GetIndexIntoMasterTable(COMMAND, UNIPHYTransmitterControl); | ||
797 | break; | ||
798 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: | ||
799 | index = GetIndexIntoMasterTable(COMMAND, LVTMATransmitterControl); | ||
800 | break; | ||
801 | } | ||
802 | |||
803 | if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev)) | ||
804 | return; | ||
805 | |||
806 | switch (frev) { | ||
807 | case 1: | ||
808 | switch (crev) { | ||
809 | case 1: | ||
810 | args.v1.ucAction = action; | ||
811 | if (action == ATOM_TRANSMITTER_ACTION_INIT) { | ||
812 | args.v1.usInitInfo = cpu_to_le16(connector_object_id); | ||
813 | } else if (action == ATOM_TRANSMITTER_ACTION_SETUP_VSEMPH) { | ||
814 | args.v1.asMode.ucLaneSel = lane_num; | ||
815 | args.v1.asMode.ucLaneSet = lane_set; | ||
816 | } else { | ||
817 | if (is_dp) | ||
818 | args.v1.usPixelClock = | ||
819 | cpu_to_le16(dp_clock / 10); | ||
820 | else if (radeon_encoder->pixel_clock > 165000) | ||
821 | args.v1.usPixelClock = cpu_to_le16((radeon_encoder->pixel_clock / 2) / 10); | ||
822 | else | ||
823 | args.v1.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); | ||
824 | } | ||
825 | |||
826 | args.v1.ucConfig = ATOM_TRANSMITTER_CONFIG_CLKSRC_PPLL; | ||
827 | |||
828 | if (dig_encoder) | ||
829 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_DIG2_ENCODER; | ||
830 | else | ||
831 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_DIG1_ENCODER; | ||
832 | |||
833 | if ((rdev->flags & RADEON_IS_IGP) && | ||
834 | (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_UNIPHY)) { | ||
835 | if (is_dp || (radeon_encoder->pixel_clock <= 165000)) { | ||
836 | if (igp_lane_info & 0x1) | ||
837 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_0_3; | ||
838 | else if (igp_lane_info & 0x2) | ||
839 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_4_7; | ||
840 | else if (igp_lane_info & 0x4) | ||
841 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_8_11; | ||
842 | else if (igp_lane_info & 0x8) | ||
843 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_12_15; | ||
844 | } else { | ||
845 | if (igp_lane_info & 0x3) | ||
846 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_0_7; | ||
847 | else if (igp_lane_info & 0xc) | ||
848 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_8_15; | ||
849 | } | ||
850 | } | ||
851 | |||
852 | if (dig->linkb) | ||
853 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKB; | ||
854 | else | ||
855 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKA; | ||
856 | |||
857 | if (is_dp) | ||
858 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_COHERENT; | ||
859 | else if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) { | ||
860 | if (dig->coherent_mode) | ||
861 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_COHERENT; | ||
862 | if (radeon_encoder->pixel_clock > 165000) | ||
863 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_8LANE_LINK; | ||
864 | } | ||
865 | break; | ||
866 | case 2: | ||
867 | args.v2.ucAction = action; | ||
868 | if (action == ATOM_TRANSMITTER_ACTION_INIT) { | ||
869 | args.v2.usInitInfo = cpu_to_le16(connector_object_id); | ||
870 | } else if (action == ATOM_TRANSMITTER_ACTION_SETUP_VSEMPH) { | ||
871 | args.v2.asMode.ucLaneSel = lane_num; | ||
872 | args.v2.asMode.ucLaneSet = lane_set; | ||
873 | } else { | ||
874 | if (is_dp) | ||
875 | args.v2.usPixelClock = | ||
876 | cpu_to_le16(dp_clock / 10); | ||
877 | else if (radeon_encoder->pixel_clock > 165000) | ||
878 | args.v2.usPixelClock = cpu_to_le16((radeon_encoder->pixel_clock / 2) / 10); | ||
879 | else | ||
880 | args.v2.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); | ||
881 | } | ||
882 | |||
883 | args.v2.acConfig.ucEncoderSel = dig_encoder; | ||
884 | if (dig->linkb) | ||
885 | args.v2.acConfig.ucLinkSel = 1; | ||
886 | |||
887 | switch (radeon_encoder->encoder_id) { | ||
888 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: | ||
889 | args.v2.acConfig.ucTransmitterSel = 0; | ||
890 | break; | ||
891 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: | ||
892 | args.v2.acConfig.ucTransmitterSel = 1; | ||
893 | break; | ||
894 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: | ||
895 | args.v2.acConfig.ucTransmitterSel = 2; | ||
896 | break; | ||
897 | } | ||
898 | |||
899 | if (is_dp) { | ||
900 | args.v2.acConfig.fCoherentMode = 1; | ||
901 | args.v2.acConfig.fDPConnector = 1; | ||
902 | } else if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) { | ||
903 | if (dig->coherent_mode) | ||
904 | args.v2.acConfig.fCoherentMode = 1; | ||
905 | if (radeon_encoder->pixel_clock > 165000) | ||
906 | args.v2.acConfig.fDualLinkConnector = 1; | ||
907 | } | ||
908 | break; | ||
909 | case 3: | ||
910 | args.v3.ucAction = action; | ||
911 | if (action == ATOM_TRANSMITTER_ACTION_INIT) { | ||
912 | args.v3.usInitInfo = cpu_to_le16(connector_object_id); | ||
913 | } else if (action == ATOM_TRANSMITTER_ACTION_SETUP_VSEMPH) { | ||
914 | args.v3.asMode.ucLaneSel = lane_num; | ||
915 | args.v3.asMode.ucLaneSet = lane_set; | ||
916 | } else { | ||
917 | if (is_dp) | ||
918 | args.v3.usPixelClock = | ||
919 | cpu_to_le16(dp_clock / 10); | ||
920 | else if (radeon_encoder->pixel_clock > 165000) | ||
921 | args.v3.usPixelClock = cpu_to_le16((radeon_encoder->pixel_clock / 2) / 10); | ||
922 | else | ||
923 | args.v3.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); | ||
924 | } | ||
925 | |||
926 | if (is_dp) | ||
927 | args.v3.ucLaneNum = dp_lane_count; | ||
928 | else if (radeon_encoder->pixel_clock > 165000) | ||
929 | args.v3.ucLaneNum = 8; | ||
930 | else | ||
931 | args.v3.ucLaneNum = 4; | ||
932 | |||
933 | if (dig->linkb) | ||
934 | args.v3.acConfig.ucLinkSel = 1; | ||
935 | if (dig_encoder & 1) | ||
936 | args.v3.acConfig.ucEncoderSel = 1; | ||
937 | |||
938 | /* Select the PLL for the PHY | ||
939 | * DP PHY should be clocked from external src if there is | ||
940 | * one. | ||
941 | */ | ||
942 | /* On DCE4, if there is an external clock, it generates the DP ref clock */ | ||
943 | if (is_dp && rdev->clock.dp_extclk) | ||
944 | args.v3.acConfig.ucRefClkSource = 2; /* external src */ | ||
945 | else | ||
946 | args.v3.acConfig.ucRefClkSource = pll_id; | ||
947 | |||
948 | switch (radeon_encoder->encoder_id) { | ||
949 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: | ||
950 | args.v3.acConfig.ucTransmitterSel = 0; | ||
951 | break; | ||
952 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: | ||
953 | args.v3.acConfig.ucTransmitterSel = 1; | ||
954 | break; | ||
955 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: | ||
956 | args.v3.acConfig.ucTransmitterSel = 2; | ||
957 | break; | ||
958 | } | ||
959 | |||
960 | if (is_dp) | ||
961 | args.v3.acConfig.fCoherentMode = 1; /* DP requires coherent */ | ||
962 | else if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) { | ||
963 | if (dig->coherent_mode) | ||
964 | args.v3.acConfig.fCoherentMode = 1; | ||
965 | if (radeon_encoder->pixel_clock > 165000) | ||
966 | args.v3.acConfig.fDualLinkConnector = 1; | ||
967 | } | ||
968 | break; | ||
969 | case 4: | ||
970 | args.v4.ucAction = action; | ||
971 | if (action == ATOM_TRANSMITTER_ACTION_INIT) { | ||
972 | args.v4.usInitInfo = cpu_to_le16(connector_object_id); | ||
973 | } else if (action == ATOM_TRANSMITTER_ACTION_SETUP_VSEMPH) { | ||
974 | args.v4.asMode.ucLaneSel = lane_num; | ||
975 | args.v4.asMode.ucLaneSet = lane_set; | ||
976 | } else { | ||
977 | if (is_dp) | ||
978 | args.v4.usPixelClock = | ||
979 | cpu_to_le16(dp_clock / 10); | ||
980 | else if (radeon_encoder->pixel_clock > 165000) | ||
981 | args.v4.usPixelClock = cpu_to_le16((radeon_encoder->pixel_clock / 2) / 10); | ||
982 | else | ||
983 | args.v4.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); | ||
984 | } | ||
985 | |||
986 | if (is_dp) | ||
987 | args.v4.ucLaneNum = dp_lane_count; | ||
988 | else if (radeon_encoder->pixel_clock > 165000) | ||
989 | args.v4.ucLaneNum = 8; | ||
990 | else | ||
991 | args.v4.ucLaneNum = 4; | ||
992 | |||
993 | if (dig->linkb) | ||
994 | args.v4.acConfig.ucLinkSel = 1; | ||
995 | if (dig_encoder & 1) | ||
996 | args.v4.acConfig.ucEncoderSel = 1; | ||
997 | |||
998 | /* Select the PLL for the PHY | ||
999 | * DP PHY should be clocked from external src if there is | ||
1000 | * one. | ||
1001 | */ | ||
1002 | /* On DCE5 DCPLL usually generates the DP ref clock */ | ||
1003 | if (is_dp) { | ||
1004 | if (rdev->clock.dp_extclk) | ||
1005 | args.v4.acConfig.ucRefClkSource = ENCODER_REFCLK_SRC_EXTCLK; | ||
1006 | else | ||
1007 | args.v4.acConfig.ucRefClkSource = ENCODER_REFCLK_SRC_DCPLL; | ||
1008 | } else | ||
1009 | args.v4.acConfig.ucRefClkSource = pll_id; | ||
1010 | |||
1011 | switch (radeon_encoder->encoder_id) { | ||
1012 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: | ||
1013 | args.v4.acConfig.ucTransmitterSel = 0; | ||
1014 | break; | ||
1015 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: | ||
1016 | args.v4.acConfig.ucTransmitterSel = 1; | ||
1017 | break; | ||
1018 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: | ||
1019 | args.v4.acConfig.ucTransmitterSel = 2; | ||
1020 | break; | ||
1021 | } | ||
1022 | |||
1023 | if (is_dp) | ||
1024 | args.v4.acConfig.fCoherentMode = 1; /* DP requires coherent */ | ||
1025 | else if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) { | ||
1026 | if (dig->coherent_mode) | ||
1027 | args.v4.acConfig.fCoherentMode = 1; | ||
1028 | if (radeon_encoder->pixel_clock > 165000) | ||
1029 | args.v4.acConfig.fDualLinkConnector = 1; | ||
1030 | } | ||
1031 | break; | ||
1032 | default: | ||
1033 | DRM_ERROR("Unknown table version %d, %d\n", frev, crev); | ||
1034 | break; | ||
1035 | } | ||
1036 | break; | ||
1037 | default: | ||
1038 | DRM_ERROR("Unknown table version %d, %d\n", frev, crev); | ||
1039 | break; | ||
1040 | } | ||
1041 | |||
1042 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); | ||
1043 | } | ||
1044 | |||
1045 | bool | ||
1046 | atombios_set_edp_panel_power(struct drm_connector *connector, int action) | ||
1047 | { | ||
1048 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | ||
1049 | struct drm_device *dev = radeon_connector->base.dev; | ||
1050 | struct radeon_device *rdev = dev->dev_private; | ||
1051 | union dig_transmitter_control args; | ||
1052 | int index = GetIndexIntoMasterTable(COMMAND, UNIPHYTransmitterControl); | ||
1053 | uint8_t frev, crev; | ||
1054 | |||
1055 | if (connector->connector_type != DRM_MODE_CONNECTOR_eDP) | ||
1056 | goto done; | ||
1057 | |||
1058 | if (!ASIC_IS_DCE4(rdev)) | ||
1059 | goto done; | ||
1060 | |||
1061 | if ((action != ATOM_TRANSMITTER_ACTION_POWER_ON) && | ||
1062 | (action != ATOM_TRANSMITTER_ACTION_POWER_OFF)) | ||
1063 | goto done; | ||
1064 | |||
1065 | if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev)) | ||
1066 | goto done; | ||
1067 | |||
1068 | memset(&args, 0, sizeof(args)); | ||
1069 | |||
1070 | args.v1.ucAction = action; | ||
1071 | |||
1072 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); | ||
1073 | |||
1074 | /* wait for the panel to power up */ | ||
1075 | if (action == ATOM_TRANSMITTER_ACTION_POWER_ON) { | ||
1076 | int i; | ||
1077 | |||
1078 | for (i = 0; i < 300; i++) { | ||
1079 | if (radeon_hpd_sense(rdev, radeon_connector->hpd.hpd)) | ||
1080 | return true; | ||
1081 | mdelay(1); | ||
1082 | } | ||
1083 | return false; | ||
1084 | } | ||
1085 | done: | ||
1086 | return true; | ||
1087 | } | ||
1088 | |||
1089 | union external_encoder_control { | ||
1090 | EXTERNAL_ENCODER_CONTROL_PS_ALLOCATION v1; | ||
1091 | EXTERNAL_ENCODER_CONTROL_PS_ALLOCATION_V3 v3; | ||
1092 | }; | ||
1093 | |||
1094 | static void | ||
1095 | atombios_external_encoder_setup(struct drm_encoder *encoder, | ||
1096 | struct drm_encoder *ext_encoder, | ||
1097 | int action) | ||
1098 | { | ||
1099 | struct drm_device *dev = encoder->dev; | ||
1100 | struct radeon_device *rdev = dev->dev_private; | ||
1101 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
1102 | struct radeon_encoder *ext_radeon_encoder = to_radeon_encoder(ext_encoder); | ||
1103 | union external_encoder_control args; | ||
1104 | struct drm_connector *connector; | ||
1105 | int index = GetIndexIntoMasterTable(COMMAND, ExternalEncoderControl); | ||
1106 | u8 frev, crev; | ||
1107 | int dp_clock = 0; | ||
1108 | int dp_lane_count = 0; | ||
1109 | int connector_object_id = 0; | ||
1110 | u32 ext_enum = (ext_radeon_encoder->encoder_enum & ENUM_ID_MASK) >> ENUM_ID_SHIFT; | ||
1111 | int bpc = 8; | ||
1112 | |||
1113 | if (action == EXTERNAL_ENCODER_ACTION_V3_ENCODER_INIT) | ||
1114 | connector = radeon_get_connector_for_encoder_init(encoder); | ||
1115 | else | ||
1116 | connector = radeon_get_connector_for_encoder(encoder); | ||
1117 | |||
1118 | if (connector) { | ||
1119 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | ||
1120 | struct radeon_connector_atom_dig *dig_connector = | ||
1121 | radeon_connector->con_priv; | ||
1122 | |||
1123 | dp_clock = dig_connector->dp_clock; | ||
1124 | dp_lane_count = dig_connector->dp_lane_count; | ||
1125 | connector_object_id = | ||
1126 | (radeon_connector->connector_object_id & OBJECT_ID_MASK) >> OBJECT_ID_SHIFT; | ||
1127 | bpc = connector->display_info.bpc; | ||
1128 | } | ||
1129 | |||
1130 | memset(&args, 0, sizeof(args)); | ||
1131 | |||
1132 | if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev)) | ||
1133 | return; | ||
1134 | |||
1135 | switch (frev) { | ||
1136 | case 1: | ||
1137 | /* no params on frev 1 */ | ||
1138 | break; | ||
1139 | case 2: | ||
1140 | switch (crev) { | ||
1141 | case 1: | ||
1142 | case 2: | ||
1143 | args.v1.sDigEncoder.ucAction = action; | ||
1144 | args.v1.sDigEncoder.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); | ||
1145 | args.v1.sDigEncoder.ucEncoderMode = atombios_get_encoder_mode(encoder); | ||
1146 | |||
1147 | if (ENCODER_MODE_IS_DP(args.v1.sDigEncoder.ucEncoderMode)) { | ||
1148 | if (dp_clock == 270000) | ||
1149 | args.v1.sDigEncoder.ucConfig |= ATOM_ENCODER_CONFIG_DPLINKRATE_2_70GHZ; | ||
1150 | args.v1.sDigEncoder.ucLaneNum = dp_lane_count; | ||
1151 | } else if (radeon_encoder->pixel_clock > 165000) | ||
1152 | args.v1.sDigEncoder.ucLaneNum = 8; | ||
1153 | else | ||
1154 | args.v1.sDigEncoder.ucLaneNum = 4; | ||
1155 | break; | ||
1156 | case 3: | ||
1157 | args.v3.sExtEncoder.ucAction = action; | ||
1158 | if (action == EXTERNAL_ENCODER_ACTION_V3_ENCODER_INIT) | ||
1159 | args.v3.sExtEncoder.usConnectorId = cpu_to_le16(connector_object_id); | ||
1160 | else | ||
1161 | args.v3.sExtEncoder.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); | ||
1162 | args.v3.sExtEncoder.ucEncoderMode = atombios_get_encoder_mode(encoder); | ||
1163 | |||
1164 | if (ENCODER_MODE_IS_DP(args.v3.sExtEncoder.ucEncoderMode)) { | ||
1165 | if (dp_clock == 270000) | ||
1166 | args.v3.sExtEncoder.ucConfig |= EXTERNAL_ENCODER_CONFIG_V3_DPLINKRATE_2_70GHZ; | ||
1167 | else if (dp_clock == 540000) | ||
1168 | args.v3.sExtEncoder.ucConfig |= EXTERNAL_ENCODER_CONFIG_V3_DPLINKRATE_5_40GHZ; | ||
1169 | args.v3.sExtEncoder.ucLaneNum = dp_lane_count; | ||
1170 | } else if (radeon_encoder->pixel_clock > 165000) | ||
1171 | args.v3.sExtEncoder.ucLaneNum = 8; | ||
1172 | else | ||
1173 | args.v3.sExtEncoder.ucLaneNum = 4; | ||
1174 | switch (ext_enum) { | ||
1175 | case GRAPH_OBJECT_ENUM_ID1: | ||
1176 | args.v3.sExtEncoder.ucConfig |= EXTERNAL_ENCODER_CONFIG_V3_ENCODER1; | ||
1177 | break; | ||
1178 | case GRAPH_OBJECT_ENUM_ID2: | ||
1179 | args.v3.sExtEncoder.ucConfig |= EXTERNAL_ENCODER_CONFIG_V3_ENCODER2; | ||
1180 | break; | ||
1181 | case GRAPH_OBJECT_ENUM_ID3: | ||
1182 | args.v3.sExtEncoder.ucConfig |= EXTERNAL_ENCODER_CONFIG_V3_ENCODER3; | ||
1183 | break; | ||
1184 | } | ||
1185 | switch (bpc) { | ||
1186 | case 0: | ||
1187 | args.v3.sExtEncoder.ucBitPerColor = PANEL_BPC_UNDEFINE; | ||
1188 | break; | ||
1189 | case 6: | ||
1190 | args.v3.sExtEncoder.ucBitPerColor = PANEL_6BIT_PER_COLOR; | ||
1191 | break; | ||
1192 | case 8: | ||
1193 | default: | ||
1194 | args.v3.sExtEncoder.ucBitPerColor = PANEL_8BIT_PER_COLOR; | ||
1195 | break; | ||
1196 | case 10: | ||
1197 | args.v3.sExtEncoder.ucBitPerColor = PANEL_10BIT_PER_COLOR; | ||
1198 | break; | ||
1199 | case 12: | ||
1200 | args.v3.sExtEncoder.ucBitPerColor = PANEL_12BIT_PER_COLOR; | ||
1201 | break; | ||
1202 | case 16: | ||
1203 | args.v3.sExtEncoder.ucBitPerColor = PANEL_16BIT_PER_COLOR; | ||
1204 | break; | ||
1205 | } | ||
1206 | break; | ||
1207 | default: | ||
1208 | DRM_ERROR("Unknown table version: %d, %d\n", frev, crev); | ||
1209 | return; | ||
1210 | } | ||
1211 | break; | ||
1212 | default: | ||
1213 | DRM_ERROR("Unknown table version: %d, %d\n", frev, crev); | ||
1214 | return; | ||
1215 | } | ||
1216 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); | ||
1217 | } | ||
1218 | |||
1219 | static void | ||
1220 | atombios_yuv_setup(struct drm_encoder *encoder, bool enable) | ||
1221 | { | ||
1222 | struct drm_device *dev = encoder->dev; | ||
1223 | struct radeon_device *rdev = dev->dev_private; | ||
1224 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
1225 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc); | ||
1226 | ENABLE_YUV_PS_ALLOCATION args; | ||
1227 | int index = GetIndexIntoMasterTable(COMMAND, EnableYUV); | ||
1228 | uint32_t temp, reg; | ||
1229 | |||
1230 | memset(&args, 0, sizeof(args)); | ||
1231 | |||
1232 | if (rdev->family >= CHIP_R600) | ||
1233 | reg = R600_BIOS_3_SCRATCH; | ||
1234 | else | ||
1235 | reg = RADEON_BIOS_3_SCRATCH; | ||
1236 | |||
1237 | /* XXX: fix up scratch reg handling */ | ||
1238 | temp = RREG32(reg); | ||
1239 | if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT)) | ||
1240 | WREG32(reg, (ATOM_S3_TV1_ACTIVE | | ||
1241 | (radeon_crtc->crtc_id << 18))); | ||
1242 | else if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT)) | ||
1243 | WREG32(reg, (ATOM_S3_CV_ACTIVE | (radeon_crtc->crtc_id << 24))); | ||
1244 | else | ||
1245 | WREG32(reg, 0); | ||
1246 | |||
1247 | if (enable) | ||
1248 | args.ucEnable = ATOM_ENABLE; | ||
1249 | args.ucCRTC = radeon_crtc->crtc_id; | ||
1250 | |||
1251 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); | ||
1252 | |||
1253 | WREG32(reg, temp); | ||
1254 | } | ||
1255 | |||
1256 | static void | ||
1257 | radeon_atom_encoder_dpms_avivo(struct drm_encoder *encoder, int mode) | ||
1258 | { | ||
1259 | struct drm_device *dev = encoder->dev; | ||
1260 | struct radeon_device *rdev = dev->dev_private; | ||
1261 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
1262 | DISPLAY_DEVICE_OUTPUT_CONTROL_PS_ALLOCATION args; | ||
1263 | int index = 0; | ||
1264 | |||
1265 | memset(&args, 0, sizeof(args)); | ||
1266 | |||
1267 | switch (radeon_encoder->encoder_id) { | ||
1268 | case ENCODER_OBJECT_ID_INTERNAL_TMDS1: | ||
1269 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1: | ||
1270 | index = GetIndexIntoMasterTable(COMMAND, TMDSAOutputControl); | ||
1271 | break; | ||
1272 | case ENCODER_OBJECT_ID_INTERNAL_DVO1: | ||
1273 | case ENCODER_OBJECT_ID_INTERNAL_DDI: | ||
1274 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1: | ||
1275 | index = GetIndexIntoMasterTable(COMMAND, DVOOutputControl); | ||
1276 | break; | ||
1277 | case ENCODER_OBJECT_ID_INTERNAL_LVDS: | ||
1278 | index = GetIndexIntoMasterTable(COMMAND, LCD1OutputControl); | ||
1279 | break; | ||
1280 | case ENCODER_OBJECT_ID_INTERNAL_LVTM1: | ||
1281 | if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) | ||
1282 | index = GetIndexIntoMasterTable(COMMAND, LCD1OutputControl); | ||
1283 | else | ||
1284 | index = GetIndexIntoMasterTable(COMMAND, LVTMAOutputControl); | ||
1285 | break; | ||
1286 | case ENCODER_OBJECT_ID_INTERNAL_DAC1: | ||
1287 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1: | ||
1288 | if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT)) | ||
1289 | index = GetIndexIntoMasterTable(COMMAND, TV1OutputControl); | ||
1290 | else if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT)) | ||
1291 | index = GetIndexIntoMasterTable(COMMAND, CV1OutputControl); | ||
1292 | else | ||
1293 | index = GetIndexIntoMasterTable(COMMAND, DAC1OutputControl); | ||
1294 | break; | ||
1295 | case ENCODER_OBJECT_ID_INTERNAL_DAC2: | ||
1296 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2: | ||
1297 | if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT)) | ||
1298 | index = GetIndexIntoMasterTable(COMMAND, TV1OutputControl); | ||
1299 | else if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT)) | ||
1300 | index = GetIndexIntoMasterTable(COMMAND, CV1OutputControl); | ||
1301 | else | ||
1302 | index = GetIndexIntoMasterTable(COMMAND, DAC2OutputControl); | ||
1303 | break; | ||
1304 | default: | ||
1305 | return; | ||
1306 | } | ||
1307 | |||
1308 | switch (mode) { | ||
1309 | case DRM_MODE_DPMS_ON: | ||
1310 | args.ucAction = ATOM_ENABLE; | ||
1311 | /* workaround for DVOOutputControl on some RS690 systems */ | ||
1312 | if (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_DDI) { | ||
1313 | u32 reg = RREG32(RADEON_BIOS_3_SCRATCH); | ||
1314 | WREG32(RADEON_BIOS_3_SCRATCH, reg & ~ATOM_S3_DFP2I_ACTIVE); | ||
1315 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); | ||
1316 | WREG32(RADEON_BIOS_3_SCRATCH, reg); | ||
1317 | } else | ||
1318 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); | ||
1319 | if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) { | ||
1320 | args.ucAction = ATOM_LCD_BLON; | ||
1321 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); | ||
1322 | } | ||
1323 | break; | ||
1324 | case DRM_MODE_DPMS_STANDBY: | ||
1325 | case DRM_MODE_DPMS_SUSPEND: | ||
1326 | case DRM_MODE_DPMS_OFF: | ||
1327 | args.ucAction = ATOM_DISABLE; | ||
1328 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); | ||
1329 | if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) { | ||
1330 | args.ucAction = ATOM_LCD_BLOFF; | ||
1331 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); | ||
1332 | } | ||
1333 | break; | ||
1334 | } | ||
1335 | } | ||
1336 | |||
1337 | static void | ||
1338 | radeon_atom_encoder_dpms_dig(struct drm_encoder *encoder, int mode) | ||
1339 | { | ||
1340 | struct drm_device *dev = encoder->dev; | ||
1341 | struct radeon_device *rdev = dev->dev_private; | ||
1342 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
1343 | struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); | ||
1344 | struct radeon_connector *radeon_connector = NULL; | ||
1345 | struct radeon_connector_atom_dig *radeon_dig_connector = NULL; | ||
1346 | |||
1347 | if (connector) { | ||
1348 | radeon_connector = to_radeon_connector(connector); | ||
1349 | radeon_dig_connector = radeon_connector->con_priv; | ||
1350 | } | ||
1351 | |||
1352 | switch (mode) { | ||
1353 | case DRM_MODE_DPMS_ON: | ||
1354 | /* some early dce3.2 boards have a bug in their transmitter control table */ | ||
1355 | if ((rdev->family == CHIP_RV710) || (rdev->family == CHIP_RV730)) | ||
1356 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0); | ||
1357 | else | ||
1358 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE_OUTPUT, 0, 0); | ||
1359 | if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(encoder)) && connector) { | ||
1360 | if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) { | ||
1361 | atombios_set_edp_panel_power(connector, | ||
1362 | ATOM_TRANSMITTER_ACTION_POWER_ON); | ||
1363 | radeon_dig_connector->edp_on = true; | ||
1364 | } | ||
1365 | if (ASIC_IS_DCE4(rdev)) | ||
1366 | atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_VIDEO_OFF, 0); | ||
1367 | radeon_dp_link_train(encoder, connector); | ||
1368 | if (ASIC_IS_DCE4(rdev)) | ||
1369 | atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_VIDEO_ON, 0); | ||
1370 | } | ||
1371 | if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) | ||
1372 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_LCD_BLON, 0, 0); | ||
1373 | break; | ||
1374 | case DRM_MODE_DPMS_STANDBY: | ||
1375 | case DRM_MODE_DPMS_SUSPEND: | ||
1376 | case DRM_MODE_DPMS_OFF: | ||
1377 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE_OUTPUT, 0, 0); | ||
1378 | if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(encoder)) && connector) { | ||
1379 | if (ASIC_IS_DCE4(rdev)) | ||
1380 | atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_VIDEO_OFF, 0); | ||
1381 | if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) { | ||
1382 | atombios_set_edp_panel_power(connector, | ||
1383 | ATOM_TRANSMITTER_ACTION_POWER_OFF); | ||
1384 | radeon_dig_connector->edp_on = false; | ||
1385 | } | ||
1386 | } | ||
1387 | if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) | ||
1388 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_LCD_BLOFF, 0, 0); | ||
1389 | break; | ||
1390 | } | ||
1391 | } | ||
1392 | |||
1393 | static void | ||
1394 | radeon_atom_encoder_dpms_ext(struct drm_encoder *encoder, | ||
1395 | struct drm_encoder *ext_encoder, | ||
1396 | int mode) | ||
1397 | { | ||
1398 | struct drm_device *dev = encoder->dev; | ||
1399 | struct radeon_device *rdev = dev->dev_private; | ||
1400 | |||
1401 | switch (mode) { | ||
1402 | case DRM_MODE_DPMS_ON: | ||
1403 | default: | ||
1404 | if (ASIC_IS_DCE41(rdev)) { | ||
1405 | atombios_external_encoder_setup(encoder, ext_encoder, | ||
1406 | EXTERNAL_ENCODER_ACTION_V3_ENABLE_OUTPUT); | ||
1407 | atombios_external_encoder_setup(encoder, ext_encoder, | ||
1408 | EXTERNAL_ENCODER_ACTION_V3_ENCODER_BLANKING_OFF); | ||
1409 | } else | ||
1410 | atombios_external_encoder_setup(encoder, ext_encoder, ATOM_ENABLE); | ||
1411 | break; | ||
1412 | case DRM_MODE_DPMS_STANDBY: | ||
1413 | case DRM_MODE_DPMS_SUSPEND: | ||
1414 | case DRM_MODE_DPMS_OFF: | ||
1415 | if (ASIC_IS_DCE41(rdev)) { | ||
1416 | atombios_external_encoder_setup(encoder, ext_encoder, | ||
1417 | EXTERNAL_ENCODER_ACTION_V3_ENCODER_BLANKING); | ||
1418 | atombios_external_encoder_setup(encoder, ext_encoder, | ||
1419 | EXTERNAL_ENCODER_ACTION_V3_DISABLE_OUTPUT); | ||
1420 | } else | ||
1421 | atombios_external_encoder_setup(encoder, ext_encoder, ATOM_DISABLE); | ||
1422 | break; | ||
1423 | } | ||
1424 | } | ||
1425 | |||
1426 | static void | ||
1427 | radeon_atom_encoder_dpms(struct drm_encoder *encoder, int mode) | ||
1428 | { | ||
1429 | struct drm_device *dev = encoder->dev; | ||
1430 | struct radeon_device *rdev = dev->dev_private; | ||
1431 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
1432 | struct drm_encoder *ext_encoder = radeon_get_external_encoder(encoder); | ||
1433 | |||
1434 | DRM_DEBUG_KMS("encoder dpms %d to mode %d, devices %08x, active_devices %08x\n", | ||
1435 | radeon_encoder->encoder_id, mode, radeon_encoder->devices, | ||
1436 | radeon_encoder->active_device); | ||
1437 | switch (radeon_encoder->encoder_id) { | ||
1438 | case ENCODER_OBJECT_ID_INTERNAL_TMDS1: | ||
1439 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1: | ||
1440 | case ENCODER_OBJECT_ID_INTERNAL_LVDS: | ||
1441 | case ENCODER_OBJECT_ID_INTERNAL_LVTM1: | ||
1442 | case ENCODER_OBJECT_ID_INTERNAL_DVO1: | ||
1443 | case ENCODER_OBJECT_ID_INTERNAL_DDI: | ||
1444 | case ENCODER_OBJECT_ID_INTERNAL_DAC2: | ||
1445 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2: | ||
1446 | radeon_atom_encoder_dpms_avivo(encoder, mode); | ||
1447 | break; | ||
1448 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: | ||
1449 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: | ||
1450 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: | ||
1451 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: | ||
1452 | radeon_atom_encoder_dpms_dig(encoder, mode); | ||
1453 | break; | ||
1454 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1: | ||
1455 | if (ASIC_IS_DCE5(rdev)) { | ||
1456 | switch (mode) { | ||
1457 | case DRM_MODE_DPMS_ON: | ||
1458 | atombios_dvo_setup(encoder, ATOM_ENABLE); | ||
1459 | break; | ||
1460 | case DRM_MODE_DPMS_STANDBY: | ||
1461 | case DRM_MODE_DPMS_SUSPEND: | ||
1462 | case DRM_MODE_DPMS_OFF: | ||
1463 | atombios_dvo_setup(encoder, ATOM_DISABLE); | ||
1464 | break; | ||
1465 | } | ||
1466 | } else if (ASIC_IS_DCE3(rdev)) | ||
1467 | radeon_atom_encoder_dpms_dig(encoder, mode); | ||
1468 | else | ||
1469 | radeon_atom_encoder_dpms_avivo(encoder, mode); | ||
1470 | break; | ||
1471 | case ENCODER_OBJECT_ID_INTERNAL_DAC1: | ||
1472 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1: | ||
1473 | if (ASIC_IS_DCE5(rdev)) { | ||
1474 | switch (mode) { | ||
1475 | case DRM_MODE_DPMS_ON: | ||
1476 | atombios_dac_setup(encoder, ATOM_ENABLE); | ||
1477 | break; | ||
1478 | case DRM_MODE_DPMS_STANDBY: | ||
1479 | case DRM_MODE_DPMS_SUSPEND: | ||
1480 | case DRM_MODE_DPMS_OFF: | ||
1481 | atombios_dac_setup(encoder, ATOM_DISABLE); | ||
1482 | break; | ||
1483 | } | ||
1484 | } else | ||
1485 | radeon_atom_encoder_dpms_avivo(encoder, mode); | ||
1486 | break; | ||
1487 | default: | ||
1488 | return; | ||
1489 | } | ||
1490 | |||
1491 | if (ext_encoder) | ||
1492 | radeon_atom_encoder_dpms_ext(encoder, ext_encoder, mode); | ||
1493 | |||
1494 | radeon_atombios_encoder_dpms_scratch_regs(encoder, (mode == DRM_MODE_DPMS_ON) ? true : false); | ||
1495 | |||
1496 | } | ||
1497 | |||
1498 | union crtc_source_param { | ||
1499 | SELECT_CRTC_SOURCE_PS_ALLOCATION v1; | ||
1500 | SELECT_CRTC_SOURCE_PARAMETERS_V2 v2; | ||
1501 | }; | ||
1502 | |||
1503 | static void | ||
1504 | atombios_set_encoder_crtc_source(struct drm_encoder *encoder) | ||
1505 | { | ||
1506 | struct drm_device *dev = encoder->dev; | ||
1507 | struct radeon_device *rdev = dev->dev_private; | ||
1508 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
1509 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc); | ||
1510 | union crtc_source_param args; | ||
1511 | int index = GetIndexIntoMasterTable(COMMAND, SelectCRTC_Source); | ||
1512 | uint8_t frev, crev; | ||
1513 | struct radeon_encoder_atom_dig *dig; | ||
1514 | |||
1515 | memset(&args, 0, sizeof(args)); | ||
1516 | |||
1517 | if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev)) | ||
1518 | return; | ||
1519 | |||
1520 | switch (frev) { | ||
1521 | case 1: | ||
1522 | switch (crev) { | ||
1523 | case 1: | ||
1524 | default: | ||
1525 | if (ASIC_IS_AVIVO(rdev)) | ||
1526 | args.v1.ucCRTC = radeon_crtc->crtc_id; | ||
1527 | else { | ||
1528 | if (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_DAC1) { | ||
1529 | args.v1.ucCRTC = radeon_crtc->crtc_id; | ||
1530 | } else { | ||
1531 | args.v1.ucCRTC = radeon_crtc->crtc_id << 2; | ||
1532 | } | ||
1533 | } | ||
1534 | switch (radeon_encoder->encoder_id) { | ||
1535 | case ENCODER_OBJECT_ID_INTERNAL_TMDS1: | ||
1536 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1: | ||
1537 | args.v1.ucDevice = ATOM_DEVICE_DFP1_INDEX; | ||
1538 | break; | ||
1539 | case ENCODER_OBJECT_ID_INTERNAL_LVDS: | ||
1540 | case ENCODER_OBJECT_ID_INTERNAL_LVTM1: | ||
1541 | if (radeon_encoder->devices & ATOM_DEVICE_LCD1_SUPPORT) | ||
1542 | args.v1.ucDevice = ATOM_DEVICE_LCD1_INDEX; | ||
1543 | else | ||
1544 | args.v1.ucDevice = ATOM_DEVICE_DFP3_INDEX; | ||
1545 | break; | ||
1546 | case ENCODER_OBJECT_ID_INTERNAL_DVO1: | ||
1547 | case ENCODER_OBJECT_ID_INTERNAL_DDI: | ||
1548 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1: | ||
1549 | args.v1.ucDevice = ATOM_DEVICE_DFP2_INDEX; | ||
1550 | break; | ||
1551 | case ENCODER_OBJECT_ID_INTERNAL_DAC1: | ||
1552 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1: | ||
1553 | if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT)) | ||
1554 | args.v1.ucDevice = ATOM_DEVICE_TV1_INDEX; | ||
1555 | else if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT)) | ||
1556 | args.v1.ucDevice = ATOM_DEVICE_CV_INDEX; | ||
1557 | else | ||
1558 | args.v1.ucDevice = ATOM_DEVICE_CRT1_INDEX; | ||
1559 | break; | ||
1560 | case ENCODER_OBJECT_ID_INTERNAL_DAC2: | ||
1561 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2: | ||
1562 | if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT)) | ||
1563 | args.v1.ucDevice = ATOM_DEVICE_TV1_INDEX; | ||
1564 | else if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT)) | ||
1565 | args.v1.ucDevice = ATOM_DEVICE_CV_INDEX; | ||
1566 | else | ||
1567 | args.v1.ucDevice = ATOM_DEVICE_CRT2_INDEX; | ||
1568 | break; | ||
1569 | } | ||
1570 | break; | ||
1571 | case 2: | ||
1572 | args.v2.ucCRTC = radeon_crtc->crtc_id; | ||
1573 | if (radeon_encoder_get_dp_bridge_encoder_id(encoder) != ENCODER_OBJECT_ID_NONE) { | ||
1574 | struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); | ||
1575 | |||
1576 | if (connector->connector_type == DRM_MODE_CONNECTOR_LVDS) | ||
1577 | args.v2.ucEncodeMode = ATOM_ENCODER_MODE_LVDS; | ||
1578 | else if (connector->connector_type == DRM_MODE_CONNECTOR_VGA) | ||
1579 | args.v2.ucEncodeMode = ATOM_ENCODER_MODE_CRT; | ||
1580 | else | ||
1581 | args.v2.ucEncodeMode = atombios_get_encoder_mode(encoder); | ||
1582 | } else | ||
1583 | args.v2.ucEncodeMode = atombios_get_encoder_mode(encoder); | ||
1584 | switch (radeon_encoder->encoder_id) { | ||
1585 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: | ||
1586 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: | ||
1587 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: | ||
1588 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: | ||
1589 | dig = radeon_encoder->enc_priv; | ||
1590 | switch (dig->dig_encoder) { | ||
1591 | case 0: | ||
1592 | args.v2.ucEncoderID = ASIC_INT_DIG1_ENCODER_ID; | ||
1593 | break; | ||
1594 | case 1: | ||
1595 | args.v2.ucEncoderID = ASIC_INT_DIG2_ENCODER_ID; | ||
1596 | break; | ||
1597 | case 2: | ||
1598 | args.v2.ucEncoderID = ASIC_INT_DIG3_ENCODER_ID; | ||
1599 | break; | ||
1600 | case 3: | ||
1601 | args.v2.ucEncoderID = ASIC_INT_DIG4_ENCODER_ID; | ||
1602 | break; | ||
1603 | case 4: | ||
1604 | args.v2.ucEncoderID = ASIC_INT_DIG5_ENCODER_ID; | ||
1605 | break; | ||
1606 | case 5: | ||
1607 | args.v2.ucEncoderID = ASIC_INT_DIG6_ENCODER_ID; | ||
1608 | break; | ||
1609 | } | ||
1610 | break; | ||
1611 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1: | ||
1612 | args.v2.ucEncoderID = ASIC_INT_DVO_ENCODER_ID; | ||
1613 | break; | ||
1614 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1: | ||
1615 | if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT)) | ||
1616 | args.v2.ucEncoderID = ASIC_INT_TV_ENCODER_ID; | ||
1617 | else if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT)) | ||
1618 | args.v2.ucEncoderID = ASIC_INT_TV_ENCODER_ID; | ||
1619 | else | ||
1620 | args.v2.ucEncoderID = ASIC_INT_DAC1_ENCODER_ID; | ||
1621 | break; | ||
1622 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2: | ||
1623 | if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT)) | ||
1624 | args.v2.ucEncoderID = ASIC_INT_TV_ENCODER_ID; | ||
1625 | else if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT)) | ||
1626 | args.v2.ucEncoderID = ASIC_INT_TV_ENCODER_ID; | ||
1627 | else | ||
1628 | args.v2.ucEncoderID = ASIC_INT_DAC2_ENCODER_ID; | ||
1629 | break; | ||
1630 | } | ||
1631 | break; | ||
1632 | } | ||
1633 | break; | ||
1634 | default: | ||
1635 | DRM_ERROR("Unknown table version: %d, %d\n", frev, crev); | ||
1636 | return; | ||
1637 | } | ||
1638 | |||
1639 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); | ||
1640 | |||
1641 | /* update scratch regs with new routing */ | ||
1642 | radeon_atombios_encoder_crtc_scratch_regs(encoder, radeon_crtc->crtc_id); | ||
1643 | } | ||
1644 | |||
1645 | static void | ||
1646 | atombios_apply_encoder_quirks(struct drm_encoder *encoder, | ||
1647 | struct drm_display_mode *mode) | ||
1648 | { | ||
1649 | struct drm_device *dev = encoder->dev; | ||
1650 | struct radeon_device *rdev = dev->dev_private; | ||
1651 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
1652 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc); | ||
1653 | |||
1654 | /* Funky macbooks */ | ||
1655 | if ((dev->pdev->device == 0x71C5) && | ||
1656 | (dev->pdev->subsystem_vendor == 0x106b) && | ||
1657 | (dev->pdev->subsystem_device == 0x0080)) { | ||
1658 | if (radeon_encoder->devices & ATOM_DEVICE_LCD1_SUPPORT) { | ||
1659 | uint32_t lvtma_bit_depth_control = RREG32(AVIVO_LVTMA_BIT_DEPTH_CONTROL); | ||
1660 | |||
1661 | lvtma_bit_depth_control &= ~AVIVO_LVTMA_BIT_DEPTH_CONTROL_TRUNCATE_EN; | ||
1662 | lvtma_bit_depth_control &= ~AVIVO_LVTMA_BIT_DEPTH_CONTROL_SPATIAL_DITHER_EN; | ||
1663 | |||
1664 | WREG32(AVIVO_LVTMA_BIT_DEPTH_CONTROL, lvtma_bit_depth_control); | ||
1665 | } | ||
1666 | } | ||
1667 | |||
1668 | /* set scaler clears this on some chips */ | ||
1669 | if (ASIC_IS_AVIVO(rdev) && | ||
1670 | (!(radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT)))) { | ||
1671 | if (ASIC_IS_DCE4(rdev)) { | ||
1672 | if (mode->flags & DRM_MODE_FLAG_INTERLACE) | ||
1673 | WREG32(EVERGREEN_DATA_FORMAT + radeon_crtc->crtc_offset, | ||
1674 | EVERGREEN_INTERLEAVE_EN); | ||
1675 | else | ||
1676 | WREG32(EVERGREEN_DATA_FORMAT + radeon_crtc->crtc_offset, 0); | ||
1677 | } else { | ||
1678 | if (mode->flags & DRM_MODE_FLAG_INTERLACE) | ||
1679 | WREG32(AVIVO_D1MODE_DATA_FORMAT + radeon_crtc->crtc_offset, | ||
1680 | AVIVO_D1MODE_INTERLEAVE_EN); | ||
1681 | else | ||
1682 | WREG32(AVIVO_D1MODE_DATA_FORMAT + radeon_crtc->crtc_offset, 0); | ||
1683 | } | ||
1684 | } | ||
1685 | } | ||
1686 | |||
1687 | static int radeon_atom_pick_dig_encoder(struct drm_encoder *encoder) | ||
1688 | { | ||
1689 | struct drm_device *dev = encoder->dev; | ||
1690 | struct radeon_device *rdev = dev->dev_private; | ||
1691 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc); | ||
1692 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
1693 | struct drm_encoder *test_encoder; | ||
1694 | struct radeon_encoder_atom_dig *dig; | ||
1695 | uint32_t dig_enc_in_use = 0; | ||
1696 | |||
1697 | /* DCE4/5 */ | ||
1698 | if (ASIC_IS_DCE4(rdev)) { | ||
1699 | dig = radeon_encoder->enc_priv; | ||
1700 | if (ASIC_IS_DCE41(rdev)) { | ||
1701 | /* ontario follows DCE4 */ | ||
1702 | if (rdev->family == CHIP_PALM) { | ||
1703 | if (dig->linkb) | ||
1704 | return 1; | ||
1705 | else | ||
1706 | return 0; | ||
1707 | } else | ||
1708 | /* llano follows DCE3.2 */ | ||
1709 | return radeon_crtc->crtc_id; | ||
1710 | } else { | ||
1711 | switch (radeon_encoder->encoder_id) { | ||
1712 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: | ||
1713 | if (dig->linkb) | ||
1714 | return 1; | ||
1715 | else | ||
1716 | return 0; | ||
1717 | break; | ||
1718 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: | ||
1719 | if (dig->linkb) | ||
1720 | return 3; | ||
1721 | else | ||
1722 | return 2; | ||
1723 | break; | ||
1724 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: | ||
1725 | if (dig->linkb) | ||
1726 | return 5; | ||
1727 | else | ||
1728 | return 4; | ||
1729 | break; | ||
1730 | } | ||
1731 | } | ||
1732 | } | ||
1733 | |||
1734 | /* on DCE32 and encoder can driver any block so just crtc id */ | ||
1735 | if (ASIC_IS_DCE32(rdev)) { | ||
1736 | return radeon_crtc->crtc_id; | ||
1737 | } | ||
1738 | |||
1739 | /* on DCE3 - LVTMA can only be driven by DIGB */ | ||
1740 | list_for_each_entry(test_encoder, &dev->mode_config.encoder_list, head) { | ||
1741 | struct radeon_encoder *radeon_test_encoder; | ||
1742 | |||
1743 | if (encoder == test_encoder) | ||
1744 | continue; | ||
1745 | |||
1746 | if (!radeon_encoder_is_digital(test_encoder)) | ||
1747 | continue; | ||
1748 | |||
1749 | radeon_test_encoder = to_radeon_encoder(test_encoder); | ||
1750 | dig = radeon_test_encoder->enc_priv; | ||
1751 | |||
1752 | if (dig->dig_encoder >= 0) | ||
1753 | dig_enc_in_use |= (1 << dig->dig_encoder); | ||
1754 | } | ||
1755 | |||
1756 | if (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA) { | ||
1757 | if (dig_enc_in_use & 0x2) | ||
1758 | DRM_ERROR("LVDS required digital encoder 2 but it was in use - stealing\n"); | ||
1759 | return 1; | ||
1760 | } | ||
1761 | if (!(dig_enc_in_use & 1)) | ||
1762 | return 0; | ||
1763 | return 1; | ||
1764 | } | ||
1765 | |||
1766 | /* This only needs to be called once at startup */ | ||
1767 | void | ||
1768 | radeon_atom_encoder_init(struct radeon_device *rdev) | ||
1769 | { | ||
1770 | struct drm_device *dev = rdev->ddev; | ||
1771 | struct drm_encoder *encoder; | ||
1772 | |||
1773 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { | ||
1774 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
1775 | struct drm_encoder *ext_encoder = radeon_get_external_encoder(encoder); | ||
1776 | |||
1777 | switch (radeon_encoder->encoder_id) { | ||
1778 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: | ||
1779 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: | ||
1780 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: | ||
1781 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: | ||
1782 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_INIT, 0, 0); | ||
1783 | break; | ||
1784 | default: | ||
1785 | break; | ||
1786 | } | ||
1787 | |||
1788 | if (ext_encoder && ASIC_IS_DCE41(rdev)) | ||
1789 | atombios_external_encoder_setup(encoder, ext_encoder, | ||
1790 | EXTERNAL_ENCODER_ACTION_V3_ENCODER_INIT); | ||
1791 | } | ||
1792 | } | ||
1793 | |||
1794 | static void | ||
1795 | radeon_atom_encoder_mode_set(struct drm_encoder *encoder, | ||
1796 | struct drm_display_mode *mode, | ||
1797 | struct drm_display_mode *adjusted_mode) | ||
1798 | { | ||
1799 | struct drm_device *dev = encoder->dev; | ||
1800 | struct radeon_device *rdev = dev->dev_private; | ||
1801 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
1802 | struct drm_encoder *ext_encoder = radeon_get_external_encoder(encoder); | ||
1803 | |||
1804 | radeon_encoder->pixel_clock = adjusted_mode->clock; | ||
1805 | |||
1806 | if (ASIC_IS_AVIVO(rdev) && !ASIC_IS_DCE4(rdev)) { | ||
1807 | if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT | ATOM_DEVICE_TV_SUPPORT)) | ||
1808 | atombios_yuv_setup(encoder, true); | ||
1809 | else | ||
1810 | atombios_yuv_setup(encoder, false); | ||
1811 | } | ||
1812 | |||
1813 | switch (radeon_encoder->encoder_id) { | ||
1814 | case ENCODER_OBJECT_ID_INTERNAL_TMDS1: | ||
1815 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1: | ||
1816 | case ENCODER_OBJECT_ID_INTERNAL_LVDS: | ||
1817 | case ENCODER_OBJECT_ID_INTERNAL_LVTM1: | ||
1818 | atombios_digital_setup(encoder, PANEL_ENCODER_ACTION_ENABLE); | ||
1819 | break; | ||
1820 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: | ||
1821 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: | ||
1822 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: | ||
1823 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: | ||
1824 | if (ASIC_IS_DCE4(rdev)) { | ||
1825 | /* disable the transmitter */ | ||
1826 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0); | ||
1827 | /* setup and enable the encoder */ | ||
1828 | atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_SETUP, 0); | ||
1829 | |||
1830 | /* enable the transmitter */ | ||
1831 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0); | ||
1832 | } else { | ||
1833 | /* disable the encoder and transmitter */ | ||
1834 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0); | ||
1835 | atombios_dig_encoder_setup(encoder, ATOM_DISABLE, 0); | ||
1836 | |||
1837 | /* setup and enable the encoder and transmitter */ | ||
1838 | atombios_dig_encoder_setup(encoder, ATOM_ENABLE, 0); | ||
1839 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_SETUP, 0, 0); | ||
1840 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0); | ||
1841 | } | ||
1842 | break; | ||
1843 | case ENCODER_OBJECT_ID_INTERNAL_DDI: | ||
1844 | case ENCODER_OBJECT_ID_INTERNAL_DVO1: | ||
1845 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1: | ||
1846 | atombios_dvo_setup(encoder, ATOM_ENABLE); | ||
1847 | break; | ||
1848 | case ENCODER_OBJECT_ID_INTERNAL_DAC1: | ||
1849 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1: | ||
1850 | case ENCODER_OBJECT_ID_INTERNAL_DAC2: | ||
1851 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2: | ||
1852 | atombios_dac_setup(encoder, ATOM_ENABLE); | ||
1853 | if (radeon_encoder->devices & (ATOM_DEVICE_TV_SUPPORT | ATOM_DEVICE_CV_SUPPORT)) { | ||
1854 | if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT | ATOM_DEVICE_CV_SUPPORT)) | ||
1855 | atombios_tv_setup(encoder, ATOM_ENABLE); | ||
1856 | else | ||
1857 | atombios_tv_setup(encoder, ATOM_DISABLE); | ||
1858 | } | ||
1859 | break; | ||
1860 | } | ||
1861 | |||
1862 | if (ext_encoder) { | ||
1863 | if (ASIC_IS_DCE41(rdev)) | ||
1864 | atombios_external_encoder_setup(encoder, ext_encoder, | ||
1865 | EXTERNAL_ENCODER_ACTION_V3_ENCODER_SETUP); | ||
1866 | else | ||
1867 | atombios_external_encoder_setup(encoder, ext_encoder, ATOM_ENABLE); | ||
1868 | } | ||
1869 | |||
1870 | atombios_apply_encoder_quirks(encoder, adjusted_mode); | ||
1871 | |||
1872 | if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_HDMI) { | ||
1873 | r600_hdmi_enable(encoder); | ||
1874 | r600_hdmi_setmode(encoder, adjusted_mode); | ||
1875 | } | ||
1876 | } | ||
1877 | |||
1878 | static bool | ||
1879 | atombios_dac_load_detect(struct drm_encoder *encoder, struct drm_connector *connector) | ||
1880 | { | ||
1881 | struct drm_device *dev = encoder->dev; | ||
1882 | struct radeon_device *rdev = dev->dev_private; | ||
1883 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
1884 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | ||
1885 | |||
1886 | if (radeon_encoder->devices & (ATOM_DEVICE_TV_SUPPORT | | ||
1887 | ATOM_DEVICE_CV_SUPPORT | | ||
1888 | ATOM_DEVICE_CRT_SUPPORT)) { | ||
1889 | DAC_LOAD_DETECTION_PS_ALLOCATION args; | ||
1890 | int index = GetIndexIntoMasterTable(COMMAND, DAC_LoadDetection); | ||
1891 | uint8_t frev, crev; | ||
1892 | |||
1893 | memset(&args, 0, sizeof(args)); | ||
1894 | |||
1895 | if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev)) | ||
1896 | return false; | ||
1897 | |||
1898 | args.sDacload.ucMisc = 0; | ||
1899 | |||
1900 | if ((radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_DAC1) || | ||
1901 | (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1)) | ||
1902 | args.sDacload.ucDacType = ATOM_DAC_A; | ||
1903 | else | ||
1904 | args.sDacload.ucDacType = ATOM_DAC_B; | ||
1905 | |||
1906 | if (radeon_connector->devices & ATOM_DEVICE_CRT1_SUPPORT) | ||
1907 | args.sDacload.usDeviceID = cpu_to_le16(ATOM_DEVICE_CRT1_SUPPORT); | ||
1908 | else if (radeon_connector->devices & ATOM_DEVICE_CRT2_SUPPORT) | ||
1909 | args.sDacload.usDeviceID = cpu_to_le16(ATOM_DEVICE_CRT2_SUPPORT); | ||
1910 | else if (radeon_connector->devices & ATOM_DEVICE_CV_SUPPORT) { | ||
1911 | args.sDacload.usDeviceID = cpu_to_le16(ATOM_DEVICE_CV_SUPPORT); | ||
1912 | if (crev >= 3) | ||
1913 | args.sDacload.ucMisc = DAC_LOAD_MISC_YPrPb; | ||
1914 | } else if (radeon_connector->devices & ATOM_DEVICE_TV1_SUPPORT) { | ||
1915 | args.sDacload.usDeviceID = cpu_to_le16(ATOM_DEVICE_TV1_SUPPORT); | ||
1916 | if (crev >= 3) | ||
1917 | args.sDacload.ucMisc = DAC_LOAD_MISC_YPrPb; | ||
1918 | } | ||
1919 | |||
1920 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); | ||
1921 | |||
1922 | return true; | ||
1923 | } else | ||
1924 | return false; | ||
1925 | } | ||
1926 | |||
1927 | static enum drm_connector_status | ||
1928 | radeon_atom_dac_detect(struct drm_encoder *encoder, struct drm_connector *connector) | ||
1929 | { | ||
1930 | struct drm_device *dev = encoder->dev; | ||
1931 | struct radeon_device *rdev = dev->dev_private; | ||
1932 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
1933 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | ||
1934 | uint32_t bios_0_scratch; | ||
1935 | |||
1936 | if (!atombios_dac_load_detect(encoder, connector)) { | ||
1937 | DRM_DEBUG_KMS("detect returned false \n"); | ||
1938 | return connector_status_unknown; | ||
1939 | } | ||
1940 | |||
1941 | if (rdev->family >= CHIP_R600) | ||
1942 | bios_0_scratch = RREG32(R600_BIOS_0_SCRATCH); | ||
1943 | else | ||
1944 | bios_0_scratch = RREG32(RADEON_BIOS_0_SCRATCH); | ||
1945 | |||
1946 | DRM_DEBUG_KMS("Bios 0 scratch %x %08x\n", bios_0_scratch, radeon_encoder->devices); | ||
1947 | if (radeon_connector->devices & ATOM_DEVICE_CRT1_SUPPORT) { | ||
1948 | if (bios_0_scratch & ATOM_S0_CRT1_MASK) | ||
1949 | return connector_status_connected; | ||
1950 | } | ||
1951 | if (radeon_connector->devices & ATOM_DEVICE_CRT2_SUPPORT) { | ||
1952 | if (bios_0_scratch & ATOM_S0_CRT2_MASK) | ||
1953 | return connector_status_connected; | ||
1954 | } | ||
1955 | if (radeon_connector->devices & ATOM_DEVICE_CV_SUPPORT) { | ||
1956 | if (bios_0_scratch & (ATOM_S0_CV_MASK|ATOM_S0_CV_MASK_A)) | ||
1957 | return connector_status_connected; | ||
1958 | } | ||
1959 | if (radeon_connector->devices & ATOM_DEVICE_TV1_SUPPORT) { | ||
1960 | if (bios_0_scratch & (ATOM_S0_TV1_COMPOSITE | ATOM_S0_TV1_COMPOSITE_A)) | ||
1961 | return connector_status_connected; /* CTV */ | ||
1962 | else if (bios_0_scratch & (ATOM_S0_TV1_SVIDEO | ATOM_S0_TV1_SVIDEO_A)) | ||
1963 | return connector_status_connected; /* STV */ | ||
1964 | } | ||
1965 | return connector_status_disconnected; | ||
1966 | } | ||
1967 | |||
1968 | static enum drm_connector_status | ||
1969 | radeon_atom_dig_detect(struct drm_encoder *encoder, struct drm_connector *connector) | ||
1970 | { | ||
1971 | struct drm_device *dev = encoder->dev; | ||
1972 | struct radeon_device *rdev = dev->dev_private; | ||
1973 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
1974 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | ||
1975 | struct drm_encoder *ext_encoder = radeon_get_external_encoder(encoder); | ||
1976 | u32 bios_0_scratch; | ||
1977 | |||
1978 | if (!ASIC_IS_DCE4(rdev)) | ||
1979 | return connector_status_unknown; | ||
1980 | |||
1981 | if (!ext_encoder) | ||
1982 | return connector_status_unknown; | ||
1983 | |||
1984 | if ((radeon_connector->devices & ATOM_DEVICE_CRT_SUPPORT) == 0) | ||
1985 | return connector_status_unknown; | ||
1986 | |||
1987 | /* load detect on the dp bridge */ | ||
1988 | atombios_external_encoder_setup(encoder, ext_encoder, | ||
1989 | EXTERNAL_ENCODER_ACTION_V3_DACLOAD_DETECTION); | ||
1990 | |||
1991 | bios_0_scratch = RREG32(R600_BIOS_0_SCRATCH); | ||
1992 | |||
1993 | DRM_DEBUG_KMS("Bios 0 scratch %x %08x\n", bios_0_scratch, radeon_encoder->devices); | ||
1994 | if (radeon_connector->devices & ATOM_DEVICE_CRT1_SUPPORT) { | ||
1995 | if (bios_0_scratch & ATOM_S0_CRT1_MASK) | ||
1996 | return connector_status_connected; | ||
1997 | } | ||
1998 | if (radeon_connector->devices & ATOM_DEVICE_CRT2_SUPPORT) { | ||
1999 | if (bios_0_scratch & ATOM_S0_CRT2_MASK) | ||
2000 | return connector_status_connected; | ||
2001 | } | ||
2002 | if (radeon_connector->devices & ATOM_DEVICE_CV_SUPPORT) { | ||
2003 | if (bios_0_scratch & (ATOM_S0_CV_MASK|ATOM_S0_CV_MASK_A)) | ||
2004 | return connector_status_connected; | ||
2005 | } | ||
2006 | if (radeon_connector->devices & ATOM_DEVICE_TV1_SUPPORT) { | ||
2007 | if (bios_0_scratch & (ATOM_S0_TV1_COMPOSITE | ATOM_S0_TV1_COMPOSITE_A)) | ||
2008 | return connector_status_connected; /* CTV */ | ||
2009 | else if (bios_0_scratch & (ATOM_S0_TV1_SVIDEO | ATOM_S0_TV1_SVIDEO_A)) | ||
2010 | return connector_status_connected; /* STV */ | ||
2011 | } | ||
2012 | return connector_status_disconnected; | ||
2013 | } | ||
2014 | |||
2015 | void | ||
2016 | radeon_atom_ext_encoder_setup_ddc(struct drm_encoder *encoder) | ||
2017 | { | ||
2018 | struct drm_encoder *ext_encoder = radeon_get_external_encoder(encoder); | ||
2019 | |||
2020 | if (ext_encoder) | ||
2021 | /* ddc_setup on the dp bridge */ | ||
2022 | atombios_external_encoder_setup(encoder, ext_encoder, | ||
2023 | EXTERNAL_ENCODER_ACTION_V3_DDC_SETUP); | ||
2024 | |||
2025 | } | ||
2026 | |||
2027 | static void radeon_atom_encoder_prepare(struct drm_encoder *encoder) | ||
2028 | { | ||
2029 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
2030 | struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); | ||
2031 | |||
2032 | if ((radeon_encoder->active_device & | ||
2033 | (ATOM_DEVICE_DFP_SUPPORT | ATOM_DEVICE_LCD_SUPPORT)) || | ||
2034 | (radeon_encoder_get_dp_bridge_encoder_id(encoder) != | ||
2035 | ENCODER_OBJECT_ID_NONE)) { | ||
2036 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; | ||
2037 | if (dig) | ||
2038 | dig->dig_encoder = radeon_atom_pick_dig_encoder(encoder); | ||
2039 | } | ||
2040 | |||
2041 | radeon_atom_output_lock(encoder, true); | ||
2042 | radeon_atom_encoder_dpms(encoder, DRM_MODE_DPMS_OFF); | ||
2043 | |||
2044 | if (connector) { | ||
2045 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | ||
2046 | |||
2047 | /* select the clock/data port if it uses a router */ | ||
2048 | if (radeon_connector->router.cd_valid) | ||
2049 | radeon_router_select_cd_port(radeon_connector); | ||
2050 | |||
2051 | /* turn eDP panel on for mode set */ | ||
2052 | if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) | ||
2053 | atombios_set_edp_panel_power(connector, | ||
2054 | ATOM_TRANSMITTER_ACTION_POWER_ON); | ||
2055 | } | ||
2056 | |||
2057 | /* this is needed for the pll/ss setup to work correctly in some cases */ | ||
2058 | atombios_set_encoder_crtc_source(encoder); | ||
2059 | } | ||
2060 | |||
2061 | static void radeon_atom_encoder_commit(struct drm_encoder *encoder) | ||
2062 | { | ||
2063 | radeon_atom_encoder_dpms(encoder, DRM_MODE_DPMS_ON); | ||
2064 | radeon_atom_output_lock(encoder, false); | ||
2065 | } | ||
2066 | |||
2067 | static void radeon_atom_encoder_disable(struct drm_encoder *encoder) | ||
2068 | { | ||
2069 | struct drm_device *dev = encoder->dev; | ||
2070 | struct radeon_device *rdev = dev->dev_private; | ||
2071 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
2072 | struct radeon_encoder_atom_dig *dig; | ||
2073 | |||
2074 | /* check for pre-DCE3 cards with shared encoders; | ||
2075 | * can't really use the links individually, so don't disable | ||
2076 | * the encoder if it's in use by another connector | ||
2077 | */ | ||
2078 | if (!ASIC_IS_DCE3(rdev)) { | ||
2079 | struct drm_encoder *other_encoder; | ||
2080 | struct radeon_encoder *other_radeon_encoder; | ||
2081 | |||
2082 | list_for_each_entry(other_encoder, &dev->mode_config.encoder_list, head) { | ||
2083 | other_radeon_encoder = to_radeon_encoder(other_encoder); | ||
2084 | if ((radeon_encoder->encoder_id == other_radeon_encoder->encoder_id) && | ||
2085 | drm_helper_encoder_in_use(other_encoder)) | ||
2086 | goto disable_done; | ||
2087 | } | ||
2088 | } | ||
2089 | |||
2090 | radeon_atom_encoder_dpms(encoder, DRM_MODE_DPMS_OFF); | ||
2091 | |||
2092 | switch (radeon_encoder->encoder_id) { | ||
2093 | case ENCODER_OBJECT_ID_INTERNAL_TMDS1: | ||
2094 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1: | ||
2095 | case ENCODER_OBJECT_ID_INTERNAL_LVDS: | ||
2096 | case ENCODER_OBJECT_ID_INTERNAL_LVTM1: | ||
2097 | atombios_digital_setup(encoder, PANEL_ENCODER_ACTION_DISABLE); | ||
2098 | break; | ||
2099 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: | ||
2100 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: | ||
2101 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: | ||
2102 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: | ||
2103 | if (ASIC_IS_DCE4(rdev)) | ||
2104 | /* disable the transmitter */ | ||
2105 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0); | ||
2106 | else { | ||
2107 | /* disable the encoder and transmitter */ | ||
2108 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0); | ||
2109 | atombios_dig_encoder_setup(encoder, ATOM_DISABLE, 0); | ||
2110 | } | ||
2111 | break; | ||
2112 | case ENCODER_OBJECT_ID_INTERNAL_DDI: | ||
2113 | case ENCODER_OBJECT_ID_INTERNAL_DVO1: | ||
2114 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1: | ||
2115 | atombios_dvo_setup(encoder, ATOM_DISABLE); | ||
2116 | break; | ||
2117 | case ENCODER_OBJECT_ID_INTERNAL_DAC1: | ||
2118 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1: | ||
2119 | case ENCODER_OBJECT_ID_INTERNAL_DAC2: | ||
2120 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2: | ||
2121 | atombios_dac_setup(encoder, ATOM_DISABLE); | ||
2122 | if (radeon_encoder->devices & (ATOM_DEVICE_TV_SUPPORT | ATOM_DEVICE_CV_SUPPORT)) | ||
2123 | atombios_tv_setup(encoder, ATOM_DISABLE); | ||
2124 | break; | ||
2125 | } | ||
2126 | |||
2127 | disable_done: | ||
2128 | if (radeon_encoder_is_digital(encoder)) { | ||
2129 | if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_HDMI) | ||
2130 | r600_hdmi_disable(encoder); | ||
2131 | dig = radeon_encoder->enc_priv; | ||
2132 | dig->dig_encoder = -1; | ||
2133 | } | ||
2134 | radeon_encoder->active_device = 0; | ||
2135 | } | ||
2136 | |||
2137 | /* these are handled by the primary encoders */ | ||
2138 | static void radeon_atom_ext_prepare(struct drm_encoder *encoder) | ||
2139 | { | ||
2140 | |||
2141 | } | ||
2142 | |||
2143 | static void radeon_atom_ext_commit(struct drm_encoder *encoder) | ||
2144 | { | ||
2145 | |||
2146 | } | ||
2147 | |||
2148 | static void | ||
2149 | radeon_atom_ext_mode_set(struct drm_encoder *encoder, | ||
2150 | struct drm_display_mode *mode, | ||
2151 | struct drm_display_mode *adjusted_mode) | ||
2152 | { | ||
2153 | |||
2154 | } | ||
2155 | |||
2156 | static void radeon_atom_ext_disable(struct drm_encoder *encoder) | ||
2157 | { | ||
2158 | |||
2159 | } | ||
2160 | |||
2161 | static void | ||
2162 | radeon_atom_ext_dpms(struct drm_encoder *encoder, int mode) | ||
2163 | { | ||
2164 | |||
2165 | } | ||
2166 | |||
2167 | static bool radeon_atom_ext_mode_fixup(struct drm_encoder *encoder, | ||
2168 | struct drm_display_mode *mode, | ||
2169 | struct drm_display_mode *adjusted_mode) | ||
2170 | { | ||
2171 | return true; | ||
2172 | } | ||
2173 | |||
2174 | static const struct drm_encoder_helper_funcs radeon_atom_ext_helper_funcs = { | ||
2175 | .dpms = radeon_atom_ext_dpms, | ||
2176 | .mode_fixup = radeon_atom_ext_mode_fixup, | ||
2177 | .prepare = radeon_atom_ext_prepare, | ||
2178 | .mode_set = radeon_atom_ext_mode_set, | ||
2179 | .commit = radeon_atom_ext_commit, | ||
2180 | .disable = radeon_atom_ext_disable, | ||
2181 | /* no detect for TMDS/LVDS yet */ | ||
2182 | }; | ||
2183 | |||
2184 | static const struct drm_encoder_helper_funcs radeon_atom_dig_helper_funcs = { | ||
2185 | .dpms = radeon_atom_encoder_dpms, | ||
2186 | .mode_fixup = radeon_atom_mode_fixup, | ||
2187 | .prepare = radeon_atom_encoder_prepare, | ||
2188 | .mode_set = radeon_atom_encoder_mode_set, | ||
2189 | .commit = radeon_atom_encoder_commit, | ||
2190 | .disable = radeon_atom_encoder_disable, | ||
2191 | .detect = radeon_atom_dig_detect, | ||
2192 | }; | ||
2193 | |||
2194 | static const struct drm_encoder_helper_funcs radeon_atom_dac_helper_funcs = { | ||
2195 | .dpms = radeon_atom_encoder_dpms, | ||
2196 | .mode_fixup = radeon_atom_mode_fixup, | ||
2197 | .prepare = radeon_atom_encoder_prepare, | ||
2198 | .mode_set = radeon_atom_encoder_mode_set, | ||
2199 | .commit = radeon_atom_encoder_commit, | ||
2200 | .detect = radeon_atom_dac_detect, | ||
2201 | }; | ||
2202 | |||
2203 | void radeon_enc_destroy(struct drm_encoder *encoder) | ||
2204 | { | ||
2205 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
2206 | kfree(radeon_encoder->enc_priv); | ||
2207 | drm_encoder_cleanup(encoder); | ||
2208 | kfree(radeon_encoder); | ||
2209 | } | ||
2210 | |||
2211 | static const struct drm_encoder_funcs radeon_atom_enc_funcs = { | ||
2212 | .destroy = radeon_enc_destroy, | ||
2213 | }; | ||
2214 | |||
2215 | struct radeon_encoder_atom_dac * | ||
2216 | radeon_atombios_set_dac_info(struct radeon_encoder *radeon_encoder) | ||
2217 | { | ||
2218 | struct drm_device *dev = radeon_encoder->base.dev; | ||
2219 | struct radeon_device *rdev = dev->dev_private; | ||
2220 | struct radeon_encoder_atom_dac *dac = kzalloc(sizeof(struct radeon_encoder_atom_dac), GFP_KERNEL); | ||
2221 | |||
2222 | if (!dac) | ||
2223 | return NULL; | ||
2224 | |||
2225 | dac->tv_std = radeon_atombios_get_tv_info(rdev); | ||
2226 | return dac; | ||
2227 | } | ||
2228 | |||
2229 | struct radeon_encoder_atom_dig * | ||
2230 | radeon_atombios_set_dig_info(struct radeon_encoder *radeon_encoder) | ||
2231 | { | ||
2232 | int encoder_enum = (radeon_encoder->encoder_enum & ENUM_ID_MASK) >> ENUM_ID_SHIFT; | ||
2233 | struct radeon_encoder_atom_dig *dig = kzalloc(sizeof(struct radeon_encoder_atom_dig), GFP_KERNEL); | ||
2234 | |||
2235 | if (!dig) | ||
2236 | return NULL; | ||
2237 | |||
2238 | /* coherent mode by default */ | ||
2239 | dig->coherent_mode = true; | ||
2240 | dig->dig_encoder = -1; | ||
2241 | |||
2242 | if (encoder_enum == 2) | ||
2243 | dig->linkb = true; | ||
2244 | else | ||
2245 | dig->linkb = false; | ||
2246 | |||
2247 | return dig; | ||
2248 | } | ||
2249 | |||
2250 | void | ||
2251 | radeon_add_atom_encoder(struct drm_device *dev, | ||
2252 | uint32_t encoder_enum, | ||
2253 | uint32_t supported_device, | ||
2254 | u16 caps) | ||
2255 | { | ||
2256 | struct radeon_device *rdev = dev->dev_private; | ||
2257 | struct drm_encoder *encoder; | ||
2258 | struct radeon_encoder *radeon_encoder; | ||
2259 | |||
2260 | /* see if we already added it */ | ||
2261 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { | ||
2262 | radeon_encoder = to_radeon_encoder(encoder); | ||
2263 | if (radeon_encoder->encoder_enum == encoder_enum) { | ||
2264 | radeon_encoder->devices |= supported_device; | ||
2265 | return; | ||
2266 | } | ||
2267 | |||
2268 | } | ||
2269 | |||
2270 | /* add a new one */ | ||
2271 | radeon_encoder = kzalloc(sizeof(struct radeon_encoder), GFP_KERNEL); | ||
2272 | if (!radeon_encoder) | ||
2273 | return; | ||
2274 | |||
2275 | encoder = &radeon_encoder->base; | ||
2276 | switch (rdev->num_crtc) { | ||
2277 | case 1: | ||
2278 | encoder->possible_crtcs = 0x1; | ||
2279 | break; | ||
2280 | case 2: | ||
2281 | default: | ||
2282 | encoder->possible_crtcs = 0x3; | ||
2283 | break; | ||
2284 | case 4: | ||
2285 | encoder->possible_crtcs = 0xf; | ||
2286 | break; | ||
2287 | case 6: | ||
2288 | encoder->possible_crtcs = 0x3f; | ||
2289 | break; | ||
2290 | } | ||
2291 | |||
2292 | radeon_encoder->enc_priv = NULL; | ||
2293 | |||
2294 | radeon_encoder->encoder_enum = encoder_enum; | ||
2295 | radeon_encoder->encoder_id = (encoder_enum & OBJECT_ID_MASK) >> OBJECT_ID_SHIFT; | ||
2296 | radeon_encoder->devices = supported_device; | ||
2297 | radeon_encoder->rmx_type = RMX_OFF; | ||
2298 | radeon_encoder->underscan_type = UNDERSCAN_OFF; | ||
2299 | radeon_encoder->is_ext_encoder = false; | ||
2300 | radeon_encoder->caps = caps; | ||
2301 | |||
2302 | switch (radeon_encoder->encoder_id) { | ||
2303 | case ENCODER_OBJECT_ID_INTERNAL_LVDS: | ||
2304 | case ENCODER_OBJECT_ID_INTERNAL_TMDS1: | ||
2305 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1: | ||
2306 | case ENCODER_OBJECT_ID_INTERNAL_LVTM1: | ||
2307 | if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) { | ||
2308 | radeon_encoder->rmx_type = RMX_FULL; | ||
2309 | drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_LVDS); | ||
2310 | radeon_encoder->enc_priv = radeon_atombios_get_lvds_info(radeon_encoder); | ||
2311 | } else { | ||
2312 | drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_TMDS); | ||
2313 | radeon_encoder->enc_priv = radeon_atombios_set_dig_info(radeon_encoder); | ||
2314 | } | ||
2315 | drm_encoder_helper_add(encoder, &radeon_atom_dig_helper_funcs); | ||
2316 | break; | ||
2317 | case ENCODER_OBJECT_ID_INTERNAL_DAC1: | ||
2318 | drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_DAC); | ||
2319 | radeon_encoder->enc_priv = radeon_atombios_set_dac_info(radeon_encoder); | ||
2320 | drm_encoder_helper_add(encoder, &radeon_atom_dac_helper_funcs); | ||
2321 | break; | ||
2322 | case ENCODER_OBJECT_ID_INTERNAL_DAC2: | ||
2323 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1: | ||
2324 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2: | ||
2325 | drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_TVDAC); | ||
2326 | radeon_encoder->enc_priv = radeon_atombios_set_dac_info(radeon_encoder); | ||
2327 | drm_encoder_helper_add(encoder, &radeon_atom_dac_helper_funcs); | ||
2328 | break; | ||
2329 | case ENCODER_OBJECT_ID_INTERNAL_DVO1: | ||
2330 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1: | ||
2331 | case ENCODER_OBJECT_ID_INTERNAL_DDI: | ||
2332 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: | ||
2333 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: | ||
2334 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: | ||
2335 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: | ||
2336 | if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) { | ||
2337 | radeon_encoder->rmx_type = RMX_FULL; | ||
2338 | drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_LVDS); | ||
2339 | radeon_encoder->enc_priv = radeon_atombios_get_lvds_info(radeon_encoder); | ||
2340 | } else if (radeon_encoder->devices & (ATOM_DEVICE_CRT_SUPPORT)) { | ||
2341 | drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_DAC); | ||
2342 | radeon_encoder->enc_priv = radeon_atombios_set_dig_info(radeon_encoder); | ||
2343 | } else { | ||
2344 | drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_TMDS); | ||
2345 | radeon_encoder->enc_priv = radeon_atombios_set_dig_info(radeon_encoder); | ||
2346 | } | ||
2347 | drm_encoder_helper_add(encoder, &radeon_atom_dig_helper_funcs); | ||
2348 | break; | ||
2349 | case ENCODER_OBJECT_ID_SI170B: | ||
2350 | case ENCODER_OBJECT_ID_CH7303: | ||
2351 | case ENCODER_OBJECT_ID_EXTERNAL_SDVOA: | ||
2352 | case ENCODER_OBJECT_ID_EXTERNAL_SDVOB: | ||
2353 | case ENCODER_OBJECT_ID_TITFP513: | ||
2354 | case ENCODER_OBJECT_ID_VT1623: | ||
2355 | case ENCODER_OBJECT_ID_HDMI_SI1930: | ||
2356 | case ENCODER_OBJECT_ID_TRAVIS: | ||
2357 | case ENCODER_OBJECT_ID_NUTMEG: | ||
2358 | /* these are handled by the primary encoders */ | ||
2359 | radeon_encoder->is_ext_encoder = true; | ||
2360 | if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) | ||
2361 | drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_LVDS); | ||
2362 | else if (radeon_encoder->devices & (ATOM_DEVICE_CRT_SUPPORT)) | ||
2363 | drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_DAC); | ||
2364 | else | ||
2365 | drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_TMDS); | ||
2366 | drm_encoder_helper_add(encoder, &radeon_atom_ext_helper_funcs); | ||
2367 | break; | ||
2368 | } | ||
2369 | } | ||
diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index ed406e8404a3..e4c384b9511c 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c | |||
@@ -353,6 +353,7 @@ void evergreen_hpd_init(struct radeon_device *rdev) | |||
353 | default: | 353 | default: |
354 | break; | 354 | break; |
355 | } | 355 | } |
356 | radeon_hpd_set_polarity(rdev, radeon_connector->hpd.hpd); | ||
356 | } | 357 | } |
357 | if (rdev->irq.installed) | 358 | if (rdev->irq.installed) |
358 | evergreen_irq_set(rdev); | 359 | evergreen_irq_set(rdev); |
@@ -893,7 +894,7 @@ int evergreen_pcie_gart_enable(struct radeon_device *rdev) | |||
893 | u32 tmp; | 894 | u32 tmp; |
894 | int r; | 895 | int r; |
895 | 896 | ||
896 | if (rdev->gart.table.vram.robj == NULL) { | 897 | if (rdev->gart.robj == NULL) { |
897 | dev_err(rdev->dev, "No VRAM object for PCIE GART.\n"); | 898 | dev_err(rdev->dev, "No VRAM object for PCIE GART.\n"); |
898 | return -EINVAL; | 899 | return -EINVAL; |
899 | } | 900 | } |
@@ -945,7 +946,6 @@ int evergreen_pcie_gart_enable(struct radeon_device *rdev) | |||
945 | void evergreen_pcie_gart_disable(struct radeon_device *rdev) | 946 | void evergreen_pcie_gart_disable(struct radeon_device *rdev) |
946 | { | 947 | { |
947 | u32 tmp; | 948 | u32 tmp; |
948 | int r; | ||
949 | 949 | ||
950 | /* Disable all tables */ | 950 | /* Disable all tables */ |
951 | WREG32(VM_CONTEXT0_CNTL, 0); | 951 | WREG32(VM_CONTEXT0_CNTL, 0); |
@@ -965,14 +965,7 @@ void evergreen_pcie_gart_disable(struct radeon_device *rdev) | |||
965 | WREG32(MC_VM_MB_L1_TLB1_CNTL, tmp); | 965 | WREG32(MC_VM_MB_L1_TLB1_CNTL, tmp); |
966 | WREG32(MC_VM_MB_L1_TLB2_CNTL, tmp); | 966 | WREG32(MC_VM_MB_L1_TLB2_CNTL, tmp); |
967 | WREG32(MC_VM_MB_L1_TLB3_CNTL, tmp); | 967 | WREG32(MC_VM_MB_L1_TLB3_CNTL, tmp); |
968 | if (rdev->gart.table.vram.robj) { | 968 | radeon_gart_table_vram_unpin(rdev); |
969 | r = radeon_bo_reserve(rdev->gart.table.vram.robj, false); | ||
970 | if (likely(r == 0)) { | ||
971 | radeon_bo_kunmap(rdev->gart.table.vram.robj); | ||
972 | radeon_bo_unpin(rdev->gart.table.vram.robj); | ||
973 | radeon_bo_unreserve(rdev->gart.table.vram.robj); | ||
974 | } | ||
975 | } | ||
976 | } | 969 | } |
977 | 970 | ||
978 | void evergreen_pcie_gart_fini(struct radeon_device *rdev) | 971 | void evergreen_pcie_gart_fini(struct radeon_device *rdev) |
@@ -3031,6 +3024,10 @@ static int evergreen_startup(struct radeon_device *rdev) | |||
3031 | } | 3024 | } |
3032 | } | 3025 | } |
3033 | 3026 | ||
3027 | r = r600_vram_scratch_init(rdev); | ||
3028 | if (r) | ||
3029 | return r; | ||
3030 | |||
3034 | evergreen_mc_program(rdev); | 3031 | evergreen_mc_program(rdev); |
3035 | if (rdev->flags & RADEON_IS_AGP) { | 3032 | if (rdev->flags & RADEON_IS_AGP) { |
3036 | evergreen_agp_enable(rdev); | 3033 | evergreen_agp_enable(rdev); |
@@ -3235,6 +3232,7 @@ void evergreen_fini(struct radeon_device *rdev) | |||
3235 | radeon_ib_pool_fini(rdev); | 3232 | radeon_ib_pool_fini(rdev); |
3236 | radeon_irq_kms_fini(rdev); | 3233 | radeon_irq_kms_fini(rdev); |
3237 | evergreen_pcie_gart_fini(rdev); | 3234 | evergreen_pcie_gart_fini(rdev); |
3235 | r600_vram_scratch_fini(rdev); | ||
3238 | radeon_gem_fini(rdev); | 3236 | radeon_gem_fini(rdev); |
3239 | radeon_fence_driver_fini(rdev); | 3237 | radeon_fence_driver_fini(rdev); |
3240 | radeon_agp_fini(rdev); | 3238 | radeon_agp_fini(rdev); |
diff --git a/drivers/gpu/drm/radeon/evergreen_blit_kms.c b/drivers/gpu/drm/radeon/evergreen_blit_kms.c index dcf11bbc06d9..914e5af84163 100644 --- a/drivers/gpu/drm/radeon/evergreen_blit_kms.c +++ b/drivers/gpu/drm/radeon/evergreen_blit_kms.c | |||
@@ -94,6 +94,15 @@ cp_set_surface_sync(struct radeon_device *rdev, | |||
94 | else | 94 | else |
95 | cp_coher_size = ((size + 255) >> 8); | 95 | cp_coher_size = ((size + 255) >> 8); |
96 | 96 | ||
97 | if (rdev->family >= CHIP_CAYMAN) { | ||
98 | /* CP_COHER_CNTL2 has to be set manually when submitting a surface_sync | ||
99 | * to the RB directly. For IBs, the CP programs this as part of the | ||
100 | * surface_sync packet. | ||
101 | */ | ||
102 | radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONFIG_REG, 1)); | ||
103 | radeon_ring_write(rdev, (0x85e8 - PACKET3_SET_CONFIG_REG_START) >> 2); | ||
104 | radeon_ring_write(rdev, 0); /* CP_COHER_CNTL2 */ | ||
105 | } | ||
97 | radeon_ring_write(rdev, PACKET3(PACKET3_SURFACE_SYNC, 3)); | 106 | radeon_ring_write(rdev, PACKET3(PACKET3_SURFACE_SYNC, 3)); |
98 | radeon_ring_write(rdev, sync_type); | 107 | radeon_ring_write(rdev, sync_type); |
99 | radeon_ring_write(rdev, cp_coher_size); | 108 | radeon_ring_write(rdev, cp_coher_size); |
@@ -174,7 +183,7 @@ set_vtx_resource(struct radeon_device *rdev, u64 gpu_addr) | |||
174 | static void | 183 | static void |
175 | set_tex_resource(struct radeon_device *rdev, | 184 | set_tex_resource(struct radeon_device *rdev, |
176 | int format, int w, int h, int pitch, | 185 | int format, int w, int h, int pitch, |
177 | u64 gpu_addr) | 186 | u64 gpu_addr, u32 size) |
178 | { | 187 | { |
179 | u32 sq_tex_resource_word0, sq_tex_resource_word1; | 188 | u32 sq_tex_resource_word0, sq_tex_resource_word1; |
180 | u32 sq_tex_resource_word4, sq_tex_resource_word7; | 189 | u32 sq_tex_resource_word4, sq_tex_resource_word7; |
@@ -196,6 +205,9 @@ set_tex_resource(struct radeon_device *rdev, | |||
196 | sq_tex_resource_word7 = format | | 205 | sq_tex_resource_word7 = format | |
197 | S__SQ_CONSTANT_TYPE(SQ_TEX_VTX_VALID_TEXTURE); | 206 | S__SQ_CONSTANT_TYPE(SQ_TEX_VTX_VALID_TEXTURE); |
198 | 207 | ||
208 | cp_set_surface_sync(rdev, | ||
209 | PACKET3_TC_ACTION_ENA, size, gpu_addr); | ||
210 | |||
199 | radeon_ring_write(rdev, PACKET3(PACKET3_SET_RESOURCE, 8)); | 211 | radeon_ring_write(rdev, PACKET3(PACKET3_SET_RESOURCE, 8)); |
200 | radeon_ring_write(rdev, 0); | 212 | radeon_ring_write(rdev, 0); |
201 | radeon_ring_write(rdev, sq_tex_resource_word0); | 213 | radeon_ring_write(rdev, sq_tex_resource_word0); |
@@ -613,11 +625,13 @@ int evergreen_blit_init(struct radeon_device *rdev) | |||
613 | rdev->r600_blit.primitives.set_default_state = set_default_state; | 625 | rdev->r600_blit.primitives.set_default_state = set_default_state; |
614 | 626 | ||
615 | rdev->r600_blit.ring_size_common = 55; /* shaders + def state */ | 627 | rdev->r600_blit.ring_size_common = 55; /* shaders + def state */ |
616 | rdev->r600_blit.ring_size_common += 10; /* fence emit for VB IB */ | 628 | rdev->r600_blit.ring_size_common += 16; /* fence emit for VB IB */ |
617 | rdev->r600_blit.ring_size_common += 5; /* done copy */ | 629 | rdev->r600_blit.ring_size_common += 5; /* done copy */ |
618 | rdev->r600_blit.ring_size_common += 10; /* fence emit for done copy */ | 630 | rdev->r600_blit.ring_size_common += 16; /* fence emit for done copy */ |
619 | 631 | ||
620 | rdev->r600_blit.ring_size_per_loop = 74; | 632 | rdev->r600_blit.ring_size_per_loop = 74; |
633 | if (rdev->family >= CHIP_CAYMAN) | ||
634 | rdev->r600_blit.ring_size_per_loop += 9; /* additional DWs for surface sync */ | ||
621 | 635 | ||
622 | rdev->r600_blit.max_dim = 16384; | 636 | rdev->r600_blit.max_dim = 16384; |
623 | 637 | ||
diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c index fdb93f884575..0e5799857465 100644 --- a/drivers/gpu/drm/radeon/ni.c +++ b/drivers/gpu/drm/radeon/ni.c | |||
@@ -262,8 +262,11 @@ int ni_mc_load_microcode(struct radeon_device *rdev) | |||
262 | WREG32(MC_SEQ_SUP_CNTL, 0x00000001); | 262 | WREG32(MC_SEQ_SUP_CNTL, 0x00000001); |
263 | 263 | ||
264 | /* wait for training to complete */ | 264 | /* wait for training to complete */ |
265 | while (!(RREG32(MC_IO_PAD_CNTL_D0) & MEM_FALL_OUT_CMD)) | 265 | for (i = 0; i < rdev->usec_timeout; i++) { |
266 | udelay(10); | 266 | if (RREG32(MC_IO_PAD_CNTL_D0) & MEM_FALL_OUT_CMD) |
267 | break; | ||
268 | udelay(1); | ||
269 | } | ||
267 | 270 | ||
268 | if (running) | 271 | if (running) |
269 | WREG32(MC_SHARED_BLACKOUT_CNTL, blackout); | 272 | WREG32(MC_SHARED_BLACKOUT_CNTL, blackout); |
@@ -933,7 +936,7 @@ int cayman_pcie_gart_enable(struct radeon_device *rdev) | |||
933 | { | 936 | { |
934 | int r; | 937 | int r; |
935 | 938 | ||
936 | if (rdev->gart.table.vram.robj == NULL) { | 939 | if (rdev->gart.robj == NULL) { |
937 | dev_err(rdev->dev, "No VRAM object for PCIE GART.\n"); | 940 | dev_err(rdev->dev, "No VRAM object for PCIE GART.\n"); |
938 | return -EINVAL; | 941 | return -EINVAL; |
939 | } | 942 | } |
@@ -978,8 +981,6 @@ int cayman_pcie_gart_enable(struct radeon_device *rdev) | |||
978 | 981 | ||
979 | void cayman_pcie_gart_disable(struct radeon_device *rdev) | 982 | void cayman_pcie_gart_disable(struct radeon_device *rdev) |
980 | { | 983 | { |
981 | int r; | ||
982 | |||
983 | /* Disable all tables */ | 984 | /* Disable all tables */ |
984 | WREG32(VM_CONTEXT0_CNTL, 0); | 985 | WREG32(VM_CONTEXT0_CNTL, 0); |
985 | WREG32(VM_CONTEXT1_CNTL, 0); | 986 | WREG32(VM_CONTEXT1_CNTL, 0); |
@@ -995,14 +996,7 @@ void cayman_pcie_gart_disable(struct radeon_device *rdev) | |||
995 | WREG32(VM_L2_CNTL2, 0); | 996 | WREG32(VM_L2_CNTL2, 0); |
996 | WREG32(VM_L2_CNTL3, L2_CACHE_BIGK_ASSOCIATIVITY | | 997 | WREG32(VM_L2_CNTL3, L2_CACHE_BIGK_ASSOCIATIVITY | |
997 | L2_CACHE_BIGK_FRAGMENT_SIZE(6)); | 998 | L2_CACHE_BIGK_FRAGMENT_SIZE(6)); |
998 | if (rdev->gart.table.vram.robj) { | 999 | radeon_gart_table_vram_unpin(rdev); |
999 | r = radeon_bo_reserve(rdev->gart.table.vram.robj, false); | ||
1000 | if (likely(r == 0)) { | ||
1001 | radeon_bo_kunmap(rdev->gart.table.vram.robj); | ||
1002 | radeon_bo_unpin(rdev->gart.table.vram.robj); | ||
1003 | radeon_bo_unreserve(rdev->gart.table.vram.robj); | ||
1004 | } | ||
1005 | } | ||
1006 | } | 1000 | } |
1007 | 1001 | ||
1008 | void cayman_pcie_gart_fini(struct radeon_device *rdev) | 1002 | void cayman_pcie_gart_fini(struct radeon_device *rdev) |
@@ -1362,6 +1356,10 @@ static int cayman_startup(struct radeon_device *rdev) | |||
1362 | return r; | 1356 | return r; |
1363 | } | 1357 | } |
1364 | 1358 | ||
1359 | r = r600_vram_scratch_init(rdev); | ||
1360 | if (r) | ||
1361 | return r; | ||
1362 | |||
1365 | evergreen_mc_program(rdev); | 1363 | evergreen_mc_program(rdev); |
1366 | r = cayman_pcie_gart_enable(rdev); | 1364 | r = cayman_pcie_gart_enable(rdev); |
1367 | if (r) | 1365 | if (r) |
@@ -1557,6 +1555,7 @@ void cayman_fini(struct radeon_device *rdev) | |||
1557 | radeon_ib_pool_fini(rdev); | 1555 | radeon_ib_pool_fini(rdev); |
1558 | radeon_irq_kms_fini(rdev); | 1556 | radeon_irq_kms_fini(rdev); |
1559 | cayman_pcie_gart_fini(rdev); | 1557 | cayman_pcie_gart_fini(rdev); |
1558 | r600_vram_scratch_fini(rdev); | ||
1560 | radeon_gem_fini(rdev); | 1559 | radeon_gem_fini(rdev); |
1561 | radeon_fence_driver_fini(rdev); | 1560 | radeon_fence_driver_fini(rdev); |
1562 | radeon_bo_fini(rdev); | 1561 | radeon_bo_fini(rdev); |
diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c index cbf49f4f408e..ad158ea49901 100644 --- a/drivers/gpu/drm/radeon/r100.c +++ b/drivers/gpu/drm/radeon/r100.c | |||
@@ -537,6 +537,7 @@ void r100_hpd_init(struct radeon_device *rdev) | |||
537 | default: | 537 | default: |
538 | break; | 538 | break; |
539 | } | 539 | } |
540 | radeon_hpd_set_polarity(rdev, radeon_connector->hpd.hpd); | ||
540 | } | 541 | } |
541 | if (rdev->irq.installed) | 542 | if (rdev->irq.installed) |
542 | r100_irq_set(rdev); | 543 | r100_irq_set(rdev); |
@@ -577,7 +578,7 @@ int r100_pci_gart_init(struct radeon_device *rdev) | |||
577 | { | 578 | { |
578 | int r; | 579 | int r; |
579 | 580 | ||
580 | if (rdev->gart.table.ram.ptr) { | 581 | if (rdev->gart.ptr) { |
581 | WARN(1, "R100 PCI GART already initialized\n"); | 582 | WARN(1, "R100 PCI GART already initialized\n"); |
582 | return 0; | 583 | return 0; |
583 | } | 584 | } |
@@ -636,10 +637,12 @@ void r100_pci_gart_disable(struct radeon_device *rdev) | |||
636 | 637 | ||
637 | int r100_pci_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr) | 638 | int r100_pci_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr) |
638 | { | 639 | { |
640 | u32 *gtt = rdev->gart.ptr; | ||
641 | |||
639 | if (i < 0 || i > rdev->gart.num_gpu_pages) { | 642 | if (i < 0 || i > rdev->gart.num_gpu_pages) { |
640 | return -EINVAL; | 643 | return -EINVAL; |
641 | } | 644 | } |
642 | rdev->gart.table.ram.ptr[i] = cpu_to_le32(lower_32_bits(addr)); | 645 | gtt[i] = cpu_to_le32(lower_32_bits(addr)); |
643 | return 0; | 646 | return 0; |
644 | } | 647 | } |
645 | 648 | ||
diff --git a/drivers/gpu/drm/radeon/r300.c b/drivers/gpu/drm/radeon/r300.c index 33f2b68c680b..400b26df652a 100644 --- a/drivers/gpu/drm/radeon/r300.c +++ b/drivers/gpu/drm/radeon/r300.c | |||
@@ -74,7 +74,7 @@ void rv370_pcie_gart_tlb_flush(struct radeon_device *rdev) | |||
74 | 74 | ||
75 | int rv370_pcie_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr) | 75 | int rv370_pcie_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr) |
76 | { | 76 | { |
77 | void __iomem *ptr = (void *)rdev->gart.table.vram.ptr; | 77 | void __iomem *ptr = rdev->gart.ptr; |
78 | 78 | ||
79 | if (i < 0 || i > rdev->gart.num_gpu_pages) { | 79 | if (i < 0 || i > rdev->gart.num_gpu_pages) { |
80 | return -EINVAL; | 80 | return -EINVAL; |
@@ -93,7 +93,7 @@ int rv370_pcie_gart_init(struct radeon_device *rdev) | |||
93 | { | 93 | { |
94 | int r; | 94 | int r; |
95 | 95 | ||
96 | if (rdev->gart.table.vram.robj) { | 96 | if (rdev->gart.robj) { |
97 | WARN(1, "RV370 PCIE GART already initialized\n"); | 97 | WARN(1, "RV370 PCIE GART already initialized\n"); |
98 | return 0; | 98 | return 0; |
99 | } | 99 | } |
@@ -116,7 +116,7 @@ int rv370_pcie_gart_enable(struct radeon_device *rdev) | |||
116 | uint32_t tmp; | 116 | uint32_t tmp; |
117 | int r; | 117 | int r; |
118 | 118 | ||
119 | if (rdev->gart.table.vram.robj == NULL) { | 119 | if (rdev->gart.robj == NULL) { |
120 | dev_err(rdev->dev, "No VRAM object for PCIE GART.\n"); | 120 | dev_err(rdev->dev, "No VRAM object for PCIE GART.\n"); |
121 | return -EINVAL; | 121 | return -EINVAL; |
122 | } | 122 | } |
@@ -154,7 +154,6 @@ int rv370_pcie_gart_enable(struct radeon_device *rdev) | |||
154 | void rv370_pcie_gart_disable(struct radeon_device *rdev) | 154 | void rv370_pcie_gart_disable(struct radeon_device *rdev) |
155 | { | 155 | { |
156 | u32 tmp; | 156 | u32 tmp; |
157 | int r; | ||
158 | 157 | ||
159 | WREG32_PCIE(RADEON_PCIE_TX_GART_START_LO, 0); | 158 | WREG32_PCIE(RADEON_PCIE_TX_GART_START_LO, 0); |
160 | WREG32_PCIE(RADEON_PCIE_TX_GART_END_LO, 0); | 159 | WREG32_PCIE(RADEON_PCIE_TX_GART_END_LO, 0); |
@@ -163,14 +162,7 @@ void rv370_pcie_gart_disable(struct radeon_device *rdev) | |||
163 | tmp = RREG32_PCIE(RADEON_PCIE_TX_GART_CNTL); | 162 | tmp = RREG32_PCIE(RADEON_PCIE_TX_GART_CNTL); |
164 | tmp |= RADEON_PCIE_TX_GART_UNMAPPED_ACCESS_DISCARD; | 163 | tmp |= RADEON_PCIE_TX_GART_UNMAPPED_ACCESS_DISCARD; |
165 | WREG32_PCIE(RADEON_PCIE_TX_GART_CNTL, tmp & ~RADEON_PCIE_TX_GART_EN); | 164 | WREG32_PCIE(RADEON_PCIE_TX_GART_CNTL, tmp & ~RADEON_PCIE_TX_GART_EN); |
166 | if (rdev->gart.table.vram.robj) { | 165 | radeon_gart_table_vram_unpin(rdev); |
167 | r = radeon_bo_reserve(rdev->gart.table.vram.robj, false); | ||
168 | if (likely(r == 0)) { | ||
169 | radeon_bo_kunmap(rdev->gart.table.vram.robj); | ||
170 | radeon_bo_unpin(rdev->gart.table.vram.robj); | ||
171 | radeon_bo_unreserve(rdev->gart.table.vram.robj); | ||
172 | } | ||
173 | } | ||
174 | } | 166 | } |
175 | 167 | ||
176 | void rv370_pcie_gart_fini(struct radeon_device *rdev) | 168 | void rv370_pcie_gart_fini(struct radeon_device *rdev) |
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index 4e777c1e4b7b..19afc43ad173 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c | |||
@@ -763,13 +763,14 @@ void r600_hpd_init(struct radeon_device *rdev) | |||
763 | struct drm_device *dev = rdev->ddev; | 763 | struct drm_device *dev = rdev->ddev; |
764 | struct drm_connector *connector; | 764 | struct drm_connector *connector; |
765 | 765 | ||
766 | if (ASIC_IS_DCE3(rdev)) { | 766 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { |
767 | u32 tmp = DC_HPDx_CONNECTION_TIMER(0x9c4) | DC_HPDx_RX_INT_TIMER(0xfa); | 767 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); |
768 | if (ASIC_IS_DCE32(rdev)) | 768 | |
769 | tmp |= DC_HPDx_EN; | 769 | if (ASIC_IS_DCE3(rdev)) { |
770 | u32 tmp = DC_HPDx_CONNECTION_TIMER(0x9c4) | DC_HPDx_RX_INT_TIMER(0xfa); | ||
771 | if (ASIC_IS_DCE32(rdev)) | ||
772 | tmp |= DC_HPDx_EN; | ||
770 | 773 | ||
771 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { | ||
772 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | ||
773 | switch (radeon_connector->hpd.hpd) { | 774 | switch (radeon_connector->hpd.hpd) { |
774 | case RADEON_HPD_1: | 775 | case RADEON_HPD_1: |
775 | WREG32(DC_HPD1_CONTROL, tmp); | 776 | WREG32(DC_HPD1_CONTROL, tmp); |
@@ -799,10 +800,7 @@ void r600_hpd_init(struct radeon_device *rdev) | |||
799 | default: | 800 | default: |
800 | break; | 801 | break; |
801 | } | 802 | } |
802 | } | 803 | } else { |
803 | } else { | ||
804 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { | ||
805 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | ||
806 | switch (radeon_connector->hpd.hpd) { | 804 | switch (radeon_connector->hpd.hpd) { |
807 | case RADEON_HPD_1: | 805 | case RADEON_HPD_1: |
808 | WREG32(DC_HOT_PLUG_DETECT1_CONTROL, DC_HOT_PLUG_DETECTx_EN); | 806 | WREG32(DC_HOT_PLUG_DETECT1_CONTROL, DC_HOT_PLUG_DETECTx_EN); |
@@ -820,6 +818,7 @@ void r600_hpd_init(struct radeon_device *rdev) | |||
820 | break; | 818 | break; |
821 | } | 819 | } |
822 | } | 820 | } |
821 | radeon_hpd_set_polarity(rdev, radeon_connector->hpd.hpd); | ||
823 | } | 822 | } |
824 | if (rdev->irq.installed) | 823 | if (rdev->irq.installed) |
825 | r600_irq_set(rdev); | 824 | r600_irq_set(rdev); |
@@ -897,7 +896,7 @@ void r600_pcie_gart_tlb_flush(struct radeon_device *rdev) | |||
897 | /* flush hdp cache so updates hit vram */ | 896 | /* flush hdp cache so updates hit vram */ |
898 | if ((rdev->family >= CHIP_RV770) && (rdev->family <= CHIP_RV740) && | 897 | if ((rdev->family >= CHIP_RV770) && (rdev->family <= CHIP_RV740) && |
899 | !(rdev->flags & RADEON_IS_AGP)) { | 898 | !(rdev->flags & RADEON_IS_AGP)) { |
900 | void __iomem *ptr = (void *)rdev->gart.table.vram.ptr; | 899 | void __iomem *ptr = (void *)rdev->gart.ptr; |
901 | u32 tmp; | 900 | u32 tmp; |
902 | 901 | ||
903 | /* r7xx hw bug. write to HDP_DEBUG1 followed by fb read | 902 | /* r7xx hw bug. write to HDP_DEBUG1 followed by fb read |
@@ -932,7 +931,7 @@ int r600_pcie_gart_init(struct radeon_device *rdev) | |||
932 | { | 931 | { |
933 | int r; | 932 | int r; |
934 | 933 | ||
935 | if (rdev->gart.table.vram.robj) { | 934 | if (rdev->gart.robj) { |
936 | WARN(1, "R600 PCIE GART already initialized\n"); | 935 | WARN(1, "R600 PCIE GART already initialized\n"); |
937 | return 0; | 936 | return 0; |
938 | } | 937 | } |
@@ -949,7 +948,7 @@ int r600_pcie_gart_enable(struct radeon_device *rdev) | |||
949 | u32 tmp; | 948 | u32 tmp; |
950 | int r, i; | 949 | int r, i; |
951 | 950 | ||
952 | if (rdev->gart.table.vram.robj == NULL) { | 951 | if (rdev->gart.robj == NULL) { |
953 | dev_err(rdev->dev, "No VRAM object for PCIE GART.\n"); | 952 | dev_err(rdev->dev, "No VRAM object for PCIE GART.\n"); |
954 | return -EINVAL; | 953 | return -EINVAL; |
955 | } | 954 | } |
@@ -1004,7 +1003,7 @@ int r600_pcie_gart_enable(struct radeon_device *rdev) | |||
1004 | void r600_pcie_gart_disable(struct radeon_device *rdev) | 1003 | void r600_pcie_gart_disable(struct radeon_device *rdev) |
1005 | { | 1004 | { |
1006 | u32 tmp; | 1005 | u32 tmp; |
1007 | int i, r; | 1006 | int i; |
1008 | 1007 | ||
1009 | /* Disable all tables */ | 1008 | /* Disable all tables */ |
1010 | for (i = 0; i < 7; i++) | 1009 | for (i = 0; i < 7; i++) |
@@ -1031,14 +1030,7 @@ void r600_pcie_gart_disable(struct radeon_device *rdev) | |||
1031 | WREG32(MC_VM_L1_TLB_MCB_WR_SYS_CNTL, tmp); | 1030 | WREG32(MC_VM_L1_TLB_MCB_WR_SYS_CNTL, tmp); |
1032 | WREG32(MC_VM_L1_TLB_MCB_RD_HDP_CNTL, tmp); | 1031 | WREG32(MC_VM_L1_TLB_MCB_RD_HDP_CNTL, tmp); |
1033 | WREG32(MC_VM_L1_TLB_MCB_WR_HDP_CNTL, tmp); | 1032 | WREG32(MC_VM_L1_TLB_MCB_WR_HDP_CNTL, tmp); |
1034 | if (rdev->gart.table.vram.robj) { | 1033 | radeon_gart_table_vram_unpin(rdev); |
1035 | r = radeon_bo_reserve(rdev->gart.table.vram.robj, false); | ||
1036 | if (likely(r == 0)) { | ||
1037 | radeon_bo_kunmap(rdev->gart.table.vram.robj); | ||
1038 | radeon_bo_unpin(rdev->gart.table.vram.robj); | ||
1039 | radeon_bo_unreserve(rdev->gart.table.vram.robj); | ||
1040 | } | ||
1041 | } | ||
1042 | } | 1034 | } |
1043 | 1035 | ||
1044 | void r600_pcie_gart_fini(struct radeon_device *rdev) | 1036 | void r600_pcie_gart_fini(struct radeon_device *rdev) |
@@ -1138,7 +1130,7 @@ static void r600_mc_program(struct radeon_device *rdev) | |||
1138 | WREG32(MC_VM_SYSTEM_APERTURE_LOW_ADDR, rdev->mc.vram_start >> 12); | 1130 | WREG32(MC_VM_SYSTEM_APERTURE_LOW_ADDR, rdev->mc.vram_start >> 12); |
1139 | WREG32(MC_VM_SYSTEM_APERTURE_HIGH_ADDR, rdev->mc.vram_end >> 12); | 1131 | WREG32(MC_VM_SYSTEM_APERTURE_HIGH_ADDR, rdev->mc.vram_end >> 12); |
1140 | } | 1132 | } |
1141 | WREG32(MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR, 0); | 1133 | WREG32(MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR, rdev->vram_scratch.gpu_addr >> 12); |
1142 | tmp = ((rdev->mc.vram_end >> 24) & 0xFFFF) << 16; | 1134 | tmp = ((rdev->mc.vram_end >> 24) & 0xFFFF) << 16; |
1143 | tmp |= ((rdev->mc.vram_start >> 24) & 0xFFFF); | 1135 | tmp |= ((rdev->mc.vram_start >> 24) & 0xFFFF); |
1144 | WREG32(MC_VM_FB_LOCATION, tmp); | 1136 | WREG32(MC_VM_FB_LOCATION, tmp); |
@@ -1277,6 +1269,53 @@ int r600_mc_init(struct radeon_device *rdev) | |||
1277 | return 0; | 1269 | return 0; |
1278 | } | 1270 | } |
1279 | 1271 | ||
1272 | int r600_vram_scratch_init(struct radeon_device *rdev) | ||
1273 | { | ||
1274 | int r; | ||
1275 | |||
1276 | if (rdev->vram_scratch.robj == NULL) { | ||
1277 | r = radeon_bo_create(rdev, RADEON_GPU_PAGE_SIZE, | ||
1278 | PAGE_SIZE, true, RADEON_GEM_DOMAIN_VRAM, | ||
1279 | &rdev->vram_scratch.robj); | ||
1280 | if (r) { | ||
1281 | return r; | ||
1282 | } | ||
1283 | } | ||
1284 | |||
1285 | r = radeon_bo_reserve(rdev->vram_scratch.robj, false); | ||
1286 | if (unlikely(r != 0)) | ||
1287 | return r; | ||
1288 | r = radeon_bo_pin(rdev->vram_scratch.robj, | ||
1289 | RADEON_GEM_DOMAIN_VRAM, &rdev->vram_scratch.gpu_addr); | ||
1290 | if (r) { | ||
1291 | radeon_bo_unreserve(rdev->vram_scratch.robj); | ||
1292 | return r; | ||
1293 | } | ||
1294 | r = radeon_bo_kmap(rdev->vram_scratch.robj, | ||
1295 | (void **)&rdev->vram_scratch.ptr); | ||
1296 | if (r) | ||
1297 | radeon_bo_unpin(rdev->vram_scratch.robj); | ||
1298 | radeon_bo_unreserve(rdev->vram_scratch.robj); | ||
1299 | |||
1300 | return r; | ||
1301 | } | ||
1302 | |||
1303 | void r600_vram_scratch_fini(struct radeon_device *rdev) | ||
1304 | { | ||
1305 | int r; | ||
1306 | |||
1307 | if (rdev->vram_scratch.robj == NULL) { | ||
1308 | return; | ||
1309 | } | ||
1310 | r = radeon_bo_reserve(rdev->vram_scratch.robj, false); | ||
1311 | if (likely(r == 0)) { | ||
1312 | radeon_bo_kunmap(rdev->vram_scratch.robj); | ||
1313 | radeon_bo_unpin(rdev->vram_scratch.robj); | ||
1314 | radeon_bo_unreserve(rdev->vram_scratch.robj); | ||
1315 | } | ||
1316 | radeon_bo_unref(&rdev->vram_scratch.robj); | ||
1317 | } | ||
1318 | |||
1280 | /* We doesn't check that the GPU really needs a reset we simply do the | 1319 | /* We doesn't check that the GPU really needs a reset we simply do the |
1281 | * reset, it's up to the caller to determine if the GPU needs one. We | 1320 | * reset, it's up to the caller to determine if the GPU needs one. We |
1282 | * might add an helper function to check that. | 1321 | * might add an helper function to check that. |
@@ -2332,6 +2371,14 @@ void r600_fence_ring_emit(struct radeon_device *rdev, | |||
2332 | if (rdev->wb.use_event) { | 2371 | if (rdev->wb.use_event) { |
2333 | u64 addr = rdev->wb.gpu_addr + R600_WB_EVENT_OFFSET + | 2372 | u64 addr = rdev->wb.gpu_addr + R600_WB_EVENT_OFFSET + |
2334 | (u64)(rdev->fence_drv.scratch_reg - rdev->scratch.reg_base); | 2373 | (u64)(rdev->fence_drv.scratch_reg - rdev->scratch.reg_base); |
2374 | /* flush read cache over gart */ | ||
2375 | radeon_ring_write(rdev, PACKET3(PACKET3_SURFACE_SYNC, 3)); | ||
2376 | radeon_ring_write(rdev, PACKET3_TC_ACTION_ENA | | ||
2377 | PACKET3_VC_ACTION_ENA | | ||
2378 | PACKET3_SH_ACTION_ENA); | ||
2379 | radeon_ring_write(rdev, 0xFFFFFFFF); | ||
2380 | radeon_ring_write(rdev, 0); | ||
2381 | radeon_ring_write(rdev, 10); /* poll interval */ | ||
2335 | /* EVENT_WRITE_EOP - flush caches, send int */ | 2382 | /* EVENT_WRITE_EOP - flush caches, send int */ |
2336 | radeon_ring_write(rdev, PACKET3(PACKET3_EVENT_WRITE_EOP, 4)); | 2383 | radeon_ring_write(rdev, PACKET3(PACKET3_EVENT_WRITE_EOP, 4)); |
2337 | radeon_ring_write(rdev, EVENT_TYPE(CACHE_FLUSH_AND_INV_EVENT_TS) | EVENT_INDEX(5)); | 2384 | radeon_ring_write(rdev, EVENT_TYPE(CACHE_FLUSH_AND_INV_EVENT_TS) | EVENT_INDEX(5)); |
@@ -2340,6 +2387,14 @@ void r600_fence_ring_emit(struct radeon_device *rdev, | |||
2340 | radeon_ring_write(rdev, fence->seq); | 2387 | radeon_ring_write(rdev, fence->seq); |
2341 | radeon_ring_write(rdev, 0); | 2388 | radeon_ring_write(rdev, 0); |
2342 | } else { | 2389 | } else { |
2390 | /* flush read cache over gart */ | ||
2391 | radeon_ring_write(rdev, PACKET3(PACKET3_SURFACE_SYNC, 3)); | ||
2392 | radeon_ring_write(rdev, PACKET3_TC_ACTION_ENA | | ||
2393 | PACKET3_VC_ACTION_ENA | | ||
2394 | PACKET3_SH_ACTION_ENA); | ||
2395 | radeon_ring_write(rdev, 0xFFFFFFFF); | ||
2396 | radeon_ring_write(rdev, 0); | ||
2397 | radeon_ring_write(rdev, 10); /* poll interval */ | ||
2343 | radeon_ring_write(rdev, PACKET3(PACKET3_EVENT_WRITE, 0)); | 2398 | radeon_ring_write(rdev, PACKET3(PACKET3_EVENT_WRITE, 0)); |
2344 | radeon_ring_write(rdev, EVENT_TYPE(CACHE_FLUSH_AND_INV_EVENT) | EVENT_INDEX(0)); | 2399 | radeon_ring_write(rdev, EVENT_TYPE(CACHE_FLUSH_AND_INV_EVENT) | EVENT_INDEX(0)); |
2345 | /* wait for 3D idle clean */ | 2400 | /* wait for 3D idle clean */ |
@@ -2421,6 +2476,10 @@ int r600_startup(struct radeon_device *rdev) | |||
2421 | } | 2476 | } |
2422 | } | 2477 | } |
2423 | 2478 | ||
2479 | r = r600_vram_scratch_init(rdev); | ||
2480 | if (r) | ||
2481 | return r; | ||
2482 | |||
2424 | r600_mc_program(rdev); | 2483 | r600_mc_program(rdev); |
2425 | if (rdev->flags & RADEON_IS_AGP) { | 2484 | if (rdev->flags & RADEON_IS_AGP) { |
2426 | r600_agp_enable(rdev); | 2485 | r600_agp_enable(rdev); |
@@ -2641,6 +2700,7 @@ void r600_fini(struct radeon_device *rdev) | |||
2641 | radeon_ib_pool_fini(rdev); | 2700 | radeon_ib_pool_fini(rdev); |
2642 | radeon_irq_kms_fini(rdev); | 2701 | radeon_irq_kms_fini(rdev); |
2643 | r600_pcie_gart_fini(rdev); | 2702 | r600_pcie_gart_fini(rdev); |
2703 | r600_vram_scratch_fini(rdev); | ||
2644 | radeon_agp_fini(rdev); | 2704 | radeon_agp_fini(rdev); |
2645 | radeon_gem_fini(rdev); | 2705 | radeon_gem_fini(rdev); |
2646 | radeon_fence_driver_fini(rdev); | 2706 | radeon_fence_driver_fini(rdev); |
diff --git a/drivers/gpu/drm/radeon/r600_blit_kms.c b/drivers/gpu/drm/radeon/r600_blit_kms.c index c4cf1308d4a1..e09d2818f949 100644 --- a/drivers/gpu/drm/radeon/r600_blit_kms.c +++ b/drivers/gpu/drm/radeon/r600_blit_kms.c | |||
@@ -201,7 +201,7 @@ set_vtx_resource(struct radeon_device *rdev, u64 gpu_addr) | |||
201 | static void | 201 | static void |
202 | set_tex_resource(struct radeon_device *rdev, | 202 | set_tex_resource(struct radeon_device *rdev, |
203 | int format, int w, int h, int pitch, | 203 | int format, int w, int h, int pitch, |
204 | u64 gpu_addr) | 204 | u64 gpu_addr, u32 size) |
205 | { | 205 | { |
206 | uint32_t sq_tex_resource_word0, sq_tex_resource_word1, sq_tex_resource_word4; | 206 | uint32_t sq_tex_resource_word0, sq_tex_resource_word1, sq_tex_resource_word4; |
207 | 207 | ||
@@ -222,6 +222,9 @@ set_tex_resource(struct radeon_device *rdev, | |||
222 | S_038010_DST_SEL_Z(SQ_SEL_Z) | | 222 | S_038010_DST_SEL_Z(SQ_SEL_Z) | |
223 | S_038010_DST_SEL_W(SQ_SEL_W); | 223 | S_038010_DST_SEL_W(SQ_SEL_W); |
224 | 224 | ||
225 | cp_set_surface_sync(rdev, | ||
226 | PACKET3_TC_ACTION_ENA, size, gpu_addr); | ||
227 | |||
225 | radeon_ring_write(rdev, PACKET3(PACKET3_SET_RESOURCE, 7)); | 228 | radeon_ring_write(rdev, PACKET3(PACKET3_SET_RESOURCE, 7)); |
226 | radeon_ring_write(rdev, 0); | 229 | radeon_ring_write(rdev, 0); |
227 | radeon_ring_write(rdev, sq_tex_resource_word0); | 230 | radeon_ring_write(rdev, sq_tex_resource_word0); |
@@ -500,9 +503,9 @@ int r600_blit_init(struct radeon_device *rdev) | |||
500 | rdev->r600_blit.primitives.set_default_state = set_default_state; | 503 | rdev->r600_blit.primitives.set_default_state = set_default_state; |
501 | 504 | ||
502 | rdev->r600_blit.ring_size_common = 40; /* shaders + def state */ | 505 | rdev->r600_blit.ring_size_common = 40; /* shaders + def state */ |
503 | rdev->r600_blit.ring_size_common += 10; /* fence emit for VB IB */ | 506 | rdev->r600_blit.ring_size_common += 16; /* fence emit for VB IB */ |
504 | rdev->r600_blit.ring_size_common += 5; /* done copy */ | 507 | rdev->r600_blit.ring_size_common += 5; /* done copy */ |
505 | rdev->r600_blit.ring_size_common += 10; /* fence emit for done copy */ | 508 | rdev->r600_blit.ring_size_common += 16; /* fence emit for done copy */ |
506 | 509 | ||
507 | rdev->r600_blit.ring_size_per_loop = 76; | 510 | rdev->r600_blit.ring_size_per_loop = 76; |
508 | /* set_render_target emits 2 extra dwords on rv6xx */ | 511 | /* set_render_target emits 2 extra dwords on rv6xx */ |
@@ -760,10 +763,7 @@ void r600_kms_blit_copy(struct radeon_device *rdev, | |||
760 | vb[11] = i2f(h); | 763 | vb[11] = i2f(h); |
761 | 764 | ||
762 | rdev->r600_blit.primitives.set_tex_resource(rdev, FMT_8_8_8_8, | 765 | rdev->r600_blit.primitives.set_tex_resource(rdev, FMT_8_8_8_8, |
763 | w, h, w, src_gpu_addr); | 766 | w, h, w, src_gpu_addr, size_in_bytes); |
764 | rdev->r600_blit.primitives.cp_set_surface_sync(rdev, | ||
765 | PACKET3_TC_ACTION_ENA, | ||
766 | size_in_bytes, src_gpu_addr); | ||
767 | rdev->r600_blit.primitives.set_render_target(rdev, COLOR_8_8_8_8, | 767 | rdev->r600_blit.primitives.set_render_target(rdev, COLOR_8_8_8_8, |
768 | w, h, dst_gpu_addr); | 768 | w, h, dst_gpu_addr); |
769 | rdev->r600_blit.primitives.set_scissors(rdev, 0, 0, w, h); | 769 | rdev->r600_blit.primitives.set_scissors(rdev, 0, 0, w, h); |
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index e3170c794c1d..b316b301152f 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h | |||
@@ -93,6 +93,7 @@ extern int radeon_audio; | |||
93 | extern int radeon_disp_priority; | 93 | extern int radeon_disp_priority; |
94 | extern int radeon_hw_i2c; | 94 | extern int radeon_hw_i2c; |
95 | extern int radeon_pcie_gen2; | 95 | extern int radeon_pcie_gen2; |
96 | extern int radeon_msi; | ||
96 | 97 | ||
97 | /* | 98 | /* |
98 | * Copy from radeon_drv.h so we don't have to include both and have conflicting | 99 | * Copy from radeon_drv.h so we don't have to include both and have conflicting |
@@ -306,30 +307,17 @@ int radeon_mode_dumb_destroy(struct drm_file *file_priv, | |||
306 | */ | 307 | */ |
307 | struct radeon_mc; | 308 | struct radeon_mc; |
308 | 309 | ||
309 | struct radeon_gart_table_ram { | ||
310 | volatile uint32_t *ptr; | ||
311 | }; | ||
312 | |||
313 | struct radeon_gart_table_vram { | ||
314 | struct radeon_bo *robj; | ||
315 | volatile uint32_t *ptr; | ||
316 | }; | ||
317 | |||
318 | union radeon_gart_table { | ||
319 | struct radeon_gart_table_ram ram; | ||
320 | struct radeon_gart_table_vram vram; | ||
321 | }; | ||
322 | |||
323 | #define RADEON_GPU_PAGE_SIZE 4096 | 310 | #define RADEON_GPU_PAGE_SIZE 4096 |
324 | #define RADEON_GPU_PAGE_MASK (RADEON_GPU_PAGE_SIZE - 1) | 311 | #define RADEON_GPU_PAGE_MASK (RADEON_GPU_PAGE_SIZE - 1) |
325 | #define RADEON_GPU_PAGE_SHIFT 12 | 312 | #define RADEON_GPU_PAGE_SHIFT 12 |
326 | 313 | ||
327 | struct radeon_gart { | 314 | struct radeon_gart { |
328 | dma_addr_t table_addr; | 315 | dma_addr_t table_addr; |
316 | struct radeon_bo *robj; | ||
317 | void *ptr; | ||
329 | unsigned num_gpu_pages; | 318 | unsigned num_gpu_pages; |
330 | unsigned num_cpu_pages; | 319 | unsigned num_cpu_pages; |
331 | unsigned table_size; | 320 | unsigned table_size; |
332 | union radeon_gart_table table; | ||
333 | struct page **pages; | 321 | struct page **pages; |
334 | dma_addr_t *pages_addr; | 322 | dma_addr_t *pages_addr; |
335 | bool *ttm_alloced; | 323 | bool *ttm_alloced; |
@@ -340,6 +328,8 @@ int radeon_gart_table_ram_alloc(struct radeon_device *rdev); | |||
340 | void radeon_gart_table_ram_free(struct radeon_device *rdev); | 328 | void radeon_gart_table_ram_free(struct radeon_device *rdev); |
341 | int radeon_gart_table_vram_alloc(struct radeon_device *rdev); | 329 | int radeon_gart_table_vram_alloc(struct radeon_device *rdev); |
342 | void radeon_gart_table_vram_free(struct radeon_device *rdev); | 330 | void radeon_gart_table_vram_free(struct radeon_device *rdev); |
331 | int radeon_gart_table_vram_pin(struct radeon_device *rdev); | ||
332 | void radeon_gart_table_vram_unpin(struct radeon_device *rdev); | ||
343 | int radeon_gart_init(struct radeon_device *rdev); | 333 | int radeon_gart_init(struct radeon_device *rdev); |
344 | void radeon_gart_fini(struct radeon_device *rdev); | 334 | void radeon_gart_fini(struct radeon_device *rdev); |
345 | void radeon_gart_unbind(struct radeon_device *rdev, unsigned offset, | 335 | void radeon_gart_unbind(struct radeon_device *rdev, unsigned offset, |
@@ -347,6 +337,7 @@ void radeon_gart_unbind(struct radeon_device *rdev, unsigned offset, | |||
347 | int radeon_gart_bind(struct radeon_device *rdev, unsigned offset, | 337 | int radeon_gart_bind(struct radeon_device *rdev, unsigned offset, |
348 | int pages, struct page **pagelist, | 338 | int pages, struct page **pagelist, |
349 | dma_addr_t *dma_addr); | 339 | dma_addr_t *dma_addr); |
340 | void radeon_gart_restore(struct radeon_device *rdev); | ||
350 | 341 | ||
351 | 342 | ||
352 | /* | 343 | /* |
@@ -437,25 +428,26 @@ union radeon_irq_stat_regs { | |||
437 | struct evergreen_irq_stat_regs evergreen; | 428 | struct evergreen_irq_stat_regs evergreen; |
438 | }; | 429 | }; |
439 | 430 | ||
431 | #define RADEON_MAX_HPD_PINS 6 | ||
432 | #define RADEON_MAX_CRTCS 6 | ||
433 | #define RADEON_MAX_HDMI_BLOCKS 2 | ||
434 | |||
440 | struct radeon_irq { | 435 | struct radeon_irq { |
441 | bool installed; | 436 | bool installed; |
442 | bool sw_int; | 437 | bool sw_int; |
443 | /* FIXME: use a define max crtc rather than hardcode it */ | 438 | bool crtc_vblank_int[RADEON_MAX_CRTCS]; |
444 | bool crtc_vblank_int[6]; | 439 | bool pflip[RADEON_MAX_CRTCS]; |
445 | bool pflip[6]; | ||
446 | wait_queue_head_t vblank_queue; | 440 | wait_queue_head_t vblank_queue; |
447 | /* FIXME: use defines for max hpd/dacs */ | 441 | bool hpd[RADEON_MAX_HPD_PINS]; |
448 | bool hpd[6]; | ||
449 | bool gui_idle; | 442 | bool gui_idle; |
450 | bool gui_idle_acked; | 443 | bool gui_idle_acked; |
451 | wait_queue_head_t idle_queue; | 444 | wait_queue_head_t idle_queue; |
452 | /* FIXME: use defines for max HDMI blocks */ | 445 | bool hdmi[RADEON_MAX_HDMI_BLOCKS]; |
453 | bool hdmi[2]; | ||
454 | spinlock_t sw_lock; | 446 | spinlock_t sw_lock; |
455 | int sw_refcount; | 447 | int sw_refcount; |
456 | union radeon_irq_stat_regs stat_regs; | 448 | union radeon_irq_stat_regs stat_regs; |
457 | spinlock_t pflip_lock[6]; | 449 | spinlock_t pflip_lock[RADEON_MAX_CRTCS]; |
458 | int pflip_refcount[6]; | 450 | int pflip_refcount[RADEON_MAX_CRTCS]; |
459 | }; | 451 | }; |
460 | 452 | ||
461 | int radeon_irq_kms_init(struct radeon_device *rdev); | 453 | int radeon_irq_kms_init(struct radeon_device *rdev); |
@@ -533,7 +525,7 @@ struct r600_blit_cp_primitives { | |||
533 | void (*set_vtx_resource)(struct radeon_device *rdev, u64 gpu_addr); | 525 | void (*set_vtx_resource)(struct radeon_device *rdev, u64 gpu_addr); |
534 | void (*set_tex_resource)(struct radeon_device *rdev, | 526 | void (*set_tex_resource)(struct radeon_device *rdev, |
535 | int format, int w, int h, int pitch, | 527 | int format, int w, int h, int pitch, |
536 | u64 gpu_addr); | 528 | u64 gpu_addr, u32 size); |
537 | void (*set_scissors)(struct radeon_device *rdev, int x1, int y1, | 529 | void (*set_scissors)(struct radeon_device *rdev, int x1, int y1, |
538 | int x2, int y2); | 530 | int x2, int y2); |
539 | void (*draw_auto)(struct radeon_device *rdev); | 531 | void (*draw_auto)(struct radeon_device *rdev); |
@@ -1143,10 +1135,11 @@ int radeon_gem_set_tiling_ioctl(struct drm_device *dev, void *data, | |||
1143 | int radeon_gem_get_tiling_ioctl(struct drm_device *dev, void *data, | 1135 | int radeon_gem_get_tiling_ioctl(struct drm_device *dev, void *data, |
1144 | struct drm_file *filp); | 1136 | struct drm_file *filp); |
1145 | 1137 | ||
1146 | /* VRAM scratch page for HDP bug */ | 1138 | /* VRAM scratch page for HDP bug, default vram page */ |
1147 | struct r700_vram_scratch { | 1139 | struct r600_vram_scratch { |
1148 | struct radeon_bo *robj; | 1140 | struct radeon_bo *robj; |
1149 | volatile uint32_t *ptr; | 1141 | volatile uint32_t *ptr; |
1142 | u64 gpu_addr; | ||
1150 | }; | 1143 | }; |
1151 | 1144 | ||
1152 | /* | 1145 | /* |
@@ -1218,7 +1211,7 @@ struct radeon_device { | |||
1218 | const struct firmware *rlc_fw; /* r6/700 RLC firmware */ | 1211 | const struct firmware *rlc_fw; /* r6/700 RLC firmware */ |
1219 | const struct firmware *mc_fw; /* NI MC firmware */ | 1212 | const struct firmware *mc_fw; /* NI MC firmware */ |
1220 | struct r600_blit r600_blit; | 1213 | struct r600_blit r600_blit; |
1221 | struct r700_vram_scratch vram_scratch; | 1214 | struct r600_vram_scratch vram_scratch; |
1222 | int msi_enabled; /* msi enabled */ | 1215 | int msi_enabled; /* msi enabled */ |
1223 | struct r600_ih ih; /* r6/700 interrupt ring */ | 1216 | struct r600_ih ih; /* r6/700 interrupt ring */ |
1224 | struct work_struct hotplug_work; | 1217 | struct work_struct hotplug_work; |
@@ -1442,8 +1435,6 @@ void radeon_ring_write(struct radeon_device *rdev, uint32_t v); | |||
1442 | /* AGP */ | 1435 | /* AGP */ |
1443 | extern int radeon_gpu_reset(struct radeon_device *rdev); | 1436 | extern int radeon_gpu_reset(struct radeon_device *rdev); |
1444 | extern void radeon_agp_disable(struct radeon_device *rdev); | 1437 | extern void radeon_agp_disable(struct radeon_device *rdev); |
1445 | extern int radeon_gart_table_vram_pin(struct radeon_device *rdev); | ||
1446 | extern void radeon_gart_restore(struct radeon_device *rdev); | ||
1447 | extern int radeon_modeset_init(struct radeon_device *rdev); | 1438 | extern int radeon_modeset_init(struct radeon_device *rdev); |
1448 | extern void radeon_modeset_fini(struct radeon_device *rdev); | 1439 | extern void radeon_modeset_fini(struct radeon_device *rdev); |
1449 | extern bool radeon_card_posted(struct radeon_device *rdev); | 1440 | extern bool radeon_card_posted(struct radeon_device *rdev); |
@@ -1467,6 +1458,12 @@ extern int radeon_suspend_kms(struct drm_device *dev, pm_message_t state); | |||
1467 | extern void radeon_ttm_set_active_vram_size(struct radeon_device *rdev, u64 size); | 1458 | extern void radeon_ttm_set_active_vram_size(struct radeon_device *rdev, u64 size); |
1468 | 1459 | ||
1469 | /* | 1460 | /* |
1461 | * R600 vram scratch functions | ||
1462 | */ | ||
1463 | int r600_vram_scratch_init(struct radeon_device *rdev); | ||
1464 | void r600_vram_scratch_fini(struct radeon_device *rdev); | ||
1465 | |||
1466 | /* | ||
1470 | * r600 functions used by radeon_encoder.c | 1467 | * r600 functions used by radeon_encoder.c |
1471 | */ | 1468 | */ |
1472 | extern void r600_hdmi_enable(struct drm_encoder *encoder); | 1469 | extern void r600_hdmi_enable(struct drm_encoder *encoder); |
diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c index dec6cbe6a0a6..e7cb3ab09243 100644 --- a/drivers/gpu/drm/radeon/radeon_connectors.c +++ b/drivers/gpu/drm/radeon/radeon_connectors.c | |||
@@ -44,8 +44,6 @@ extern void | |||
44 | radeon_legacy_backlight_init(struct radeon_encoder *radeon_encoder, | 44 | radeon_legacy_backlight_init(struct radeon_encoder *radeon_encoder, |
45 | struct drm_connector *drm_connector); | 45 | struct drm_connector *drm_connector); |
46 | 46 | ||
47 | bool radeon_connector_encoder_is_dp_bridge(struct drm_connector *connector); | ||
48 | |||
49 | void radeon_connector_hotplug(struct drm_connector *connector) | 47 | void radeon_connector_hotplug(struct drm_connector *connector) |
50 | { | 48 | { |
51 | struct drm_device *dev = connector->dev; | 49 | struct drm_device *dev = connector->dev; |
@@ -432,55 +430,6 @@ int radeon_connector_set_property(struct drm_connector *connector, struct drm_pr | |||
432 | return 0; | 430 | return 0; |
433 | } | 431 | } |
434 | 432 | ||
435 | /* | ||
436 | * Some integrated ATI Radeon chipset implementations (e. g. | ||
437 | * Asus M2A-VM HDMI) may indicate the availability of a DDC, | ||
438 | * even when there's no monitor connected. For these connectors | ||
439 | * following DDC probe extension will be applied: check also for the | ||
440 | * availability of EDID with at least a correct EDID header. Only then, | ||
441 | * DDC is assumed to be available. This prevents drm_get_edid() and | ||
442 | * drm_edid_block_valid() from periodically dumping data and kernel | ||
443 | * errors into the logs and onto the terminal. | ||
444 | */ | ||
445 | static bool radeon_connector_needs_extended_probe(struct radeon_device *dev, | ||
446 | uint32_t supported_device, | ||
447 | int connector_type) | ||
448 | { | ||
449 | /* Asus M2A-VM HDMI board sends data to i2c bus even, | ||
450 | * if HDMI add-on card is not plugged in or HDMI is disabled in | ||
451 | * BIOS. Valid DDC can only be assumed, if also a valid EDID header | ||
452 | * can be retrieved via i2c bus during DDC probe */ | ||
453 | if ((dev->pdev->device == 0x791e) && | ||
454 | (dev->pdev->subsystem_vendor == 0x1043) && | ||
455 | (dev->pdev->subsystem_device == 0x826d)) { | ||
456 | if ((connector_type == DRM_MODE_CONNECTOR_HDMIA) && | ||
457 | (supported_device == ATOM_DEVICE_DFP2_SUPPORT)) | ||
458 | return true; | ||
459 | } | ||
460 | /* ECS A740GM-M with ATI RADEON 2100 sends data to i2c bus | ||
461 | * for a DVI connector that is not implemented */ | ||
462 | if ((dev->pdev->device == 0x796e) && | ||
463 | (dev->pdev->subsystem_vendor == 0x1019) && | ||
464 | (dev->pdev->subsystem_device == 0x2615)) { | ||
465 | if ((connector_type == DRM_MODE_CONNECTOR_DVID) && | ||
466 | (supported_device == ATOM_DEVICE_DFP2_SUPPORT)) | ||
467 | return true; | ||
468 | } | ||
469 | /* TOSHIBA Satellite L300D with ATI Mobility Radeon x1100 | ||
470 | * (RS690M) sends data to i2c bus for a HDMI connector that | ||
471 | * is not implemented */ | ||
472 | if ((dev->pdev->device == 0x791f) && | ||
473 | (dev->pdev->subsystem_vendor == 0x1179) && | ||
474 | (dev->pdev->subsystem_device == 0xff68)) { | ||
475 | if ((connector_type == DRM_MODE_CONNECTOR_HDMIA) && | ||
476 | (supported_device == ATOM_DEVICE_DFP2_SUPPORT)) | ||
477 | return true; | ||
478 | } | ||
479 | |||
480 | /* Default: no EDID header probe required for DDC probing */ | ||
481 | return false; | ||
482 | } | ||
483 | |||
484 | static void radeon_fixup_lvds_native_mode(struct drm_encoder *encoder, | 433 | static void radeon_fixup_lvds_native_mode(struct drm_encoder *encoder, |
485 | struct drm_connector *connector) | 434 | struct drm_connector *connector) |
486 | { | 435 | { |
@@ -721,8 +670,7 @@ radeon_vga_detect(struct drm_connector *connector, bool force) | |||
721 | ret = connector_status_disconnected; | 670 | ret = connector_status_disconnected; |
722 | 671 | ||
723 | if (radeon_connector->ddc_bus) | 672 | if (radeon_connector->ddc_bus) |
724 | dret = radeon_ddc_probe(radeon_connector, | 673 | dret = radeon_ddc_probe(radeon_connector); |
725 | radeon_connector->requires_extended_probe); | ||
726 | if (dret) { | 674 | if (dret) { |
727 | radeon_connector->detected_by_load = false; | 675 | radeon_connector->detected_by_load = false; |
728 | if (radeon_connector->edid) { | 676 | if (radeon_connector->edid) { |
@@ -764,7 +712,7 @@ radeon_vga_detect(struct drm_connector *connector, bool force) | |||
764 | if (radeon_connector->dac_load_detect && encoder) { | 712 | if (radeon_connector->dac_load_detect && encoder) { |
765 | encoder_funcs = encoder->helper_private; | 713 | encoder_funcs = encoder->helper_private; |
766 | ret = encoder_funcs->detect(encoder, connector); | 714 | ret = encoder_funcs->detect(encoder, connector); |
767 | if (ret == connector_status_connected) | 715 | if (ret != connector_status_disconnected) |
768 | radeon_connector->detected_by_load = true; | 716 | radeon_connector->detected_by_load = true; |
769 | } | 717 | } |
770 | } | 718 | } |
@@ -904,8 +852,7 @@ radeon_dvi_detect(struct drm_connector *connector, bool force) | |||
904 | bool dret = false; | 852 | bool dret = false; |
905 | 853 | ||
906 | if (radeon_connector->ddc_bus) | 854 | if (radeon_connector->ddc_bus) |
907 | dret = radeon_ddc_probe(radeon_connector, | 855 | dret = radeon_ddc_probe(radeon_connector); |
908 | radeon_connector->requires_extended_probe); | ||
909 | if (dret) { | 856 | if (dret) { |
910 | radeon_connector->detected_by_load = false; | 857 | radeon_connector->detected_by_load = false; |
911 | if (radeon_connector->edid) { | 858 | if (radeon_connector->edid) { |
@@ -1005,8 +952,9 @@ radeon_dvi_detect(struct drm_connector *connector, bool force) | |||
1005 | ret = encoder_funcs->detect(encoder, connector); | 952 | ret = encoder_funcs->detect(encoder, connector); |
1006 | if (ret == connector_status_connected) { | 953 | if (ret == connector_status_connected) { |
1007 | radeon_connector->use_digital = false; | 954 | radeon_connector->use_digital = false; |
1008 | radeon_connector->detected_by_load = true; | ||
1009 | } | 955 | } |
956 | if (ret != connector_status_disconnected) | ||
957 | radeon_connector->detected_by_load = true; | ||
1010 | } | 958 | } |
1011 | break; | 959 | break; |
1012 | } | 960 | } |
@@ -1203,7 +1151,8 @@ static int radeon_dp_get_modes(struct drm_connector *connector) | |||
1203 | } | 1151 | } |
1204 | } else { | 1152 | } else { |
1205 | /* need to setup ddc on the bridge */ | 1153 | /* need to setup ddc on the bridge */ |
1206 | if (radeon_connector_encoder_is_dp_bridge(connector)) { | 1154 | if (radeon_connector_encoder_get_dp_bridge_encoder_id(connector) != |
1155 | ENCODER_OBJECT_ID_NONE) { | ||
1207 | if (encoder) | 1156 | if (encoder) |
1208 | radeon_atom_ext_encoder_setup_ddc(encoder); | 1157 | radeon_atom_ext_encoder_setup_ddc(encoder); |
1209 | } | 1158 | } |
@@ -1213,13 +1162,12 @@ static int radeon_dp_get_modes(struct drm_connector *connector) | |||
1213 | return ret; | 1162 | return ret; |
1214 | } | 1163 | } |
1215 | 1164 | ||
1216 | bool radeon_connector_encoder_is_dp_bridge(struct drm_connector *connector) | 1165 | u16 radeon_connector_encoder_get_dp_bridge_encoder_id(struct drm_connector *connector) |
1217 | { | 1166 | { |
1218 | struct drm_mode_object *obj; | 1167 | struct drm_mode_object *obj; |
1219 | struct drm_encoder *encoder; | 1168 | struct drm_encoder *encoder; |
1220 | struct radeon_encoder *radeon_encoder; | 1169 | struct radeon_encoder *radeon_encoder; |
1221 | int i; | 1170 | int i; |
1222 | bool found = false; | ||
1223 | 1171 | ||
1224 | for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) { | 1172 | for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) { |
1225 | if (connector->encoder_ids[i] == 0) | 1173 | if (connector->encoder_ids[i] == 0) |
@@ -1235,14 +1183,13 @@ bool radeon_connector_encoder_is_dp_bridge(struct drm_connector *connector) | |||
1235 | switch (radeon_encoder->encoder_id) { | 1183 | switch (radeon_encoder->encoder_id) { |
1236 | case ENCODER_OBJECT_ID_TRAVIS: | 1184 | case ENCODER_OBJECT_ID_TRAVIS: |
1237 | case ENCODER_OBJECT_ID_NUTMEG: | 1185 | case ENCODER_OBJECT_ID_NUTMEG: |
1238 | found = true; | 1186 | return radeon_encoder->encoder_id; |
1239 | break; | ||
1240 | default: | 1187 | default: |
1241 | break; | 1188 | break; |
1242 | } | 1189 | } |
1243 | } | 1190 | } |
1244 | 1191 | ||
1245 | return found; | 1192 | return ENCODER_OBJECT_ID_NONE; |
1246 | } | 1193 | } |
1247 | 1194 | ||
1248 | bool radeon_connector_encoder_is_hbr2(struct drm_connector *connector) | 1195 | bool radeon_connector_encoder_is_hbr2(struct drm_connector *connector) |
@@ -1319,7 +1266,8 @@ radeon_dp_detect(struct drm_connector *connector, bool force) | |||
1319 | if (!radeon_dig_connector->edp_on) | 1266 | if (!radeon_dig_connector->edp_on) |
1320 | atombios_set_edp_panel_power(connector, | 1267 | atombios_set_edp_panel_power(connector, |
1321 | ATOM_TRANSMITTER_ACTION_POWER_OFF); | 1268 | ATOM_TRANSMITTER_ACTION_POWER_OFF); |
1322 | } else if (radeon_connector_encoder_is_dp_bridge(connector)) { | 1269 | } else if (radeon_connector_encoder_get_dp_bridge_encoder_id(connector) != |
1270 | ENCODER_OBJECT_ID_NONE) { | ||
1323 | /* DP bridges are always DP */ | 1271 | /* DP bridges are always DP */ |
1324 | radeon_dig_connector->dp_sink_type = CONNECTOR_OBJECT_ID_DISPLAYPORT; | 1272 | radeon_dig_connector->dp_sink_type = CONNECTOR_OBJECT_ID_DISPLAYPORT; |
1325 | /* get the DPCD from the bridge */ | 1273 | /* get the DPCD from the bridge */ |
@@ -1328,8 +1276,7 @@ radeon_dp_detect(struct drm_connector *connector, bool force) | |||
1328 | if (encoder) { | 1276 | if (encoder) { |
1329 | /* setup ddc on the bridge */ | 1277 | /* setup ddc on the bridge */ |
1330 | radeon_atom_ext_encoder_setup_ddc(encoder); | 1278 | radeon_atom_ext_encoder_setup_ddc(encoder); |
1331 | if (radeon_ddc_probe(radeon_connector, | 1279 | if (radeon_ddc_probe(radeon_connector)) /* try DDC */ |
1332 | radeon_connector->requires_extended_probe)) /* try DDC */ | ||
1333 | ret = connector_status_connected; | 1280 | ret = connector_status_connected; |
1334 | else if (radeon_connector->dac_load_detect) { /* try load detection */ | 1281 | else if (radeon_connector->dac_load_detect) { /* try load detection */ |
1335 | struct drm_encoder_helper_funcs *encoder_funcs = encoder->helper_private; | 1282 | struct drm_encoder_helper_funcs *encoder_funcs = encoder->helper_private; |
@@ -1347,8 +1294,7 @@ radeon_dp_detect(struct drm_connector *connector, bool force) | |||
1347 | if (radeon_dp_getdpcd(radeon_connector)) | 1294 | if (radeon_dp_getdpcd(radeon_connector)) |
1348 | ret = connector_status_connected; | 1295 | ret = connector_status_connected; |
1349 | } else { | 1296 | } else { |
1350 | if (radeon_ddc_probe(radeon_connector, | 1297 | if (radeon_ddc_probe(radeon_connector)) |
1351 | radeon_connector->requires_extended_probe)) | ||
1352 | ret = connector_status_connected; | 1298 | ret = connector_status_connected; |
1353 | } | 1299 | } |
1354 | } | 1300 | } |
@@ -1493,9 +1439,7 @@ radeon_add_atom_connector(struct drm_device *dev, | |||
1493 | radeon_connector->shared_ddc = shared_ddc; | 1439 | radeon_connector->shared_ddc = shared_ddc; |
1494 | radeon_connector->connector_object_id = connector_object_id; | 1440 | radeon_connector->connector_object_id = connector_object_id; |
1495 | radeon_connector->hpd = *hpd; | 1441 | radeon_connector->hpd = *hpd; |
1496 | radeon_connector->requires_extended_probe = | 1442 | |
1497 | radeon_connector_needs_extended_probe(rdev, supported_device, | ||
1498 | connector_type); | ||
1499 | radeon_connector->router = *router; | 1443 | radeon_connector->router = *router; |
1500 | if (router->ddc_valid || router->cd_valid) { | 1444 | if (router->ddc_valid || router->cd_valid) { |
1501 | radeon_connector->router_bus = radeon_i2c_lookup(rdev, &router->i2c_info); | 1445 | radeon_connector->router_bus = radeon_i2c_lookup(rdev, &router->i2c_info); |
@@ -1842,9 +1786,7 @@ radeon_add_legacy_connector(struct drm_device *dev, | |||
1842 | radeon_connector->devices = supported_device; | 1786 | radeon_connector->devices = supported_device; |
1843 | radeon_connector->connector_object_id = connector_object_id; | 1787 | radeon_connector->connector_object_id = connector_object_id; |
1844 | radeon_connector->hpd = *hpd; | 1788 | radeon_connector->hpd = *hpd; |
1845 | radeon_connector->requires_extended_probe = | 1789 | |
1846 | radeon_connector_needs_extended_probe(rdev, supported_device, | ||
1847 | connector_type); | ||
1848 | switch (connector_type) { | 1790 | switch (connector_type) { |
1849 | case DRM_MODE_CONNECTOR_VGA: | 1791 | case DRM_MODE_CONNECTOR_VGA: |
1850 | drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type); | 1792 | drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type); |
diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c index 6adb3e58affd..a22d6e6a49a2 100644 --- a/drivers/gpu/drm/radeon/radeon_display.c +++ b/drivers/gpu/drm/radeon/radeon_display.c | |||
@@ -33,8 +33,6 @@ | |||
33 | #include "drm_crtc_helper.h" | 33 | #include "drm_crtc_helper.h" |
34 | #include "drm_edid.h" | 34 | #include "drm_edid.h" |
35 | 35 | ||
36 | static int radeon_ddc_dump(struct drm_connector *connector); | ||
37 | |||
38 | static void avivo_crtc_load_lut(struct drm_crtc *crtc) | 36 | static void avivo_crtc_load_lut(struct drm_crtc *crtc) |
39 | { | 37 | { |
40 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); | 38 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); |
@@ -669,7 +667,6 @@ static void radeon_print_display_setup(struct drm_device *dev) | |||
669 | static bool radeon_setup_enc_conn(struct drm_device *dev) | 667 | static bool radeon_setup_enc_conn(struct drm_device *dev) |
670 | { | 668 | { |
671 | struct radeon_device *rdev = dev->dev_private; | 669 | struct radeon_device *rdev = dev->dev_private; |
672 | struct drm_connector *drm_connector; | ||
673 | bool ret = false; | 670 | bool ret = false; |
674 | 671 | ||
675 | if (rdev->bios) { | 672 | if (rdev->bios) { |
@@ -689,8 +686,6 @@ static bool radeon_setup_enc_conn(struct drm_device *dev) | |||
689 | if (ret) { | 686 | if (ret) { |
690 | radeon_setup_encoder_clones(dev); | 687 | radeon_setup_encoder_clones(dev); |
691 | radeon_print_display_setup(dev); | 688 | radeon_print_display_setup(dev); |
692 | list_for_each_entry(drm_connector, &dev->mode_config.connector_list, head) | ||
693 | radeon_ddc_dump(drm_connector); | ||
694 | } | 689 | } |
695 | 690 | ||
696 | return ret; | 691 | return ret; |
@@ -708,7 +703,8 @@ int radeon_ddc_get_modes(struct radeon_connector *radeon_connector) | |||
708 | 703 | ||
709 | if ((radeon_connector->base.connector_type == DRM_MODE_CONNECTOR_DisplayPort) || | 704 | if ((radeon_connector->base.connector_type == DRM_MODE_CONNECTOR_DisplayPort) || |
710 | (radeon_connector->base.connector_type == DRM_MODE_CONNECTOR_eDP) || | 705 | (radeon_connector->base.connector_type == DRM_MODE_CONNECTOR_eDP) || |
711 | radeon_connector_encoder_is_dp_bridge(&radeon_connector->base)) { | 706 | (radeon_connector_encoder_get_dp_bridge_encoder_id(&radeon_connector->base) != |
707 | ENCODER_OBJECT_ID_NONE)) { | ||
712 | struct radeon_connector_atom_dig *dig = radeon_connector->con_priv; | 708 | struct radeon_connector_atom_dig *dig = radeon_connector->con_priv; |
713 | 709 | ||
714 | if ((dig->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT || | 710 | if ((dig->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT || |
@@ -743,34 +739,6 @@ int radeon_ddc_get_modes(struct radeon_connector *radeon_connector) | |||
743 | return 0; | 739 | return 0; |
744 | } | 740 | } |
745 | 741 | ||
746 | static int radeon_ddc_dump(struct drm_connector *connector) | ||
747 | { | ||
748 | struct edid *edid; | ||
749 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | ||
750 | int ret = 0; | ||
751 | |||
752 | /* on hw with routers, select right port */ | ||
753 | if (radeon_connector->router.ddc_valid) | ||
754 | radeon_router_select_ddc_port(radeon_connector); | ||
755 | |||
756 | if (!radeon_connector->ddc_bus) | ||
757 | return -1; | ||
758 | edid = drm_get_edid(connector, &radeon_connector->ddc_bus->adapter); | ||
759 | /* Log EDID retrieval status here. In particular with regard to | ||
760 | * connectors with requires_extended_probe flag set, that will prevent | ||
761 | * function radeon_dvi_detect() to fetch EDID on this connector, | ||
762 | * as long as there is no valid EDID header found */ | ||
763 | if (edid) { | ||
764 | DRM_INFO("Radeon display connector %s: Found valid EDID", | ||
765 | drm_get_connector_name(connector)); | ||
766 | kfree(edid); | ||
767 | } else { | ||
768 | DRM_INFO("Radeon display connector %s: No monitor connected or invalid EDID", | ||
769 | drm_get_connector_name(connector)); | ||
770 | } | ||
771 | return ret; | ||
772 | } | ||
773 | |||
774 | /* avivo */ | 742 | /* avivo */ |
775 | static void avivo_get_fb_div(struct radeon_pll *pll, | 743 | static void avivo_get_fb_div(struct radeon_pll *pll, |
776 | u32 target_clock, | 744 | u32 target_clock, |
diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c index 969933833ccb..a0b35e909489 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.c +++ b/drivers/gpu/drm/radeon/radeon_drv.c | |||
@@ -119,6 +119,7 @@ int radeon_audio = 0; | |||
119 | int radeon_disp_priority = 0; | 119 | int radeon_disp_priority = 0; |
120 | int radeon_hw_i2c = 0; | 120 | int radeon_hw_i2c = 0; |
121 | int radeon_pcie_gen2 = 0; | 121 | int radeon_pcie_gen2 = 0; |
122 | int radeon_msi = -1; | ||
122 | 123 | ||
123 | MODULE_PARM_DESC(no_wb, "Disable AGP writeback for scratch registers"); | 124 | MODULE_PARM_DESC(no_wb, "Disable AGP writeback for scratch registers"); |
124 | module_param_named(no_wb, radeon_no_wb, int, 0444); | 125 | module_param_named(no_wb, radeon_no_wb, int, 0444); |
@@ -165,6 +166,9 @@ module_param_named(hw_i2c, radeon_hw_i2c, int, 0444); | |||
165 | MODULE_PARM_DESC(pcie_gen2, "PCIE Gen2 mode (1 = enable)"); | 166 | MODULE_PARM_DESC(pcie_gen2, "PCIE Gen2 mode (1 = enable)"); |
166 | module_param_named(pcie_gen2, radeon_pcie_gen2, int, 0444); | 167 | module_param_named(pcie_gen2, radeon_pcie_gen2, int, 0444); |
167 | 168 | ||
169 | MODULE_PARM_DESC(msi, "MSI support (1 = enable, 0 = disable, -1 = auto)"); | ||
170 | module_param_named(msi, radeon_msi, int, 0444); | ||
171 | |||
168 | static int radeon_suspend(struct drm_device *dev, pm_message_t state) | 172 | static int radeon_suspend(struct drm_device *dev, pm_message_t state) |
169 | { | 173 | { |
170 | drm_radeon_private_t *dev_priv = dev->dev_private; | 174 | drm_radeon_private_t *dev_priv = dev->dev_private; |
diff --git a/drivers/gpu/drm/radeon/radeon_encoders.c b/drivers/gpu/drm/radeon/radeon_encoders.c index eb3f6dc6df83..06e413e6a920 100644 --- a/drivers/gpu/drm/radeon/radeon_encoders.c +++ b/drivers/gpu/drm/radeon/radeon_encoders.c | |||
@@ -29,12 +29,6 @@ | |||
29 | #include "radeon.h" | 29 | #include "radeon.h" |
30 | #include "atom.h" | 30 | #include "atom.h" |
31 | 31 | ||
32 | extern int atom_debug; | ||
33 | |||
34 | /* evil but including atombios.h is much worse */ | ||
35 | bool radeon_atom_get_tv_timings(struct radeon_device *rdev, int index, | ||
36 | struct drm_display_mode *mode); | ||
37 | |||
38 | static uint32_t radeon_encoder_clones(struct drm_encoder *encoder) | 32 | static uint32_t radeon_encoder_clones(struct drm_encoder *encoder) |
39 | { | 33 | { |
40 | struct drm_device *dev = encoder->dev; | 34 | struct drm_device *dev = encoder->dev; |
@@ -156,27 +150,6 @@ radeon_get_encoder_enum(struct drm_device *dev, uint32_t supported_device, uint8 | |||
156 | return ret; | 150 | return ret; |
157 | } | 151 | } |
158 | 152 | ||
159 | static inline bool radeon_encoder_is_digital(struct drm_encoder *encoder) | ||
160 | { | ||
161 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
162 | switch (radeon_encoder->encoder_id) { | ||
163 | case ENCODER_OBJECT_ID_INTERNAL_LVDS: | ||
164 | case ENCODER_OBJECT_ID_INTERNAL_TMDS1: | ||
165 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1: | ||
166 | case ENCODER_OBJECT_ID_INTERNAL_LVTM1: | ||
167 | case ENCODER_OBJECT_ID_INTERNAL_DVO1: | ||
168 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1: | ||
169 | case ENCODER_OBJECT_ID_INTERNAL_DDI: | ||
170 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: | ||
171 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: | ||
172 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: | ||
173 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: | ||
174 | return true; | ||
175 | default: | ||
176 | return false; | ||
177 | } | ||
178 | } | ||
179 | |||
180 | void | 153 | void |
181 | radeon_link_encoder_connector(struct drm_device *dev) | 154 | radeon_link_encoder_connector(struct drm_device *dev) |
182 | { | 155 | { |
@@ -229,23 +202,7 @@ radeon_get_connector_for_encoder(struct drm_encoder *encoder) | |||
229 | return NULL; | 202 | return NULL; |
230 | } | 203 | } |
231 | 204 | ||
232 | static struct drm_connector * | 205 | struct drm_encoder *radeon_get_external_encoder(struct drm_encoder *encoder) |
233 | radeon_get_connector_for_encoder_init(struct drm_encoder *encoder) | ||
234 | { | ||
235 | struct drm_device *dev = encoder->dev; | ||
236 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
237 | struct drm_connector *connector; | ||
238 | struct radeon_connector *radeon_connector; | ||
239 | |||
240 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { | ||
241 | radeon_connector = to_radeon_connector(connector); | ||
242 | if (radeon_encoder->devices & radeon_connector->devices) | ||
243 | return connector; | ||
244 | } | ||
245 | return NULL; | ||
246 | } | ||
247 | |||
248 | struct drm_encoder *radeon_atom_get_external_encoder(struct drm_encoder *encoder) | ||
249 | { | 206 | { |
250 | struct drm_device *dev = encoder->dev; | 207 | struct drm_device *dev = encoder->dev; |
251 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | 208 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
@@ -266,9 +223,9 @@ struct drm_encoder *radeon_atom_get_external_encoder(struct drm_encoder *encoder | |||
266 | return NULL; | 223 | return NULL; |
267 | } | 224 | } |
268 | 225 | ||
269 | bool radeon_encoder_is_dp_bridge(struct drm_encoder *encoder) | 226 | u16 radeon_encoder_get_dp_bridge_encoder_id(struct drm_encoder *encoder) |
270 | { | 227 | { |
271 | struct drm_encoder *other_encoder = radeon_atom_get_external_encoder(encoder); | 228 | struct drm_encoder *other_encoder = radeon_get_external_encoder(encoder); |
272 | 229 | ||
273 | if (other_encoder) { | 230 | if (other_encoder) { |
274 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(other_encoder); | 231 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(other_encoder); |
@@ -332,2105 +289,3 @@ void radeon_panel_mode_fixup(struct drm_encoder *encoder, | |||
332 | 289 | ||
333 | } | 290 | } |
334 | 291 | ||
335 | static bool radeon_atom_mode_fixup(struct drm_encoder *encoder, | ||
336 | struct drm_display_mode *mode, | ||
337 | struct drm_display_mode *adjusted_mode) | ||
338 | { | ||
339 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
340 | struct drm_device *dev = encoder->dev; | ||
341 | struct radeon_device *rdev = dev->dev_private; | ||
342 | |||
343 | /* set the active encoder to connector routing */ | ||
344 | radeon_encoder_set_active_device(encoder); | ||
345 | drm_mode_set_crtcinfo(adjusted_mode, 0); | ||
346 | |||
347 | /* hw bug */ | ||
348 | if ((mode->flags & DRM_MODE_FLAG_INTERLACE) | ||
349 | && (mode->crtc_vsync_start < (mode->crtc_vdisplay + 2))) | ||
350 | adjusted_mode->crtc_vsync_start = adjusted_mode->crtc_vdisplay + 2; | ||
351 | |||
352 | /* get the native mode for LVDS */ | ||
353 | if (radeon_encoder->active_device & (ATOM_DEVICE_LCD_SUPPORT)) | ||
354 | radeon_panel_mode_fixup(encoder, adjusted_mode); | ||
355 | |||
356 | /* get the native mode for TV */ | ||
357 | if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT)) { | ||
358 | struct radeon_encoder_atom_dac *tv_dac = radeon_encoder->enc_priv; | ||
359 | if (tv_dac) { | ||
360 | if (tv_dac->tv_std == TV_STD_NTSC || | ||
361 | tv_dac->tv_std == TV_STD_NTSC_J || | ||
362 | tv_dac->tv_std == TV_STD_PAL_M) | ||
363 | radeon_atom_get_tv_timings(rdev, 0, adjusted_mode); | ||
364 | else | ||
365 | radeon_atom_get_tv_timings(rdev, 1, adjusted_mode); | ||
366 | } | ||
367 | } | ||
368 | |||
369 | if (ASIC_IS_DCE3(rdev) && | ||
370 | ((radeon_encoder->active_device & (ATOM_DEVICE_DFP_SUPPORT | ATOM_DEVICE_LCD_SUPPORT)) || | ||
371 | radeon_encoder_is_dp_bridge(encoder))) { | ||
372 | struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); | ||
373 | radeon_dp_set_link_config(connector, mode); | ||
374 | } | ||
375 | |||
376 | return true; | ||
377 | } | ||
378 | |||
379 | static void | ||
380 | atombios_dac_setup(struct drm_encoder *encoder, int action) | ||
381 | { | ||
382 | struct drm_device *dev = encoder->dev; | ||
383 | struct radeon_device *rdev = dev->dev_private; | ||
384 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
385 | DAC_ENCODER_CONTROL_PS_ALLOCATION args; | ||
386 | int index = 0; | ||
387 | struct radeon_encoder_atom_dac *dac_info = radeon_encoder->enc_priv; | ||
388 | |||
389 | memset(&args, 0, sizeof(args)); | ||
390 | |||
391 | switch (radeon_encoder->encoder_id) { | ||
392 | case ENCODER_OBJECT_ID_INTERNAL_DAC1: | ||
393 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1: | ||
394 | index = GetIndexIntoMasterTable(COMMAND, DAC1EncoderControl); | ||
395 | break; | ||
396 | case ENCODER_OBJECT_ID_INTERNAL_DAC2: | ||
397 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2: | ||
398 | index = GetIndexIntoMasterTable(COMMAND, DAC2EncoderControl); | ||
399 | break; | ||
400 | } | ||
401 | |||
402 | args.ucAction = action; | ||
403 | |||
404 | if (radeon_encoder->active_device & (ATOM_DEVICE_CRT_SUPPORT)) | ||
405 | args.ucDacStandard = ATOM_DAC1_PS2; | ||
406 | else if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT)) | ||
407 | args.ucDacStandard = ATOM_DAC1_CV; | ||
408 | else { | ||
409 | switch (dac_info->tv_std) { | ||
410 | case TV_STD_PAL: | ||
411 | case TV_STD_PAL_M: | ||
412 | case TV_STD_SCART_PAL: | ||
413 | case TV_STD_SECAM: | ||
414 | case TV_STD_PAL_CN: | ||
415 | args.ucDacStandard = ATOM_DAC1_PAL; | ||
416 | break; | ||
417 | case TV_STD_NTSC: | ||
418 | case TV_STD_NTSC_J: | ||
419 | case TV_STD_PAL_60: | ||
420 | default: | ||
421 | args.ucDacStandard = ATOM_DAC1_NTSC; | ||
422 | break; | ||
423 | } | ||
424 | } | ||
425 | args.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); | ||
426 | |||
427 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); | ||
428 | |||
429 | } | ||
430 | |||
431 | static void | ||
432 | atombios_tv_setup(struct drm_encoder *encoder, int action) | ||
433 | { | ||
434 | struct drm_device *dev = encoder->dev; | ||
435 | struct radeon_device *rdev = dev->dev_private; | ||
436 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
437 | TV_ENCODER_CONTROL_PS_ALLOCATION args; | ||
438 | int index = 0; | ||
439 | struct radeon_encoder_atom_dac *dac_info = radeon_encoder->enc_priv; | ||
440 | |||
441 | memset(&args, 0, sizeof(args)); | ||
442 | |||
443 | index = GetIndexIntoMasterTable(COMMAND, TVEncoderControl); | ||
444 | |||
445 | args.sTVEncoder.ucAction = action; | ||
446 | |||
447 | if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT)) | ||
448 | args.sTVEncoder.ucTvStandard = ATOM_TV_CV; | ||
449 | else { | ||
450 | switch (dac_info->tv_std) { | ||
451 | case TV_STD_NTSC: | ||
452 | args.sTVEncoder.ucTvStandard = ATOM_TV_NTSC; | ||
453 | break; | ||
454 | case TV_STD_PAL: | ||
455 | args.sTVEncoder.ucTvStandard = ATOM_TV_PAL; | ||
456 | break; | ||
457 | case TV_STD_PAL_M: | ||
458 | args.sTVEncoder.ucTvStandard = ATOM_TV_PALM; | ||
459 | break; | ||
460 | case TV_STD_PAL_60: | ||
461 | args.sTVEncoder.ucTvStandard = ATOM_TV_PAL60; | ||
462 | break; | ||
463 | case TV_STD_NTSC_J: | ||
464 | args.sTVEncoder.ucTvStandard = ATOM_TV_NTSCJ; | ||
465 | break; | ||
466 | case TV_STD_SCART_PAL: | ||
467 | args.sTVEncoder.ucTvStandard = ATOM_TV_PAL; /* ??? */ | ||
468 | break; | ||
469 | case TV_STD_SECAM: | ||
470 | args.sTVEncoder.ucTvStandard = ATOM_TV_SECAM; | ||
471 | break; | ||
472 | case TV_STD_PAL_CN: | ||
473 | args.sTVEncoder.ucTvStandard = ATOM_TV_PALCN; | ||
474 | break; | ||
475 | default: | ||
476 | args.sTVEncoder.ucTvStandard = ATOM_TV_NTSC; | ||
477 | break; | ||
478 | } | ||
479 | } | ||
480 | |||
481 | args.sTVEncoder.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); | ||
482 | |||
483 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); | ||
484 | |||
485 | } | ||
486 | |||
487 | union dvo_encoder_control { | ||
488 | ENABLE_EXTERNAL_TMDS_ENCODER_PS_ALLOCATION ext_tmds; | ||
489 | DVO_ENCODER_CONTROL_PS_ALLOCATION dvo; | ||
490 | DVO_ENCODER_CONTROL_PS_ALLOCATION_V3 dvo_v3; | ||
491 | }; | ||
492 | |||
493 | void | ||
494 | atombios_dvo_setup(struct drm_encoder *encoder, int action) | ||
495 | { | ||
496 | struct drm_device *dev = encoder->dev; | ||
497 | struct radeon_device *rdev = dev->dev_private; | ||
498 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
499 | union dvo_encoder_control args; | ||
500 | int index = GetIndexIntoMasterTable(COMMAND, DVOEncoderControl); | ||
501 | |||
502 | memset(&args, 0, sizeof(args)); | ||
503 | |||
504 | if (ASIC_IS_DCE3(rdev)) { | ||
505 | /* DCE3+ */ | ||
506 | args.dvo_v3.ucAction = action; | ||
507 | args.dvo_v3.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); | ||
508 | args.dvo_v3.ucDVOConfig = 0; /* XXX */ | ||
509 | } else if (ASIC_IS_DCE2(rdev)) { | ||
510 | /* DCE2 (pre-DCE3 R6xx, RS600/690/740 */ | ||
511 | args.dvo.sDVOEncoder.ucAction = action; | ||
512 | args.dvo.sDVOEncoder.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); | ||
513 | /* DFP1, CRT1, TV1 depending on the type of port */ | ||
514 | args.dvo.sDVOEncoder.ucDeviceType = ATOM_DEVICE_DFP1_INDEX; | ||
515 | |||
516 | if (radeon_encoder->pixel_clock > 165000) | ||
517 | args.dvo.sDVOEncoder.usDevAttr.sDigAttrib.ucAttribute |= PANEL_ENCODER_MISC_DUAL; | ||
518 | } else { | ||
519 | /* R4xx, R5xx */ | ||
520 | args.ext_tmds.sXTmdsEncoder.ucEnable = action; | ||
521 | |||
522 | if (radeon_encoder->pixel_clock > 165000) | ||
523 | args.ext_tmds.sXTmdsEncoder.ucMisc |= PANEL_ENCODER_MISC_DUAL; | ||
524 | |||
525 | /*if (pScrn->rgbBits == 8)*/ | ||
526 | args.ext_tmds.sXTmdsEncoder.ucMisc |= ATOM_PANEL_MISC_888RGB; | ||
527 | } | ||
528 | |||
529 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); | ||
530 | } | ||
531 | |||
532 | union lvds_encoder_control { | ||
533 | LVDS_ENCODER_CONTROL_PS_ALLOCATION v1; | ||
534 | LVDS_ENCODER_CONTROL_PS_ALLOCATION_V2 v2; | ||
535 | }; | ||
536 | |||
537 | void | ||
538 | atombios_digital_setup(struct drm_encoder *encoder, int action) | ||
539 | { | ||
540 | struct drm_device *dev = encoder->dev; | ||
541 | struct radeon_device *rdev = dev->dev_private; | ||
542 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
543 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; | ||
544 | union lvds_encoder_control args; | ||
545 | int index = 0; | ||
546 | int hdmi_detected = 0; | ||
547 | uint8_t frev, crev; | ||
548 | |||
549 | if (!dig) | ||
550 | return; | ||
551 | |||
552 | if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_HDMI) | ||
553 | hdmi_detected = 1; | ||
554 | |||
555 | memset(&args, 0, sizeof(args)); | ||
556 | |||
557 | switch (radeon_encoder->encoder_id) { | ||
558 | case ENCODER_OBJECT_ID_INTERNAL_LVDS: | ||
559 | index = GetIndexIntoMasterTable(COMMAND, LVDSEncoderControl); | ||
560 | break; | ||
561 | case ENCODER_OBJECT_ID_INTERNAL_TMDS1: | ||
562 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1: | ||
563 | index = GetIndexIntoMasterTable(COMMAND, TMDS1EncoderControl); | ||
564 | break; | ||
565 | case ENCODER_OBJECT_ID_INTERNAL_LVTM1: | ||
566 | if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) | ||
567 | index = GetIndexIntoMasterTable(COMMAND, LVDSEncoderControl); | ||
568 | else | ||
569 | index = GetIndexIntoMasterTable(COMMAND, TMDS2EncoderControl); | ||
570 | break; | ||
571 | } | ||
572 | |||
573 | if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev)) | ||
574 | return; | ||
575 | |||
576 | switch (frev) { | ||
577 | case 1: | ||
578 | case 2: | ||
579 | switch (crev) { | ||
580 | case 1: | ||
581 | args.v1.ucMisc = 0; | ||
582 | args.v1.ucAction = action; | ||
583 | if (hdmi_detected) | ||
584 | args.v1.ucMisc |= PANEL_ENCODER_MISC_HDMI_TYPE; | ||
585 | args.v1.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); | ||
586 | if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) { | ||
587 | if (dig->lcd_misc & ATOM_PANEL_MISC_DUAL) | ||
588 | args.v1.ucMisc |= PANEL_ENCODER_MISC_DUAL; | ||
589 | if (dig->lcd_misc & ATOM_PANEL_MISC_888RGB) | ||
590 | args.v1.ucMisc |= ATOM_PANEL_MISC_888RGB; | ||
591 | } else { | ||
592 | if (dig->linkb) | ||
593 | args.v1.ucMisc |= PANEL_ENCODER_MISC_TMDS_LINKB; | ||
594 | if (radeon_encoder->pixel_clock > 165000) | ||
595 | args.v1.ucMisc |= PANEL_ENCODER_MISC_DUAL; | ||
596 | /*if (pScrn->rgbBits == 8) */ | ||
597 | args.v1.ucMisc |= ATOM_PANEL_MISC_888RGB; | ||
598 | } | ||
599 | break; | ||
600 | case 2: | ||
601 | case 3: | ||
602 | args.v2.ucMisc = 0; | ||
603 | args.v2.ucAction = action; | ||
604 | if (crev == 3) { | ||
605 | if (dig->coherent_mode) | ||
606 | args.v2.ucMisc |= PANEL_ENCODER_MISC_COHERENT; | ||
607 | } | ||
608 | if (hdmi_detected) | ||
609 | args.v2.ucMisc |= PANEL_ENCODER_MISC_HDMI_TYPE; | ||
610 | args.v2.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); | ||
611 | args.v2.ucTruncate = 0; | ||
612 | args.v2.ucSpatial = 0; | ||
613 | args.v2.ucTemporal = 0; | ||
614 | args.v2.ucFRC = 0; | ||
615 | if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) { | ||
616 | if (dig->lcd_misc & ATOM_PANEL_MISC_DUAL) | ||
617 | args.v2.ucMisc |= PANEL_ENCODER_MISC_DUAL; | ||
618 | if (dig->lcd_misc & ATOM_PANEL_MISC_SPATIAL) { | ||
619 | args.v2.ucSpatial = PANEL_ENCODER_SPATIAL_DITHER_EN; | ||
620 | if (dig->lcd_misc & ATOM_PANEL_MISC_888RGB) | ||
621 | args.v2.ucSpatial |= PANEL_ENCODER_SPATIAL_DITHER_DEPTH; | ||
622 | } | ||
623 | if (dig->lcd_misc & ATOM_PANEL_MISC_TEMPORAL) { | ||
624 | args.v2.ucTemporal = PANEL_ENCODER_TEMPORAL_DITHER_EN; | ||
625 | if (dig->lcd_misc & ATOM_PANEL_MISC_888RGB) | ||
626 | args.v2.ucTemporal |= PANEL_ENCODER_TEMPORAL_DITHER_DEPTH; | ||
627 | if (((dig->lcd_misc >> ATOM_PANEL_MISC_GREY_LEVEL_SHIFT) & 0x3) == 2) | ||
628 | args.v2.ucTemporal |= PANEL_ENCODER_TEMPORAL_LEVEL_4; | ||
629 | } | ||
630 | } else { | ||
631 | if (dig->linkb) | ||
632 | args.v2.ucMisc |= PANEL_ENCODER_MISC_TMDS_LINKB; | ||
633 | if (radeon_encoder->pixel_clock > 165000) | ||
634 | args.v2.ucMisc |= PANEL_ENCODER_MISC_DUAL; | ||
635 | } | ||
636 | break; | ||
637 | default: | ||
638 | DRM_ERROR("Unknown table version %d, %d\n", frev, crev); | ||
639 | break; | ||
640 | } | ||
641 | break; | ||
642 | default: | ||
643 | DRM_ERROR("Unknown table version %d, %d\n", frev, crev); | ||
644 | break; | ||
645 | } | ||
646 | |||
647 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); | ||
648 | } | ||
649 | |||
650 | int | ||
651 | atombios_get_encoder_mode(struct drm_encoder *encoder) | ||
652 | { | ||
653 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
654 | struct drm_device *dev = encoder->dev; | ||
655 | struct radeon_device *rdev = dev->dev_private; | ||
656 | struct drm_connector *connector; | ||
657 | struct radeon_connector *radeon_connector; | ||
658 | struct radeon_connector_atom_dig *dig_connector; | ||
659 | |||
660 | /* dp bridges are always DP */ | ||
661 | if (radeon_encoder_is_dp_bridge(encoder)) | ||
662 | return ATOM_ENCODER_MODE_DP; | ||
663 | |||
664 | /* DVO is always DVO */ | ||
665 | if (radeon_encoder->encoder_id == ATOM_ENCODER_MODE_DVO) | ||
666 | return ATOM_ENCODER_MODE_DVO; | ||
667 | |||
668 | connector = radeon_get_connector_for_encoder(encoder); | ||
669 | /* if we don't have an active device yet, just use one of | ||
670 | * the connectors tied to the encoder. | ||
671 | */ | ||
672 | if (!connector) | ||
673 | connector = radeon_get_connector_for_encoder_init(encoder); | ||
674 | radeon_connector = to_radeon_connector(connector); | ||
675 | |||
676 | switch (connector->connector_type) { | ||
677 | case DRM_MODE_CONNECTOR_DVII: | ||
678 | case DRM_MODE_CONNECTOR_HDMIB: /* HDMI-B is basically DL-DVI; analog works fine */ | ||
679 | if (drm_detect_monitor_audio(radeon_connector->edid) && radeon_audio) { | ||
680 | /* fix me */ | ||
681 | if (ASIC_IS_DCE4(rdev)) | ||
682 | return ATOM_ENCODER_MODE_DVI; | ||
683 | else | ||
684 | return ATOM_ENCODER_MODE_HDMI; | ||
685 | } else if (radeon_connector->use_digital) | ||
686 | return ATOM_ENCODER_MODE_DVI; | ||
687 | else | ||
688 | return ATOM_ENCODER_MODE_CRT; | ||
689 | break; | ||
690 | case DRM_MODE_CONNECTOR_DVID: | ||
691 | case DRM_MODE_CONNECTOR_HDMIA: | ||
692 | default: | ||
693 | if (drm_detect_monitor_audio(radeon_connector->edid) && radeon_audio) { | ||
694 | /* fix me */ | ||
695 | if (ASIC_IS_DCE4(rdev)) | ||
696 | return ATOM_ENCODER_MODE_DVI; | ||
697 | else | ||
698 | return ATOM_ENCODER_MODE_HDMI; | ||
699 | } else | ||
700 | return ATOM_ENCODER_MODE_DVI; | ||
701 | break; | ||
702 | case DRM_MODE_CONNECTOR_LVDS: | ||
703 | return ATOM_ENCODER_MODE_LVDS; | ||
704 | break; | ||
705 | case DRM_MODE_CONNECTOR_DisplayPort: | ||
706 | dig_connector = radeon_connector->con_priv; | ||
707 | if ((dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) || | ||
708 | (dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_eDP)) | ||
709 | return ATOM_ENCODER_MODE_DP; | ||
710 | else if (drm_detect_monitor_audio(radeon_connector->edid) && radeon_audio) { | ||
711 | /* fix me */ | ||
712 | if (ASIC_IS_DCE4(rdev)) | ||
713 | return ATOM_ENCODER_MODE_DVI; | ||
714 | else | ||
715 | return ATOM_ENCODER_MODE_HDMI; | ||
716 | } else | ||
717 | return ATOM_ENCODER_MODE_DVI; | ||
718 | break; | ||
719 | case DRM_MODE_CONNECTOR_eDP: | ||
720 | return ATOM_ENCODER_MODE_DP; | ||
721 | case DRM_MODE_CONNECTOR_DVIA: | ||
722 | case DRM_MODE_CONNECTOR_VGA: | ||
723 | return ATOM_ENCODER_MODE_CRT; | ||
724 | break; | ||
725 | case DRM_MODE_CONNECTOR_Composite: | ||
726 | case DRM_MODE_CONNECTOR_SVIDEO: | ||
727 | case DRM_MODE_CONNECTOR_9PinDIN: | ||
728 | /* fix me */ | ||
729 | return ATOM_ENCODER_MODE_TV; | ||
730 | /*return ATOM_ENCODER_MODE_CV;*/ | ||
731 | break; | ||
732 | } | ||
733 | } | ||
734 | |||
735 | /* | ||
736 | * DIG Encoder/Transmitter Setup | ||
737 | * | ||
738 | * DCE 3.0/3.1 | ||
739 | * - 2 DIG transmitter blocks. UNIPHY (links A and B) and LVTMA. | ||
740 | * Supports up to 3 digital outputs | ||
741 | * - 2 DIG encoder blocks. | ||
742 | * DIG1 can drive UNIPHY link A or link B | ||
743 | * DIG2 can drive UNIPHY link B or LVTMA | ||
744 | * | ||
745 | * DCE 3.2 | ||
746 | * - 3 DIG transmitter blocks. UNIPHY0/1/2 (links A and B). | ||
747 | * Supports up to 5 digital outputs | ||
748 | * - 2 DIG encoder blocks. | ||
749 | * DIG1/2 can drive UNIPHY0/1/2 link A or link B | ||
750 | * | ||
751 | * DCE 4.0/5.0 | ||
752 | * - 3 DIG transmitter blocks UNIPHY0/1/2 (links A and B). | ||
753 | * Supports up to 6 digital outputs | ||
754 | * - 6 DIG encoder blocks. | ||
755 | * - DIG to PHY mapping is hardcoded | ||
756 | * DIG1 drives UNIPHY0 link A, A+B | ||
757 | * DIG2 drives UNIPHY0 link B | ||
758 | * DIG3 drives UNIPHY1 link A, A+B | ||
759 | * DIG4 drives UNIPHY1 link B | ||
760 | * DIG5 drives UNIPHY2 link A, A+B | ||
761 | * DIG6 drives UNIPHY2 link B | ||
762 | * | ||
763 | * DCE 4.1 | ||
764 | * - 3 DIG transmitter blocks UNIPHY0/1/2 (links A and B). | ||
765 | * Supports up to 6 digital outputs | ||
766 | * - 2 DIG encoder blocks. | ||
767 | * DIG1/2 can drive UNIPHY0/1/2 link A or link B | ||
768 | * | ||
769 | * Routing | ||
770 | * crtc -> dig encoder -> UNIPHY/LVTMA (1 or 2 links) | ||
771 | * Examples: | ||
772 | * crtc0 -> dig2 -> LVTMA links A+B -> TMDS/HDMI | ||
773 | * crtc1 -> dig1 -> UNIPHY0 link B -> DP | ||
774 | * crtc0 -> dig1 -> UNIPHY2 link A -> LVDS | ||
775 | * crtc1 -> dig2 -> UNIPHY1 link B+A -> TMDS/HDMI | ||
776 | */ | ||
777 | |||
778 | union dig_encoder_control { | ||
779 | DIG_ENCODER_CONTROL_PS_ALLOCATION v1; | ||
780 | DIG_ENCODER_CONTROL_PARAMETERS_V2 v2; | ||
781 | DIG_ENCODER_CONTROL_PARAMETERS_V3 v3; | ||
782 | DIG_ENCODER_CONTROL_PARAMETERS_V4 v4; | ||
783 | }; | ||
784 | |||
785 | void | ||
786 | atombios_dig_encoder_setup(struct drm_encoder *encoder, int action, int panel_mode) | ||
787 | { | ||
788 | struct drm_device *dev = encoder->dev; | ||
789 | struct radeon_device *rdev = dev->dev_private; | ||
790 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
791 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; | ||
792 | struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); | ||
793 | union dig_encoder_control args; | ||
794 | int index = 0; | ||
795 | uint8_t frev, crev; | ||
796 | int dp_clock = 0; | ||
797 | int dp_lane_count = 0; | ||
798 | int hpd_id = RADEON_HPD_NONE; | ||
799 | int bpc = 8; | ||
800 | |||
801 | if (connector) { | ||
802 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | ||
803 | struct radeon_connector_atom_dig *dig_connector = | ||
804 | radeon_connector->con_priv; | ||
805 | |||
806 | dp_clock = dig_connector->dp_clock; | ||
807 | dp_lane_count = dig_connector->dp_lane_count; | ||
808 | hpd_id = radeon_connector->hpd.hpd; | ||
809 | bpc = connector->display_info.bpc; | ||
810 | } | ||
811 | |||
812 | /* no dig encoder assigned */ | ||
813 | if (dig->dig_encoder == -1) | ||
814 | return; | ||
815 | |||
816 | memset(&args, 0, sizeof(args)); | ||
817 | |||
818 | if (ASIC_IS_DCE4(rdev)) | ||
819 | index = GetIndexIntoMasterTable(COMMAND, DIGxEncoderControl); | ||
820 | else { | ||
821 | if (dig->dig_encoder) | ||
822 | index = GetIndexIntoMasterTable(COMMAND, DIG2EncoderControl); | ||
823 | else | ||
824 | index = GetIndexIntoMasterTable(COMMAND, DIG1EncoderControl); | ||
825 | } | ||
826 | |||
827 | if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev)) | ||
828 | return; | ||
829 | |||
830 | args.v1.ucAction = action; | ||
831 | args.v1.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); | ||
832 | if (action == ATOM_ENCODER_CMD_SETUP_PANEL_MODE) | ||
833 | args.v3.ucPanelMode = panel_mode; | ||
834 | else | ||
835 | args.v1.ucEncoderMode = atombios_get_encoder_mode(encoder); | ||
836 | |||
837 | if ((args.v1.ucEncoderMode == ATOM_ENCODER_MODE_DP) || | ||
838 | (args.v1.ucEncoderMode == ATOM_ENCODER_MODE_DP_MST)) | ||
839 | args.v1.ucLaneNum = dp_lane_count; | ||
840 | else if (radeon_encoder->pixel_clock > 165000) | ||
841 | args.v1.ucLaneNum = 8; | ||
842 | else | ||
843 | args.v1.ucLaneNum = 4; | ||
844 | |||
845 | if (ASIC_IS_DCE5(rdev)) { | ||
846 | if ((args.v1.ucEncoderMode == ATOM_ENCODER_MODE_DP) || | ||
847 | (args.v1.ucEncoderMode == ATOM_ENCODER_MODE_DP_MST)) { | ||
848 | if (dp_clock == 270000) | ||
849 | args.v1.ucConfig |= ATOM_ENCODER_CONFIG_V4_DPLINKRATE_2_70GHZ; | ||
850 | else if (dp_clock == 540000) | ||
851 | args.v1.ucConfig |= ATOM_ENCODER_CONFIG_V4_DPLINKRATE_5_40GHZ; | ||
852 | } | ||
853 | args.v4.acConfig.ucDigSel = dig->dig_encoder; | ||
854 | switch (bpc) { | ||
855 | case 0: | ||
856 | args.v4.ucBitPerColor = PANEL_BPC_UNDEFINE; | ||
857 | break; | ||
858 | case 6: | ||
859 | args.v4.ucBitPerColor = PANEL_6BIT_PER_COLOR; | ||
860 | break; | ||
861 | case 8: | ||
862 | default: | ||
863 | args.v4.ucBitPerColor = PANEL_8BIT_PER_COLOR; | ||
864 | break; | ||
865 | case 10: | ||
866 | args.v4.ucBitPerColor = PANEL_10BIT_PER_COLOR; | ||
867 | break; | ||
868 | case 12: | ||
869 | args.v4.ucBitPerColor = PANEL_12BIT_PER_COLOR; | ||
870 | break; | ||
871 | case 16: | ||
872 | args.v4.ucBitPerColor = PANEL_16BIT_PER_COLOR; | ||
873 | break; | ||
874 | } | ||
875 | if (hpd_id == RADEON_HPD_NONE) | ||
876 | args.v4.ucHPD_ID = 0; | ||
877 | else | ||
878 | args.v4.ucHPD_ID = hpd_id + 1; | ||
879 | } else if (ASIC_IS_DCE4(rdev)) { | ||
880 | if ((args.v1.ucEncoderMode == ATOM_ENCODER_MODE_DP) && (dp_clock == 270000)) | ||
881 | args.v1.ucConfig |= ATOM_ENCODER_CONFIG_V3_DPLINKRATE_2_70GHZ; | ||
882 | args.v3.acConfig.ucDigSel = dig->dig_encoder; | ||
883 | switch (bpc) { | ||
884 | case 0: | ||
885 | args.v3.ucBitPerColor = PANEL_BPC_UNDEFINE; | ||
886 | break; | ||
887 | case 6: | ||
888 | args.v3.ucBitPerColor = PANEL_6BIT_PER_COLOR; | ||
889 | break; | ||
890 | case 8: | ||
891 | default: | ||
892 | args.v3.ucBitPerColor = PANEL_8BIT_PER_COLOR; | ||
893 | break; | ||
894 | case 10: | ||
895 | args.v3.ucBitPerColor = PANEL_10BIT_PER_COLOR; | ||
896 | break; | ||
897 | case 12: | ||
898 | args.v3.ucBitPerColor = PANEL_12BIT_PER_COLOR; | ||
899 | break; | ||
900 | case 16: | ||
901 | args.v3.ucBitPerColor = PANEL_16BIT_PER_COLOR; | ||
902 | break; | ||
903 | } | ||
904 | } else { | ||
905 | if ((args.v1.ucEncoderMode == ATOM_ENCODER_MODE_DP) && (dp_clock == 270000)) | ||
906 | args.v1.ucConfig |= ATOM_ENCODER_CONFIG_DPLINKRATE_2_70GHZ; | ||
907 | switch (radeon_encoder->encoder_id) { | ||
908 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: | ||
909 | args.v1.ucConfig = ATOM_ENCODER_CONFIG_V2_TRANSMITTER1; | ||
910 | break; | ||
911 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: | ||
912 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: | ||
913 | args.v1.ucConfig = ATOM_ENCODER_CONFIG_V2_TRANSMITTER2; | ||
914 | break; | ||
915 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: | ||
916 | args.v1.ucConfig = ATOM_ENCODER_CONFIG_V2_TRANSMITTER3; | ||
917 | break; | ||
918 | } | ||
919 | if (dig->linkb) | ||
920 | args.v1.ucConfig |= ATOM_ENCODER_CONFIG_LINKB; | ||
921 | else | ||
922 | args.v1.ucConfig |= ATOM_ENCODER_CONFIG_LINKA; | ||
923 | } | ||
924 | |||
925 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); | ||
926 | |||
927 | } | ||
928 | |||
929 | union dig_transmitter_control { | ||
930 | DIG_TRANSMITTER_CONTROL_PS_ALLOCATION v1; | ||
931 | DIG_TRANSMITTER_CONTROL_PARAMETERS_V2 v2; | ||
932 | DIG_TRANSMITTER_CONTROL_PARAMETERS_V3 v3; | ||
933 | DIG_TRANSMITTER_CONTROL_PARAMETERS_V4 v4; | ||
934 | }; | ||
935 | |||
936 | void | ||
937 | atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t lane_num, uint8_t lane_set) | ||
938 | { | ||
939 | struct drm_device *dev = encoder->dev; | ||
940 | struct radeon_device *rdev = dev->dev_private; | ||
941 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
942 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; | ||
943 | struct drm_connector *connector; | ||
944 | union dig_transmitter_control args; | ||
945 | int index = 0; | ||
946 | uint8_t frev, crev; | ||
947 | bool is_dp = false; | ||
948 | int pll_id = 0; | ||
949 | int dp_clock = 0; | ||
950 | int dp_lane_count = 0; | ||
951 | int connector_object_id = 0; | ||
952 | int igp_lane_info = 0; | ||
953 | int dig_encoder = dig->dig_encoder; | ||
954 | |||
955 | if (action == ATOM_TRANSMITTER_ACTION_INIT) { | ||
956 | connector = radeon_get_connector_for_encoder_init(encoder); | ||
957 | /* just needed to avoid bailing in the encoder check. the encoder | ||
958 | * isn't used for init | ||
959 | */ | ||
960 | dig_encoder = 0; | ||
961 | } else | ||
962 | connector = radeon_get_connector_for_encoder(encoder); | ||
963 | |||
964 | if (connector) { | ||
965 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | ||
966 | struct radeon_connector_atom_dig *dig_connector = | ||
967 | radeon_connector->con_priv; | ||
968 | |||
969 | dp_clock = dig_connector->dp_clock; | ||
970 | dp_lane_count = dig_connector->dp_lane_count; | ||
971 | connector_object_id = | ||
972 | (radeon_connector->connector_object_id & OBJECT_ID_MASK) >> OBJECT_ID_SHIFT; | ||
973 | igp_lane_info = dig_connector->igp_lane_info; | ||
974 | } | ||
975 | |||
976 | /* no dig encoder assigned */ | ||
977 | if (dig_encoder == -1) | ||
978 | return; | ||
979 | |||
980 | if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_DP) | ||
981 | is_dp = true; | ||
982 | |||
983 | memset(&args, 0, sizeof(args)); | ||
984 | |||
985 | switch (radeon_encoder->encoder_id) { | ||
986 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1: | ||
987 | index = GetIndexIntoMasterTable(COMMAND, DVOOutputControl); | ||
988 | break; | ||
989 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: | ||
990 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: | ||
991 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: | ||
992 | index = GetIndexIntoMasterTable(COMMAND, UNIPHYTransmitterControl); | ||
993 | break; | ||
994 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: | ||
995 | index = GetIndexIntoMasterTable(COMMAND, LVTMATransmitterControl); | ||
996 | break; | ||
997 | } | ||
998 | |||
999 | if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev)) | ||
1000 | return; | ||
1001 | |||
1002 | args.v1.ucAction = action; | ||
1003 | if (action == ATOM_TRANSMITTER_ACTION_INIT) { | ||
1004 | args.v1.usInitInfo = cpu_to_le16(connector_object_id); | ||
1005 | } else if (action == ATOM_TRANSMITTER_ACTION_SETUP_VSEMPH) { | ||
1006 | args.v1.asMode.ucLaneSel = lane_num; | ||
1007 | args.v1.asMode.ucLaneSet = lane_set; | ||
1008 | } else { | ||
1009 | if (is_dp) | ||
1010 | args.v1.usPixelClock = | ||
1011 | cpu_to_le16(dp_clock / 10); | ||
1012 | else if (radeon_encoder->pixel_clock > 165000) | ||
1013 | args.v1.usPixelClock = cpu_to_le16((radeon_encoder->pixel_clock / 2) / 10); | ||
1014 | else | ||
1015 | args.v1.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); | ||
1016 | } | ||
1017 | if (ASIC_IS_DCE4(rdev)) { | ||
1018 | if (is_dp) | ||
1019 | args.v3.ucLaneNum = dp_lane_count; | ||
1020 | else if (radeon_encoder->pixel_clock > 165000) | ||
1021 | args.v3.ucLaneNum = 8; | ||
1022 | else | ||
1023 | args.v3.ucLaneNum = 4; | ||
1024 | |||
1025 | if (dig->linkb) | ||
1026 | args.v3.acConfig.ucLinkSel = 1; | ||
1027 | if (dig_encoder & 1) | ||
1028 | args.v3.acConfig.ucEncoderSel = 1; | ||
1029 | |||
1030 | /* Select the PLL for the PHY | ||
1031 | * DP PHY should be clocked from external src if there is | ||
1032 | * one. | ||
1033 | */ | ||
1034 | if (encoder->crtc) { | ||
1035 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc); | ||
1036 | pll_id = radeon_crtc->pll_id; | ||
1037 | } | ||
1038 | |||
1039 | if (ASIC_IS_DCE5(rdev)) { | ||
1040 | /* On DCE5 DCPLL usually generates the DP ref clock */ | ||
1041 | if (is_dp) { | ||
1042 | if (rdev->clock.dp_extclk) | ||
1043 | args.v4.acConfig.ucRefClkSource = ENCODER_REFCLK_SRC_EXTCLK; | ||
1044 | else | ||
1045 | args.v4.acConfig.ucRefClkSource = ENCODER_REFCLK_SRC_DCPLL; | ||
1046 | } else | ||
1047 | args.v4.acConfig.ucRefClkSource = pll_id; | ||
1048 | } else { | ||
1049 | /* On DCE4, if there is an external clock, it generates the DP ref clock */ | ||
1050 | if (is_dp && rdev->clock.dp_extclk) | ||
1051 | args.v3.acConfig.ucRefClkSource = 2; /* external src */ | ||
1052 | else | ||
1053 | args.v3.acConfig.ucRefClkSource = pll_id; | ||
1054 | } | ||
1055 | |||
1056 | switch (radeon_encoder->encoder_id) { | ||
1057 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: | ||
1058 | args.v3.acConfig.ucTransmitterSel = 0; | ||
1059 | break; | ||
1060 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: | ||
1061 | args.v3.acConfig.ucTransmitterSel = 1; | ||
1062 | break; | ||
1063 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: | ||
1064 | args.v3.acConfig.ucTransmitterSel = 2; | ||
1065 | break; | ||
1066 | } | ||
1067 | |||
1068 | if (is_dp) | ||
1069 | args.v3.acConfig.fCoherentMode = 1; /* DP requires coherent */ | ||
1070 | else if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) { | ||
1071 | if (dig->coherent_mode) | ||
1072 | args.v3.acConfig.fCoherentMode = 1; | ||
1073 | if (radeon_encoder->pixel_clock > 165000) | ||
1074 | args.v3.acConfig.fDualLinkConnector = 1; | ||
1075 | } | ||
1076 | } else if (ASIC_IS_DCE32(rdev)) { | ||
1077 | args.v2.acConfig.ucEncoderSel = dig_encoder; | ||
1078 | if (dig->linkb) | ||
1079 | args.v2.acConfig.ucLinkSel = 1; | ||
1080 | |||
1081 | switch (radeon_encoder->encoder_id) { | ||
1082 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: | ||
1083 | args.v2.acConfig.ucTransmitterSel = 0; | ||
1084 | break; | ||
1085 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: | ||
1086 | args.v2.acConfig.ucTransmitterSel = 1; | ||
1087 | break; | ||
1088 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: | ||
1089 | args.v2.acConfig.ucTransmitterSel = 2; | ||
1090 | break; | ||
1091 | } | ||
1092 | |||
1093 | if (is_dp) { | ||
1094 | args.v2.acConfig.fCoherentMode = 1; | ||
1095 | args.v2.acConfig.fDPConnector = 1; | ||
1096 | } else if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) { | ||
1097 | if (dig->coherent_mode) | ||
1098 | args.v2.acConfig.fCoherentMode = 1; | ||
1099 | if (radeon_encoder->pixel_clock > 165000) | ||
1100 | args.v2.acConfig.fDualLinkConnector = 1; | ||
1101 | } | ||
1102 | } else { | ||
1103 | args.v1.ucConfig = ATOM_TRANSMITTER_CONFIG_CLKSRC_PPLL; | ||
1104 | |||
1105 | if (dig_encoder) | ||
1106 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_DIG2_ENCODER; | ||
1107 | else | ||
1108 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_DIG1_ENCODER; | ||
1109 | |||
1110 | if ((rdev->flags & RADEON_IS_IGP) && | ||
1111 | (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_UNIPHY)) { | ||
1112 | if (is_dp || (radeon_encoder->pixel_clock <= 165000)) { | ||
1113 | if (igp_lane_info & 0x1) | ||
1114 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_0_3; | ||
1115 | else if (igp_lane_info & 0x2) | ||
1116 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_4_7; | ||
1117 | else if (igp_lane_info & 0x4) | ||
1118 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_8_11; | ||
1119 | else if (igp_lane_info & 0x8) | ||
1120 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_12_15; | ||
1121 | } else { | ||
1122 | if (igp_lane_info & 0x3) | ||
1123 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_0_7; | ||
1124 | else if (igp_lane_info & 0xc) | ||
1125 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_8_15; | ||
1126 | } | ||
1127 | } | ||
1128 | |||
1129 | if (dig->linkb) | ||
1130 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKB; | ||
1131 | else | ||
1132 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKA; | ||
1133 | |||
1134 | if (is_dp) | ||
1135 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_COHERENT; | ||
1136 | else if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) { | ||
1137 | if (dig->coherent_mode) | ||
1138 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_COHERENT; | ||
1139 | if (radeon_encoder->pixel_clock > 165000) | ||
1140 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_8LANE_LINK; | ||
1141 | } | ||
1142 | } | ||
1143 | |||
1144 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); | ||
1145 | } | ||
1146 | |||
1147 | bool | ||
1148 | atombios_set_edp_panel_power(struct drm_connector *connector, int action) | ||
1149 | { | ||
1150 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | ||
1151 | struct drm_device *dev = radeon_connector->base.dev; | ||
1152 | struct radeon_device *rdev = dev->dev_private; | ||
1153 | union dig_transmitter_control args; | ||
1154 | int index = GetIndexIntoMasterTable(COMMAND, UNIPHYTransmitterControl); | ||
1155 | uint8_t frev, crev; | ||
1156 | |||
1157 | if (connector->connector_type != DRM_MODE_CONNECTOR_eDP) | ||
1158 | goto done; | ||
1159 | |||
1160 | if (!ASIC_IS_DCE4(rdev)) | ||
1161 | goto done; | ||
1162 | |||
1163 | if ((action != ATOM_TRANSMITTER_ACTION_POWER_ON) && | ||
1164 | (action != ATOM_TRANSMITTER_ACTION_POWER_OFF)) | ||
1165 | goto done; | ||
1166 | |||
1167 | if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev)) | ||
1168 | goto done; | ||
1169 | |||
1170 | memset(&args, 0, sizeof(args)); | ||
1171 | |||
1172 | args.v1.ucAction = action; | ||
1173 | |||
1174 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); | ||
1175 | |||
1176 | /* wait for the panel to power up */ | ||
1177 | if (action == ATOM_TRANSMITTER_ACTION_POWER_ON) { | ||
1178 | int i; | ||
1179 | |||
1180 | for (i = 0; i < 300; i++) { | ||
1181 | if (radeon_hpd_sense(rdev, radeon_connector->hpd.hpd)) | ||
1182 | return true; | ||
1183 | mdelay(1); | ||
1184 | } | ||
1185 | return false; | ||
1186 | } | ||
1187 | done: | ||
1188 | return true; | ||
1189 | } | ||
1190 | |||
1191 | union external_encoder_control { | ||
1192 | EXTERNAL_ENCODER_CONTROL_PS_ALLOCATION v1; | ||
1193 | EXTERNAL_ENCODER_CONTROL_PS_ALLOCATION_V3 v3; | ||
1194 | }; | ||
1195 | |||
1196 | static void | ||
1197 | atombios_external_encoder_setup(struct drm_encoder *encoder, | ||
1198 | struct drm_encoder *ext_encoder, | ||
1199 | int action) | ||
1200 | { | ||
1201 | struct drm_device *dev = encoder->dev; | ||
1202 | struct radeon_device *rdev = dev->dev_private; | ||
1203 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
1204 | struct radeon_encoder *ext_radeon_encoder = to_radeon_encoder(ext_encoder); | ||
1205 | union external_encoder_control args; | ||
1206 | struct drm_connector *connector; | ||
1207 | int index = GetIndexIntoMasterTable(COMMAND, ExternalEncoderControl); | ||
1208 | u8 frev, crev; | ||
1209 | int dp_clock = 0; | ||
1210 | int dp_lane_count = 0; | ||
1211 | int connector_object_id = 0; | ||
1212 | u32 ext_enum = (ext_radeon_encoder->encoder_enum & ENUM_ID_MASK) >> ENUM_ID_SHIFT; | ||
1213 | int bpc = 8; | ||
1214 | |||
1215 | if (action == EXTERNAL_ENCODER_ACTION_V3_ENCODER_INIT) | ||
1216 | connector = radeon_get_connector_for_encoder_init(encoder); | ||
1217 | else | ||
1218 | connector = radeon_get_connector_for_encoder(encoder); | ||
1219 | |||
1220 | if (connector) { | ||
1221 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | ||
1222 | struct radeon_connector_atom_dig *dig_connector = | ||
1223 | radeon_connector->con_priv; | ||
1224 | |||
1225 | dp_clock = dig_connector->dp_clock; | ||
1226 | dp_lane_count = dig_connector->dp_lane_count; | ||
1227 | connector_object_id = | ||
1228 | (radeon_connector->connector_object_id & OBJECT_ID_MASK) >> OBJECT_ID_SHIFT; | ||
1229 | bpc = connector->display_info.bpc; | ||
1230 | } | ||
1231 | |||
1232 | memset(&args, 0, sizeof(args)); | ||
1233 | |||
1234 | if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev)) | ||
1235 | return; | ||
1236 | |||
1237 | switch (frev) { | ||
1238 | case 1: | ||
1239 | /* no params on frev 1 */ | ||
1240 | break; | ||
1241 | case 2: | ||
1242 | switch (crev) { | ||
1243 | case 1: | ||
1244 | case 2: | ||
1245 | args.v1.sDigEncoder.ucAction = action; | ||
1246 | args.v1.sDigEncoder.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); | ||
1247 | args.v1.sDigEncoder.ucEncoderMode = atombios_get_encoder_mode(encoder); | ||
1248 | |||
1249 | if (args.v1.sDigEncoder.ucEncoderMode == ATOM_ENCODER_MODE_DP) { | ||
1250 | if (dp_clock == 270000) | ||
1251 | args.v1.sDigEncoder.ucConfig |= ATOM_ENCODER_CONFIG_DPLINKRATE_2_70GHZ; | ||
1252 | args.v1.sDigEncoder.ucLaneNum = dp_lane_count; | ||
1253 | } else if (radeon_encoder->pixel_clock > 165000) | ||
1254 | args.v1.sDigEncoder.ucLaneNum = 8; | ||
1255 | else | ||
1256 | args.v1.sDigEncoder.ucLaneNum = 4; | ||
1257 | break; | ||
1258 | case 3: | ||
1259 | args.v3.sExtEncoder.ucAction = action; | ||
1260 | if (action == EXTERNAL_ENCODER_ACTION_V3_ENCODER_INIT) | ||
1261 | args.v3.sExtEncoder.usConnectorId = cpu_to_le16(connector_object_id); | ||
1262 | else | ||
1263 | args.v3.sExtEncoder.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); | ||
1264 | args.v3.sExtEncoder.ucEncoderMode = atombios_get_encoder_mode(encoder); | ||
1265 | |||
1266 | if (args.v3.sExtEncoder.ucEncoderMode == ATOM_ENCODER_MODE_DP) { | ||
1267 | if (dp_clock == 270000) | ||
1268 | args.v3.sExtEncoder.ucConfig |= EXTERNAL_ENCODER_CONFIG_V3_DPLINKRATE_2_70GHZ; | ||
1269 | else if (dp_clock == 540000) | ||
1270 | args.v3.sExtEncoder.ucConfig |= EXTERNAL_ENCODER_CONFIG_V3_DPLINKRATE_5_40GHZ; | ||
1271 | args.v3.sExtEncoder.ucLaneNum = dp_lane_count; | ||
1272 | } else if (radeon_encoder->pixel_clock > 165000) | ||
1273 | args.v3.sExtEncoder.ucLaneNum = 8; | ||
1274 | else | ||
1275 | args.v3.sExtEncoder.ucLaneNum = 4; | ||
1276 | switch (ext_enum) { | ||
1277 | case GRAPH_OBJECT_ENUM_ID1: | ||
1278 | args.v3.sExtEncoder.ucConfig |= EXTERNAL_ENCODER_CONFIG_V3_ENCODER1; | ||
1279 | break; | ||
1280 | case GRAPH_OBJECT_ENUM_ID2: | ||
1281 | args.v3.sExtEncoder.ucConfig |= EXTERNAL_ENCODER_CONFIG_V3_ENCODER2; | ||
1282 | break; | ||
1283 | case GRAPH_OBJECT_ENUM_ID3: | ||
1284 | args.v3.sExtEncoder.ucConfig |= EXTERNAL_ENCODER_CONFIG_V3_ENCODER3; | ||
1285 | break; | ||
1286 | } | ||
1287 | switch (bpc) { | ||
1288 | case 0: | ||
1289 | args.v3.sExtEncoder.ucBitPerColor = PANEL_BPC_UNDEFINE; | ||
1290 | break; | ||
1291 | case 6: | ||
1292 | args.v3.sExtEncoder.ucBitPerColor = PANEL_6BIT_PER_COLOR; | ||
1293 | break; | ||
1294 | case 8: | ||
1295 | default: | ||
1296 | args.v3.sExtEncoder.ucBitPerColor = PANEL_8BIT_PER_COLOR; | ||
1297 | break; | ||
1298 | case 10: | ||
1299 | args.v3.sExtEncoder.ucBitPerColor = PANEL_10BIT_PER_COLOR; | ||
1300 | break; | ||
1301 | case 12: | ||
1302 | args.v3.sExtEncoder.ucBitPerColor = PANEL_12BIT_PER_COLOR; | ||
1303 | break; | ||
1304 | case 16: | ||
1305 | args.v3.sExtEncoder.ucBitPerColor = PANEL_16BIT_PER_COLOR; | ||
1306 | break; | ||
1307 | } | ||
1308 | break; | ||
1309 | default: | ||
1310 | DRM_ERROR("Unknown table version: %d, %d\n", frev, crev); | ||
1311 | return; | ||
1312 | } | ||
1313 | break; | ||
1314 | default: | ||
1315 | DRM_ERROR("Unknown table version: %d, %d\n", frev, crev); | ||
1316 | return; | ||
1317 | } | ||
1318 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); | ||
1319 | } | ||
1320 | |||
1321 | static void | ||
1322 | atombios_yuv_setup(struct drm_encoder *encoder, bool enable) | ||
1323 | { | ||
1324 | struct drm_device *dev = encoder->dev; | ||
1325 | struct radeon_device *rdev = dev->dev_private; | ||
1326 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
1327 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc); | ||
1328 | ENABLE_YUV_PS_ALLOCATION args; | ||
1329 | int index = GetIndexIntoMasterTable(COMMAND, EnableYUV); | ||
1330 | uint32_t temp, reg; | ||
1331 | |||
1332 | memset(&args, 0, sizeof(args)); | ||
1333 | |||
1334 | if (rdev->family >= CHIP_R600) | ||
1335 | reg = R600_BIOS_3_SCRATCH; | ||
1336 | else | ||
1337 | reg = RADEON_BIOS_3_SCRATCH; | ||
1338 | |||
1339 | /* XXX: fix up scratch reg handling */ | ||
1340 | temp = RREG32(reg); | ||
1341 | if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT)) | ||
1342 | WREG32(reg, (ATOM_S3_TV1_ACTIVE | | ||
1343 | (radeon_crtc->crtc_id << 18))); | ||
1344 | else if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT)) | ||
1345 | WREG32(reg, (ATOM_S3_CV_ACTIVE | (radeon_crtc->crtc_id << 24))); | ||
1346 | else | ||
1347 | WREG32(reg, 0); | ||
1348 | |||
1349 | if (enable) | ||
1350 | args.ucEnable = ATOM_ENABLE; | ||
1351 | args.ucCRTC = radeon_crtc->crtc_id; | ||
1352 | |||
1353 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); | ||
1354 | |||
1355 | WREG32(reg, temp); | ||
1356 | } | ||
1357 | |||
1358 | static void | ||
1359 | radeon_atom_encoder_dpms(struct drm_encoder *encoder, int mode) | ||
1360 | { | ||
1361 | struct drm_device *dev = encoder->dev; | ||
1362 | struct radeon_device *rdev = dev->dev_private; | ||
1363 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
1364 | struct drm_encoder *ext_encoder = radeon_atom_get_external_encoder(encoder); | ||
1365 | DISPLAY_DEVICE_OUTPUT_CONTROL_PS_ALLOCATION args; | ||
1366 | int index = 0; | ||
1367 | bool is_dig = false; | ||
1368 | bool is_dce5_dac = false; | ||
1369 | bool is_dce5_dvo = false; | ||
1370 | |||
1371 | memset(&args, 0, sizeof(args)); | ||
1372 | |||
1373 | DRM_DEBUG_KMS("encoder dpms %d to mode %d, devices %08x, active_devices %08x\n", | ||
1374 | radeon_encoder->encoder_id, mode, radeon_encoder->devices, | ||
1375 | radeon_encoder->active_device); | ||
1376 | switch (radeon_encoder->encoder_id) { | ||
1377 | case ENCODER_OBJECT_ID_INTERNAL_TMDS1: | ||
1378 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1: | ||
1379 | index = GetIndexIntoMasterTable(COMMAND, TMDSAOutputControl); | ||
1380 | break; | ||
1381 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: | ||
1382 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: | ||
1383 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: | ||
1384 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: | ||
1385 | is_dig = true; | ||
1386 | break; | ||
1387 | case ENCODER_OBJECT_ID_INTERNAL_DVO1: | ||
1388 | case ENCODER_OBJECT_ID_INTERNAL_DDI: | ||
1389 | index = GetIndexIntoMasterTable(COMMAND, DVOOutputControl); | ||
1390 | break; | ||
1391 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1: | ||
1392 | if (ASIC_IS_DCE5(rdev)) | ||
1393 | is_dce5_dvo = true; | ||
1394 | else if (ASIC_IS_DCE3(rdev)) | ||
1395 | is_dig = true; | ||
1396 | else | ||
1397 | index = GetIndexIntoMasterTable(COMMAND, DVOOutputControl); | ||
1398 | break; | ||
1399 | case ENCODER_OBJECT_ID_INTERNAL_LVDS: | ||
1400 | index = GetIndexIntoMasterTable(COMMAND, LCD1OutputControl); | ||
1401 | break; | ||
1402 | case ENCODER_OBJECT_ID_INTERNAL_LVTM1: | ||
1403 | if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) | ||
1404 | index = GetIndexIntoMasterTable(COMMAND, LCD1OutputControl); | ||
1405 | else | ||
1406 | index = GetIndexIntoMasterTable(COMMAND, LVTMAOutputControl); | ||
1407 | break; | ||
1408 | case ENCODER_OBJECT_ID_INTERNAL_DAC1: | ||
1409 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1: | ||
1410 | if (ASIC_IS_DCE5(rdev)) | ||
1411 | is_dce5_dac = true; | ||
1412 | else { | ||
1413 | if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT)) | ||
1414 | index = GetIndexIntoMasterTable(COMMAND, TV1OutputControl); | ||
1415 | else if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT)) | ||
1416 | index = GetIndexIntoMasterTable(COMMAND, CV1OutputControl); | ||
1417 | else | ||
1418 | index = GetIndexIntoMasterTable(COMMAND, DAC1OutputControl); | ||
1419 | } | ||
1420 | break; | ||
1421 | case ENCODER_OBJECT_ID_INTERNAL_DAC2: | ||
1422 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2: | ||
1423 | if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT)) | ||
1424 | index = GetIndexIntoMasterTable(COMMAND, TV1OutputControl); | ||
1425 | else if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT)) | ||
1426 | index = GetIndexIntoMasterTable(COMMAND, CV1OutputControl); | ||
1427 | else | ||
1428 | index = GetIndexIntoMasterTable(COMMAND, DAC2OutputControl); | ||
1429 | break; | ||
1430 | } | ||
1431 | |||
1432 | if (is_dig) { | ||
1433 | switch (mode) { | ||
1434 | case DRM_MODE_DPMS_ON: | ||
1435 | /* some early dce3.2 boards have a bug in their transmitter control table */ | ||
1436 | if ((rdev->family == CHIP_RV710) || (rdev->family == CHIP_RV730)) | ||
1437 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0); | ||
1438 | else | ||
1439 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE_OUTPUT, 0, 0); | ||
1440 | if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_DP) { | ||
1441 | struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); | ||
1442 | |||
1443 | if (connector && | ||
1444 | (connector->connector_type == DRM_MODE_CONNECTOR_eDP)) { | ||
1445 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | ||
1446 | struct radeon_connector_atom_dig *radeon_dig_connector = | ||
1447 | radeon_connector->con_priv; | ||
1448 | atombios_set_edp_panel_power(connector, | ||
1449 | ATOM_TRANSMITTER_ACTION_POWER_ON); | ||
1450 | radeon_dig_connector->edp_on = true; | ||
1451 | } | ||
1452 | if (ASIC_IS_DCE4(rdev)) | ||
1453 | atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_VIDEO_OFF, 0); | ||
1454 | radeon_dp_link_train(encoder, connector); | ||
1455 | if (ASIC_IS_DCE4(rdev)) | ||
1456 | atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_VIDEO_ON, 0); | ||
1457 | } | ||
1458 | if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) | ||
1459 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_LCD_BLON, 0, 0); | ||
1460 | break; | ||
1461 | case DRM_MODE_DPMS_STANDBY: | ||
1462 | case DRM_MODE_DPMS_SUSPEND: | ||
1463 | case DRM_MODE_DPMS_OFF: | ||
1464 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE_OUTPUT, 0, 0); | ||
1465 | if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_DP) { | ||
1466 | struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); | ||
1467 | |||
1468 | if (ASIC_IS_DCE4(rdev)) | ||
1469 | atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_VIDEO_OFF, 0); | ||
1470 | if (connector && | ||
1471 | (connector->connector_type == DRM_MODE_CONNECTOR_eDP)) { | ||
1472 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | ||
1473 | struct radeon_connector_atom_dig *radeon_dig_connector = | ||
1474 | radeon_connector->con_priv; | ||
1475 | atombios_set_edp_panel_power(connector, | ||
1476 | ATOM_TRANSMITTER_ACTION_POWER_OFF); | ||
1477 | radeon_dig_connector->edp_on = false; | ||
1478 | } | ||
1479 | } | ||
1480 | if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) | ||
1481 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_LCD_BLOFF, 0, 0); | ||
1482 | break; | ||
1483 | } | ||
1484 | } else if (is_dce5_dac) { | ||
1485 | switch (mode) { | ||
1486 | case DRM_MODE_DPMS_ON: | ||
1487 | atombios_dac_setup(encoder, ATOM_ENABLE); | ||
1488 | break; | ||
1489 | case DRM_MODE_DPMS_STANDBY: | ||
1490 | case DRM_MODE_DPMS_SUSPEND: | ||
1491 | case DRM_MODE_DPMS_OFF: | ||
1492 | atombios_dac_setup(encoder, ATOM_DISABLE); | ||
1493 | break; | ||
1494 | } | ||
1495 | } else if (is_dce5_dvo) { | ||
1496 | switch (mode) { | ||
1497 | case DRM_MODE_DPMS_ON: | ||
1498 | atombios_dvo_setup(encoder, ATOM_ENABLE); | ||
1499 | break; | ||
1500 | case DRM_MODE_DPMS_STANDBY: | ||
1501 | case DRM_MODE_DPMS_SUSPEND: | ||
1502 | case DRM_MODE_DPMS_OFF: | ||
1503 | atombios_dvo_setup(encoder, ATOM_DISABLE); | ||
1504 | break; | ||
1505 | } | ||
1506 | } else { | ||
1507 | switch (mode) { | ||
1508 | case DRM_MODE_DPMS_ON: | ||
1509 | args.ucAction = ATOM_ENABLE; | ||
1510 | /* workaround for DVOOutputControl on some RS690 systems */ | ||
1511 | if (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_DDI) { | ||
1512 | u32 reg = RREG32(RADEON_BIOS_3_SCRATCH); | ||
1513 | WREG32(RADEON_BIOS_3_SCRATCH, reg & ~ATOM_S3_DFP2I_ACTIVE); | ||
1514 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); | ||
1515 | WREG32(RADEON_BIOS_3_SCRATCH, reg); | ||
1516 | } else | ||
1517 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); | ||
1518 | if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) { | ||
1519 | args.ucAction = ATOM_LCD_BLON; | ||
1520 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); | ||
1521 | } | ||
1522 | break; | ||
1523 | case DRM_MODE_DPMS_STANDBY: | ||
1524 | case DRM_MODE_DPMS_SUSPEND: | ||
1525 | case DRM_MODE_DPMS_OFF: | ||
1526 | args.ucAction = ATOM_DISABLE; | ||
1527 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); | ||
1528 | if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) { | ||
1529 | args.ucAction = ATOM_LCD_BLOFF; | ||
1530 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); | ||
1531 | } | ||
1532 | break; | ||
1533 | } | ||
1534 | } | ||
1535 | |||
1536 | if (ext_encoder) { | ||
1537 | switch (mode) { | ||
1538 | case DRM_MODE_DPMS_ON: | ||
1539 | default: | ||
1540 | if (ASIC_IS_DCE41(rdev)) { | ||
1541 | atombios_external_encoder_setup(encoder, ext_encoder, | ||
1542 | EXTERNAL_ENCODER_ACTION_V3_ENABLE_OUTPUT); | ||
1543 | atombios_external_encoder_setup(encoder, ext_encoder, | ||
1544 | EXTERNAL_ENCODER_ACTION_V3_ENCODER_BLANKING_OFF); | ||
1545 | } else | ||
1546 | atombios_external_encoder_setup(encoder, ext_encoder, ATOM_ENABLE); | ||
1547 | break; | ||
1548 | case DRM_MODE_DPMS_STANDBY: | ||
1549 | case DRM_MODE_DPMS_SUSPEND: | ||
1550 | case DRM_MODE_DPMS_OFF: | ||
1551 | if (ASIC_IS_DCE41(rdev)) { | ||
1552 | atombios_external_encoder_setup(encoder, ext_encoder, | ||
1553 | EXTERNAL_ENCODER_ACTION_V3_ENCODER_BLANKING); | ||
1554 | atombios_external_encoder_setup(encoder, ext_encoder, | ||
1555 | EXTERNAL_ENCODER_ACTION_V3_DISABLE_OUTPUT); | ||
1556 | } else | ||
1557 | atombios_external_encoder_setup(encoder, ext_encoder, ATOM_DISABLE); | ||
1558 | break; | ||
1559 | } | ||
1560 | } | ||
1561 | |||
1562 | radeon_atombios_encoder_dpms_scratch_regs(encoder, (mode == DRM_MODE_DPMS_ON) ? true : false); | ||
1563 | |||
1564 | } | ||
1565 | |||
1566 | union crtc_source_param { | ||
1567 | SELECT_CRTC_SOURCE_PS_ALLOCATION v1; | ||
1568 | SELECT_CRTC_SOURCE_PARAMETERS_V2 v2; | ||
1569 | }; | ||
1570 | |||
1571 | static void | ||
1572 | atombios_set_encoder_crtc_source(struct drm_encoder *encoder) | ||
1573 | { | ||
1574 | struct drm_device *dev = encoder->dev; | ||
1575 | struct radeon_device *rdev = dev->dev_private; | ||
1576 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
1577 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc); | ||
1578 | union crtc_source_param args; | ||
1579 | int index = GetIndexIntoMasterTable(COMMAND, SelectCRTC_Source); | ||
1580 | uint8_t frev, crev; | ||
1581 | struct radeon_encoder_atom_dig *dig; | ||
1582 | |||
1583 | memset(&args, 0, sizeof(args)); | ||
1584 | |||
1585 | if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev)) | ||
1586 | return; | ||
1587 | |||
1588 | switch (frev) { | ||
1589 | case 1: | ||
1590 | switch (crev) { | ||
1591 | case 1: | ||
1592 | default: | ||
1593 | if (ASIC_IS_AVIVO(rdev)) | ||
1594 | args.v1.ucCRTC = radeon_crtc->crtc_id; | ||
1595 | else { | ||
1596 | if (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_DAC1) { | ||
1597 | args.v1.ucCRTC = radeon_crtc->crtc_id; | ||
1598 | } else { | ||
1599 | args.v1.ucCRTC = radeon_crtc->crtc_id << 2; | ||
1600 | } | ||
1601 | } | ||
1602 | switch (radeon_encoder->encoder_id) { | ||
1603 | case ENCODER_OBJECT_ID_INTERNAL_TMDS1: | ||
1604 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1: | ||
1605 | args.v1.ucDevice = ATOM_DEVICE_DFP1_INDEX; | ||
1606 | break; | ||
1607 | case ENCODER_OBJECT_ID_INTERNAL_LVDS: | ||
1608 | case ENCODER_OBJECT_ID_INTERNAL_LVTM1: | ||
1609 | if (radeon_encoder->devices & ATOM_DEVICE_LCD1_SUPPORT) | ||
1610 | args.v1.ucDevice = ATOM_DEVICE_LCD1_INDEX; | ||
1611 | else | ||
1612 | args.v1.ucDevice = ATOM_DEVICE_DFP3_INDEX; | ||
1613 | break; | ||
1614 | case ENCODER_OBJECT_ID_INTERNAL_DVO1: | ||
1615 | case ENCODER_OBJECT_ID_INTERNAL_DDI: | ||
1616 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1: | ||
1617 | args.v1.ucDevice = ATOM_DEVICE_DFP2_INDEX; | ||
1618 | break; | ||
1619 | case ENCODER_OBJECT_ID_INTERNAL_DAC1: | ||
1620 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1: | ||
1621 | if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT)) | ||
1622 | args.v1.ucDevice = ATOM_DEVICE_TV1_INDEX; | ||
1623 | else if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT)) | ||
1624 | args.v1.ucDevice = ATOM_DEVICE_CV_INDEX; | ||
1625 | else | ||
1626 | args.v1.ucDevice = ATOM_DEVICE_CRT1_INDEX; | ||
1627 | break; | ||
1628 | case ENCODER_OBJECT_ID_INTERNAL_DAC2: | ||
1629 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2: | ||
1630 | if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT)) | ||
1631 | args.v1.ucDevice = ATOM_DEVICE_TV1_INDEX; | ||
1632 | else if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT)) | ||
1633 | args.v1.ucDevice = ATOM_DEVICE_CV_INDEX; | ||
1634 | else | ||
1635 | args.v1.ucDevice = ATOM_DEVICE_CRT2_INDEX; | ||
1636 | break; | ||
1637 | } | ||
1638 | break; | ||
1639 | case 2: | ||
1640 | args.v2.ucCRTC = radeon_crtc->crtc_id; | ||
1641 | if (radeon_encoder_is_dp_bridge(encoder)) { | ||
1642 | struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); | ||
1643 | |||
1644 | if (connector->connector_type == DRM_MODE_CONNECTOR_LVDS) | ||
1645 | args.v2.ucEncodeMode = ATOM_ENCODER_MODE_LVDS; | ||
1646 | else if (connector->connector_type == DRM_MODE_CONNECTOR_VGA) | ||
1647 | args.v2.ucEncodeMode = ATOM_ENCODER_MODE_CRT; | ||
1648 | else | ||
1649 | args.v2.ucEncodeMode = atombios_get_encoder_mode(encoder); | ||
1650 | } else | ||
1651 | args.v2.ucEncodeMode = atombios_get_encoder_mode(encoder); | ||
1652 | switch (radeon_encoder->encoder_id) { | ||
1653 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: | ||
1654 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: | ||
1655 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: | ||
1656 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: | ||
1657 | dig = radeon_encoder->enc_priv; | ||
1658 | switch (dig->dig_encoder) { | ||
1659 | case 0: | ||
1660 | args.v2.ucEncoderID = ASIC_INT_DIG1_ENCODER_ID; | ||
1661 | break; | ||
1662 | case 1: | ||
1663 | args.v2.ucEncoderID = ASIC_INT_DIG2_ENCODER_ID; | ||
1664 | break; | ||
1665 | case 2: | ||
1666 | args.v2.ucEncoderID = ASIC_INT_DIG3_ENCODER_ID; | ||
1667 | break; | ||
1668 | case 3: | ||
1669 | args.v2.ucEncoderID = ASIC_INT_DIG4_ENCODER_ID; | ||
1670 | break; | ||
1671 | case 4: | ||
1672 | args.v2.ucEncoderID = ASIC_INT_DIG5_ENCODER_ID; | ||
1673 | break; | ||
1674 | case 5: | ||
1675 | args.v2.ucEncoderID = ASIC_INT_DIG6_ENCODER_ID; | ||
1676 | break; | ||
1677 | } | ||
1678 | break; | ||
1679 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1: | ||
1680 | args.v2.ucEncoderID = ASIC_INT_DVO_ENCODER_ID; | ||
1681 | break; | ||
1682 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1: | ||
1683 | if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT)) | ||
1684 | args.v2.ucEncoderID = ASIC_INT_TV_ENCODER_ID; | ||
1685 | else if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT)) | ||
1686 | args.v2.ucEncoderID = ASIC_INT_TV_ENCODER_ID; | ||
1687 | else | ||
1688 | args.v2.ucEncoderID = ASIC_INT_DAC1_ENCODER_ID; | ||
1689 | break; | ||
1690 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2: | ||
1691 | if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT)) | ||
1692 | args.v2.ucEncoderID = ASIC_INT_TV_ENCODER_ID; | ||
1693 | else if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT)) | ||
1694 | args.v2.ucEncoderID = ASIC_INT_TV_ENCODER_ID; | ||
1695 | else | ||
1696 | args.v2.ucEncoderID = ASIC_INT_DAC2_ENCODER_ID; | ||
1697 | break; | ||
1698 | } | ||
1699 | break; | ||
1700 | } | ||
1701 | break; | ||
1702 | default: | ||
1703 | DRM_ERROR("Unknown table version: %d, %d\n", frev, crev); | ||
1704 | return; | ||
1705 | } | ||
1706 | |||
1707 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); | ||
1708 | |||
1709 | /* update scratch regs with new routing */ | ||
1710 | radeon_atombios_encoder_crtc_scratch_regs(encoder, radeon_crtc->crtc_id); | ||
1711 | } | ||
1712 | |||
1713 | static void | ||
1714 | atombios_apply_encoder_quirks(struct drm_encoder *encoder, | ||
1715 | struct drm_display_mode *mode) | ||
1716 | { | ||
1717 | struct drm_device *dev = encoder->dev; | ||
1718 | struct radeon_device *rdev = dev->dev_private; | ||
1719 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
1720 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc); | ||
1721 | |||
1722 | /* Funky macbooks */ | ||
1723 | if ((dev->pdev->device == 0x71C5) && | ||
1724 | (dev->pdev->subsystem_vendor == 0x106b) && | ||
1725 | (dev->pdev->subsystem_device == 0x0080)) { | ||
1726 | if (radeon_encoder->devices & ATOM_DEVICE_LCD1_SUPPORT) { | ||
1727 | uint32_t lvtma_bit_depth_control = RREG32(AVIVO_LVTMA_BIT_DEPTH_CONTROL); | ||
1728 | |||
1729 | lvtma_bit_depth_control &= ~AVIVO_LVTMA_BIT_DEPTH_CONTROL_TRUNCATE_EN; | ||
1730 | lvtma_bit_depth_control &= ~AVIVO_LVTMA_BIT_DEPTH_CONTROL_SPATIAL_DITHER_EN; | ||
1731 | |||
1732 | WREG32(AVIVO_LVTMA_BIT_DEPTH_CONTROL, lvtma_bit_depth_control); | ||
1733 | } | ||
1734 | } | ||
1735 | |||
1736 | /* set scaler clears this on some chips */ | ||
1737 | if (ASIC_IS_AVIVO(rdev) && | ||
1738 | (!(radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT)))) { | ||
1739 | if (ASIC_IS_DCE4(rdev)) { | ||
1740 | if (mode->flags & DRM_MODE_FLAG_INTERLACE) | ||
1741 | WREG32(EVERGREEN_DATA_FORMAT + radeon_crtc->crtc_offset, | ||
1742 | EVERGREEN_INTERLEAVE_EN); | ||
1743 | else | ||
1744 | WREG32(EVERGREEN_DATA_FORMAT + radeon_crtc->crtc_offset, 0); | ||
1745 | } else { | ||
1746 | if (mode->flags & DRM_MODE_FLAG_INTERLACE) | ||
1747 | WREG32(AVIVO_D1MODE_DATA_FORMAT + radeon_crtc->crtc_offset, | ||
1748 | AVIVO_D1MODE_INTERLEAVE_EN); | ||
1749 | else | ||
1750 | WREG32(AVIVO_D1MODE_DATA_FORMAT + radeon_crtc->crtc_offset, 0); | ||
1751 | } | ||
1752 | } | ||
1753 | } | ||
1754 | |||
1755 | static int radeon_atom_pick_dig_encoder(struct drm_encoder *encoder) | ||
1756 | { | ||
1757 | struct drm_device *dev = encoder->dev; | ||
1758 | struct radeon_device *rdev = dev->dev_private; | ||
1759 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc); | ||
1760 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
1761 | struct drm_encoder *test_encoder; | ||
1762 | struct radeon_encoder_atom_dig *dig; | ||
1763 | uint32_t dig_enc_in_use = 0; | ||
1764 | |||
1765 | /* DCE4/5 */ | ||
1766 | if (ASIC_IS_DCE4(rdev)) { | ||
1767 | dig = radeon_encoder->enc_priv; | ||
1768 | if (ASIC_IS_DCE41(rdev)) { | ||
1769 | /* ontario follows DCE4 */ | ||
1770 | if (rdev->family == CHIP_PALM) { | ||
1771 | if (dig->linkb) | ||
1772 | return 1; | ||
1773 | else | ||
1774 | return 0; | ||
1775 | } else | ||
1776 | /* llano follows DCE3.2 */ | ||
1777 | return radeon_crtc->crtc_id; | ||
1778 | } else { | ||
1779 | switch (radeon_encoder->encoder_id) { | ||
1780 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: | ||
1781 | if (dig->linkb) | ||
1782 | return 1; | ||
1783 | else | ||
1784 | return 0; | ||
1785 | break; | ||
1786 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: | ||
1787 | if (dig->linkb) | ||
1788 | return 3; | ||
1789 | else | ||
1790 | return 2; | ||
1791 | break; | ||
1792 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: | ||
1793 | if (dig->linkb) | ||
1794 | return 5; | ||
1795 | else | ||
1796 | return 4; | ||
1797 | break; | ||
1798 | } | ||
1799 | } | ||
1800 | } | ||
1801 | |||
1802 | /* on DCE32 and encoder can driver any block so just crtc id */ | ||
1803 | if (ASIC_IS_DCE32(rdev)) { | ||
1804 | return radeon_crtc->crtc_id; | ||
1805 | } | ||
1806 | |||
1807 | /* on DCE3 - LVTMA can only be driven by DIGB */ | ||
1808 | list_for_each_entry(test_encoder, &dev->mode_config.encoder_list, head) { | ||
1809 | struct radeon_encoder *radeon_test_encoder; | ||
1810 | |||
1811 | if (encoder == test_encoder) | ||
1812 | continue; | ||
1813 | |||
1814 | if (!radeon_encoder_is_digital(test_encoder)) | ||
1815 | continue; | ||
1816 | |||
1817 | radeon_test_encoder = to_radeon_encoder(test_encoder); | ||
1818 | dig = radeon_test_encoder->enc_priv; | ||
1819 | |||
1820 | if (dig->dig_encoder >= 0) | ||
1821 | dig_enc_in_use |= (1 << dig->dig_encoder); | ||
1822 | } | ||
1823 | |||
1824 | if (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA) { | ||
1825 | if (dig_enc_in_use & 0x2) | ||
1826 | DRM_ERROR("LVDS required digital encoder 2 but it was in use - stealing\n"); | ||
1827 | return 1; | ||
1828 | } | ||
1829 | if (!(dig_enc_in_use & 1)) | ||
1830 | return 0; | ||
1831 | return 1; | ||
1832 | } | ||
1833 | |||
1834 | /* This only needs to be called once at startup */ | ||
1835 | void | ||
1836 | radeon_atom_encoder_init(struct radeon_device *rdev) | ||
1837 | { | ||
1838 | struct drm_device *dev = rdev->ddev; | ||
1839 | struct drm_encoder *encoder; | ||
1840 | |||
1841 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { | ||
1842 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
1843 | struct drm_encoder *ext_encoder = radeon_atom_get_external_encoder(encoder); | ||
1844 | |||
1845 | switch (radeon_encoder->encoder_id) { | ||
1846 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: | ||
1847 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: | ||
1848 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: | ||
1849 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: | ||
1850 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_INIT, 0, 0); | ||
1851 | break; | ||
1852 | default: | ||
1853 | break; | ||
1854 | } | ||
1855 | |||
1856 | if (ext_encoder && ASIC_IS_DCE41(rdev)) | ||
1857 | atombios_external_encoder_setup(encoder, ext_encoder, | ||
1858 | EXTERNAL_ENCODER_ACTION_V3_ENCODER_INIT); | ||
1859 | } | ||
1860 | } | ||
1861 | |||
1862 | static void | ||
1863 | radeon_atom_encoder_mode_set(struct drm_encoder *encoder, | ||
1864 | struct drm_display_mode *mode, | ||
1865 | struct drm_display_mode *adjusted_mode) | ||
1866 | { | ||
1867 | struct drm_device *dev = encoder->dev; | ||
1868 | struct radeon_device *rdev = dev->dev_private; | ||
1869 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
1870 | struct drm_encoder *ext_encoder = radeon_atom_get_external_encoder(encoder); | ||
1871 | |||
1872 | radeon_encoder->pixel_clock = adjusted_mode->clock; | ||
1873 | |||
1874 | if (ASIC_IS_AVIVO(rdev) && !ASIC_IS_DCE4(rdev)) { | ||
1875 | if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT | ATOM_DEVICE_TV_SUPPORT)) | ||
1876 | atombios_yuv_setup(encoder, true); | ||
1877 | else | ||
1878 | atombios_yuv_setup(encoder, false); | ||
1879 | } | ||
1880 | |||
1881 | switch (radeon_encoder->encoder_id) { | ||
1882 | case ENCODER_OBJECT_ID_INTERNAL_TMDS1: | ||
1883 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1: | ||
1884 | case ENCODER_OBJECT_ID_INTERNAL_LVDS: | ||
1885 | case ENCODER_OBJECT_ID_INTERNAL_LVTM1: | ||
1886 | atombios_digital_setup(encoder, PANEL_ENCODER_ACTION_ENABLE); | ||
1887 | break; | ||
1888 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: | ||
1889 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: | ||
1890 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: | ||
1891 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: | ||
1892 | if (ASIC_IS_DCE4(rdev)) { | ||
1893 | /* disable the transmitter */ | ||
1894 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0); | ||
1895 | /* setup and enable the encoder */ | ||
1896 | atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_SETUP, 0); | ||
1897 | |||
1898 | /* enable the transmitter */ | ||
1899 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0); | ||
1900 | } else { | ||
1901 | /* disable the encoder and transmitter */ | ||
1902 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0); | ||
1903 | atombios_dig_encoder_setup(encoder, ATOM_DISABLE, 0); | ||
1904 | |||
1905 | /* setup and enable the encoder and transmitter */ | ||
1906 | atombios_dig_encoder_setup(encoder, ATOM_ENABLE, 0); | ||
1907 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_SETUP, 0, 0); | ||
1908 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0); | ||
1909 | } | ||
1910 | break; | ||
1911 | case ENCODER_OBJECT_ID_INTERNAL_DDI: | ||
1912 | case ENCODER_OBJECT_ID_INTERNAL_DVO1: | ||
1913 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1: | ||
1914 | atombios_dvo_setup(encoder, ATOM_ENABLE); | ||
1915 | break; | ||
1916 | case ENCODER_OBJECT_ID_INTERNAL_DAC1: | ||
1917 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1: | ||
1918 | case ENCODER_OBJECT_ID_INTERNAL_DAC2: | ||
1919 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2: | ||
1920 | atombios_dac_setup(encoder, ATOM_ENABLE); | ||
1921 | if (radeon_encoder->devices & (ATOM_DEVICE_TV_SUPPORT | ATOM_DEVICE_CV_SUPPORT)) { | ||
1922 | if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT | ATOM_DEVICE_CV_SUPPORT)) | ||
1923 | atombios_tv_setup(encoder, ATOM_ENABLE); | ||
1924 | else | ||
1925 | atombios_tv_setup(encoder, ATOM_DISABLE); | ||
1926 | } | ||
1927 | break; | ||
1928 | } | ||
1929 | |||
1930 | if (ext_encoder) { | ||
1931 | if (ASIC_IS_DCE41(rdev)) | ||
1932 | atombios_external_encoder_setup(encoder, ext_encoder, | ||
1933 | EXTERNAL_ENCODER_ACTION_V3_ENCODER_SETUP); | ||
1934 | else | ||
1935 | atombios_external_encoder_setup(encoder, ext_encoder, ATOM_ENABLE); | ||
1936 | } | ||
1937 | |||
1938 | atombios_apply_encoder_quirks(encoder, adjusted_mode); | ||
1939 | |||
1940 | if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_HDMI) { | ||
1941 | r600_hdmi_enable(encoder); | ||
1942 | r600_hdmi_setmode(encoder, adjusted_mode); | ||
1943 | } | ||
1944 | } | ||
1945 | |||
1946 | static bool | ||
1947 | atombios_dac_load_detect(struct drm_encoder *encoder, struct drm_connector *connector) | ||
1948 | { | ||
1949 | struct drm_device *dev = encoder->dev; | ||
1950 | struct radeon_device *rdev = dev->dev_private; | ||
1951 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
1952 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | ||
1953 | |||
1954 | if (radeon_encoder->devices & (ATOM_DEVICE_TV_SUPPORT | | ||
1955 | ATOM_DEVICE_CV_SUPPORT | | ||
1956 | ATOM_DEVICE_CRT_SUPPORT)) { | ||
1957 | DAC_LOAD_DETECTION_PS_ALLOCATION args; | ||
1958 | int index = GetIndexIntoMasterTable(COMMAND, DAC_LoadDetection); | ||
1959 | uint8_t frev, crev; | ||
1960 | |||
1961 | memset(&args, 0, sizeof(args)); | ||
1962 | |||
1963 | if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev)) | ||
1964 | return false; | ||
1965 | |||
1966 | args.sDacload.ucMisc = 0; | ||
1967 | |||
1968 | if ((radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_DAC1) || | ||
1969 | (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1)) | ||
1970 | args.sDacload.ucDacType = ATOM_DAC_A; | ||
1971 | else | ||
1972 | args.sDacload.ucDacType = ATOM_DAC_B; | ||
1973 | |||
1974 | if (radeon_connector->devices & ATOM_DEVICE_CRT1_SUPPORT) | ||
1975 | args.sDacload.usDeviceID = cpu_to_le16(ATOM_DEVICE_CRT1_SUPPORT); | ||
1976 | else if (radeon_connector->devices & ATOM_DEVICE_CRT2_SUPPORT) | ||
1977 | args.sDacload.usDeviceID = cpu_to_le16(ATOM_DEVICE_CRT2_SUPPORT); | ||
1978 | else if (radeon_connector->devices & ATOM_DEVICE_CV_SUPPORT) { | ||
1979 | args.sDacload.usDeviceID = cpu_to_le16(ATOM_DEVICE_CV_SUPPORT); | ||
1980 | if (crev >= 3) | ||
1981 | args.sDacload.ucMisc = DAC_LOAD_MISC_YPrPb; | ||
1982 | } else if (radeon_connector->devices & ATOM_DEVICE_TV1_SUPPORT) { | ||
1983 | args.sDacload.usDeviceID = cpu_to_le16(ATOM_DEVICE_TV1_SUPPORT); | ||
1984 | if (crev >= 3) | ||
1985 | args.sDacload.ucMisc = DAC_LOAD_MISC_YPrPb; | ||
1986 | } | ||
1987 | |||
1988 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); | ||
1989 | |||
1990 | return true; | ||
1991 | } else | ||
1992 | return false; | ||
1993 | } | ||
1994 | |||
1995 | static enum drm_connector_status | ||
1996 | radeon_atom_dac_detect(struct drm_encoder *encoder, struct drm_connector *connector) | ||
1997 | { | ||
1998 | struct drm_device *dev = encoder->dev; | ||
1999 | struct radeon_device *rdev = dev->dev_private; | ||
2000 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
2001 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | ||
2002 | uint32_t bios_0_scratch; | ||
2003 | |||
2004 | if (!atombios_dac_load_detect(encoder, connector)) { | ||
2005 | DRM_DEBUG_KMS("detect returned false \n"); | ||
2006 | return connector_status_unknown; | ||
2007 | } | ||
2008 | |||
2009 | if (rdev->family >= CHIP_R600) | ||
2010 | bios_0_scratch = RREG32(R600_BIOS_0_SCRATCH); | ||
2011 | else | ||
2012 | bios_0_scratch = RREG32(RADEON_BIOS_0_SCRATCH); | ||
2013 | |||
2014 | DRM_DEBUG_KMS("Bios 0 scratch %x %08x\n", bios_0_scratch, radeon_encoder->devices); | ||
2015 | if (radeon_connector->devices & ATOM_DEVICE_CRT1_SUPPORT) { | ||
2016 | if (bios_0_scratch & ATOM_S0_CRT1_MASK) | ||
2017 | return connector_status_connected; | ||
2018 | } | ||
2019 | if (radeon_connector->devices & ATOM_DEVICE_CRT2_SUPPORT) { | ||
2020 | if (bios_0_scratch & ATOM_S0_CRT2_MASK) | ||
2021 | return connector_status_connected; | ||
2022 | } | ||
2023 | if (radeon_connector->devices & ATOM_DEVICE_CV_SUPPORT) { | ||
2024 | if (bios_0_scratch & (ATOM_S0_CV_MASK|ATOM_S0_CV_MASK_A)) | ||
2025 | return connector_status_connected; | ||
2026 | } | ||
2027 | if (radeon_connector->devices & ATOM_DEVICE_TV1_SUPPORT) { | ||
2028 | if (bios_0_scratch & (ATOM_S0_TV1_COMPOSITE | ATOM_S0_TV1_COMPOSITE_A)) | ||
2029 | return connector_status_connected; /* CTV */ | ||
2030 | else if (bios_0_scratch & (ATOM_S0_TV1_SVIDEO | ATOM_S0_TV1_SVIDEO_A)) | ||
2031 | return connector_status_connected; /* STV */ | ||
2032 | } | ||
2033 | return connector_status_disconnected; | ||
2034 | } | ||
2035 | |||
2036 | static enum drm_connector_status | ||
2037 | radeon_atom_dig_detect(struct drm_encoder *encoder, struct drm_connector *connector) | ||
2038 | { | ||
2039 | struct drm_device *dev = encoder->dev; | ||
2040 | struct radeon_device *rdev = dev->dev_private; | ||
2041 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
2042 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | ||
2043 | struct drm_encoder *ext_encoder = radeon_atom_get_external_encoder(encoder); | ||
2044 | u32 bios_0_scratch; | ||
2045 | |||
2046 | if (!ASIC_IS_DCE4(rdev)) | ||
2047 | return connector_status_unknown; | ||
2048 | |||
2049 | if (!ext_encoder) | ||
2050 | return connector_status_unknown; | ||
2051 | |||
2052 | if ((radeon_connector->devices & ATOM_DEVICE_CRT_SUPPORT) == 0) | ||
2053 | return connector_status_unknown; | ||
2054 | |||
2055 | /* load detect on the dp bridge */ | ||
2056 | atombios_external_encoder_setup(encoder, ext_encoder, | ||
2057 | EXTERNAL_ENCODER_ACTION_V3_DACLOAD_DETECTION); | ||
2058 | |||
2059 | bios_0_scratch = RREG32(R600_BIOS_0_SCRATCH); | ||
2060 | |||
2061 | DRM_DEBUG_KMS("Bios 0 scratch %x %08x\n", bios_0_scratch, radeon_encoder->devices); | ||
2062 | if (radeon_connector->devices & ATOM_DEVICE_CRT1_SUPPORT) { | ||
2063 | if (bios_0_scratch & ATOM_S0_CRT1_MASK) | ||
2064 | return connector_status_connected; | ||
2065 | } | ||
2066 | if (radeon_connector->devices & ATOM_DEVICE_CRT2_SUPPORT) { | ||
2067 | if (bios_0_scratch & ATOM_S0_CRT2_MASK) | ||
2068 | return connector_status_connected; | ||
2069 | } | ||
2070 | if (radeon_connector->devices & ATOM_DEVICE_CV_SUPPORT) { | ||
2071 | if (bios_0_scratch & (ATOM_S0_CV_MASK|ATOM_S0_CV_MASK_A)) | ||
2072 | return connector_status_connected; | ||
2073 | } | ||
2074 | if (radeon_connector->devices & ATOM_DEVICE_TV1_SUPPORT) { | ||
2075 | if (bios_0_scratch & (ATOM_S0_TV1_COMPOSITE | ATOM_S0_TV1_COMPOSITE_A)) | ||
2076 | return connector_status_connected; /* CTV */ | ||
2077 | else if (bios_0_scratch & (ATOM_S0_TV1_SVIDEO | ATOM_S0_TV1_SVIDEO_A)) | ||
2078 | return connector_status_connected; /* STV */ | ||
2079 | } | ||
2080 | return connector_status_disconnected; | ||
2081 | } | ||
2082 | |||
2083 | void | ||
2084 | radeon_atom_ext_encoder_setup_ddc(struct drm_encoder *encoder) | ||
2085 | { | ||
2086 | struct drm_encoder *ext_encoder = radeon_atom_get_external_encoder(encoder); | ||
2087 | |||
2088 | if (ext_encoder) | ||
2089 | /* ddc_setup on the dp bridge */ | ||
2090 | atombios_external_encoder_setup(encoder, ext_encoder, | ||
2091 | EXTERNAL_ENCODER_ACTION_V3_DDC_SETUP); | ||
2092 | |||
2093 | } | ||
2094 | |||
2095 | static void radeon_atom_encoder_prepare(struct drm_encoder *encoder) | ||
2096 | { | ||
2097 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
2098 | struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); | ||
2099 | |||
2100 | if ((radeon_encoder->active_device & | ||
2101 | (ATOM_DEVICE_DFP_SUPPORT | ATOM_DEVICE_LCD_SUPPORT)) || | ||
2102 | radeon_encoder_is_dp_bridge(encoder)) { | ||
2103 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; | ||
2104 | if (dig) | ||
2105 | dig->dig_encoder = radeon_atom_pick_dig_encoder(encoder); | ||
2106 | } | ||
2107 | |||
2108 | radeon_atom_output_lock(encoder, true); | ||
2109 | radeon_atom_encoder_dpms(encoder, DRM_MODE_DPMS_OFF); | ||
2110 | |||
2111 | if (connector) { | ||
2112 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | ||
2113 | |||
2114 | /* select the clock/data port if it uses a router */ | ||
2115 | if (radeon_connector->router.cd_valid) | ||
2116 | radeon_router_select_cd_port(radeon_connector); | ||
2117 | |||
2118 | /* turn eDP panel on for mode set */ | ||
2119 | if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) | ||
2120 | atombios_set_edp_panel_power(connector, | ||
2121 | ATOM_TRANSMITTER_ACTION_POWER_ON); | ||
2122 | } | ||
2123 | |||
2124 | /* this is needed for the pll/ss setup to work correctly in some cases */ | ||
2125 | atombios_set_encoder_crtc_source(encoder); | ||
2126 | } | ||
2127 | |||
2128 | static void radeon_atom_encoder_commit(struct drm_encoder *encoder) | ||
2129 | { | ||
2130 | radeon_atom_encoder_dpms(encoder, DRM_MODE_DPMS_ON); | ||
2131 | radeon_atom_output_lock(encoder, false); | ||
2132 | } | ||
2133 | |||
2134 | static void radeon_atom_encoder_disable(struct drm_encoder *encoder) | ||
2135 | { | ||
2136 | struct drm_device *dev = encoder->dev; | ||
2137 | struct radeon_device *rdev = dev->dev_private; | ||
2138 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
2139 | struct radeon_encoder_atom_dig *dig; | ||
2140 | |||
2141 | /* check for pre-DCE3 cards with shared encoders; | ||
2142 | * can't really use the links individually, so don't disable | ||
2143 | * the encoder if it's in use by another connector | ||
2144 | */ | ||
2145 | if (!ASIC_IS_DCE3(rdev)) { | ||
2146 | struct drm_encoder *other_encoder; | ||
2147 | struct radeon_encoder *other_radeon_encoder; | ||
2148 | |||
2149 | list_for_each_entry(other_encoder, &dev->mode_config.encoder_list, head) { | ||
2150 | other_radeon_encoder = to_radeon_encoder(other_encoder); | ||
2151 | if ((radeon_encoder->encoder_id == other_radeon_encoder->encoder_id) && | ||
2152 | drm_helper_encoder_in_use(other_encoder)) | ||
2153 | goto disable_done; | ||
2154 | } | ||
2155 | } | ||
2156 | |||
2157 | radeon_atom_encoder_dpms(encoder, DRM_MODE_DPMS_OFF); | ||
2158 | |||
2159 | switch (radeon_encoder->encoder_id) { | ||
2160 | case ENCODER_OBJECT_ID_INTERNAL_TMDS1: | ||
2161 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1: | ||
2162 | case ENCODER_OBJECT_ID_INTERNAL_LVDS: | ||
2163 | case ENCODER_OBJECT_ID_INTERNAL_LVTM1: | ||
2164 | atombios_digital_setup(encoder, PANEL_ENCODER_ACTION_DISABLE); | ||
2165 | break; | ||
2166 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: | ||
2167 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: | ||
2168 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: | ||
2169 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: | ||
2170 | if (ASIC_IS_DCE4(rdev)) | ||
2171 | /* disable the transmitter */ | ||
2172 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0); | ||
2173 | else { | ||
2174 | /* disable the encoder and transmitter */ | ||
2175 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0); | ||
2176 | atombios_dig_encoder_setup(encoder, ATOM_DISABLE, 0); | ||
2177 | } | ||
2178 | break; | ||
2179 | case ENCODER_OBJECT_ID_INTERNAL_DDI: | ||
2180 | case ENCODER_OBJECT_ID_INTERNAL_DVO1: | ||
2181 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1: | ||
2182 | atombios_dvo_setup(encoder, ATOM_DISABLE); | ||
2183 | break; | ||
2184 | case ENCODER_OBJECT_ID_INTERNAL_DAC1: | ||
2185 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1: | ||
2186 | case ENCODER_OBJECT_ID_INTERNAL_DAC2: | ||
2187 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2: | ||
2188 | atombios_dac_setup(encoder, ATOM_DISABLE); | ||
2189 | if (radeon_encoder->devices & (ATOM_DEVICE_TV_SUPPORT | ATOM_DEVICE_CV_SUPPORT)) | ||
2190 | atombios_tv_setup(encoder, ATOM_DISABLE); | ||
2191 | break; | ||
2192 | } | ||
2193 | |||
2194 | disable_done: | ||
2195 | if (radeon_encoder_is_digital(encoder)) { | ||
2196 | if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_HDMI) | ||
2197 | r600_hdmi_disable(encoder); | ||
2198 | dig = radeon_encoder->enc_priv; | ||
2199 | dig->dig_encoder = -1; | ||
2200 | } | ||
2201 | radeon_encoder->active_device = 0; | ||
2202 | } | ||
2203 | |||
2204 | /* these are handled by the primary encoders */ | ||
2205 | static void radeon_atom_ext_prepare(struct drm_encoder *encoder) | ||
2206 | { | ||
2207 | |||
2208 | } | ||
2209 | |||
2210 | static void radeon_atom_ext_commit(struct drm_encoder *encoder) | ||
2211 | { | ||
2212 | |||
2213 | } | ||
2214 | |||
2215 | static void | ||
2216 | radeon_atom_ext_mode_set(struct drm_encoder *encoder, | ||
2217 | struct drm_display_mode *mode, | ||
2218 | struct drm_display_mode *adjusted_mode) | ||
2219 | { | ||
2220 | |||
2221 | } | ||
2222 | |||
2223 | static void radeon_atom_ext_disable(struct drm_encoder *encoder) | ||
2224 | { | ||
2225 | |||
2226 | } | ||
2227 | |||
2228 | static void | ||
2229 | radeon_atom_ext_dpms(struct drm_encoder *encoder, int mode) | ||
2230 | { | ||
2231 | |||
2232 | } | ||
2233 | |||
2234 | static bool radeon_atom_ext_mode_fixup(struct drm_encoder *encoder, | ||
2235 | struct drm_display_mode *mode, | ||
2236 | struct drm_display_mode *adjusted_mode) | ||
2237 | { | ||
2238 | return true; | ||
2239 | } | ||
2240 | |||
2241 | static const struct drm_encoder_helper_funcs radeon_atom_ext_helper_funcs = { | ||
2242 | .dpms = radeon_atom_ext_dpms, | ||
2243 | .mode_fixup = radeon_atom_ext_mode_fixup, | ||
2244 | .prepare = radeon_atom_ext_prepare, | ||
2245 | .mode_set = radeon_atom_ext_mode_set, | ||
2246 | .commit = radeon_atom_ext_commit, | ||
2247 | .disable = radeon_atom_ext_disable, | ||
2248 | /* no detect for TMDS/LVDS yet */ | ||
2249 | }; | ||
2250 | |||
2251 | static const struct drm_encoder_helper_funcs radeon_atom_dig_helper_funcs = { | ||
2252 | .dpms = radeon_atom_encoder_dpms, | ||
2253 | .mode_fixup = radeon_atom_mode_fixup, | ||
2254 | .prepare = radeon_atom_encoder_prepare, | ||
2255 | .mode_set = radeon_atom_encoder_mode_set, | ||
2256 | .commit = radeon_atom_encoder_commit, | ||
2257 | .disable = radeon_atom_encoder_disable, | ||
2258 | .detect = radeon_atom_dig_detect, | ||
2259 | }; | ||
2260 | |||
2261 | static const struct drm_encoder_helper_funcs radeon_atom_dac_helper_funcs = { | ||
2262 | .dpms = radeon_atom_encoder_dpms, | ||
2263 | .mode_fixup = radeon_atom_mode_fixup, | ||
2264 | .prepare = radeon_atom_encoder_prepare, | ||
2265 | .mode_set = radeon_atom_encoder_mode_set, | ||
2266 | .commit = radeon_atom_encoder_commit, | ||
2267 | .detect = radeon_atom_dac_detect, | ||
2268 | }; | ||
2269 | |||
2270 | void radeon_enc_destroy(struct drm_encoder *encoder) | ||
2271 | { | ||
2272 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
2273 | kfree(radeon_encoder->enc_priv); | ||
2274 | drm_encoder_cleanup(encoder); | ||
2275 | kfree(radeon_encoder); | ||
2276 | } | ||
2277 | |||
2278 | static const struct drm_encoder_funcs radeon_atom_enc_funcs = { | ||
2279 | .destroy = radeon_enc_destroy, | ||
2280 | }; | ||
2281 | |||
2282 | struct radeon_encoder_atom_dac * | ||
2283 | radeon_atombios_set_dac_info(struct radeon_encoder *radeon_encoder) | ||
2284 | { | ||
2285 | struct drm_device *dev = radeon_encoder->base.dev; | ||
2286 | struct radeon_device *rdev = dev->dev_private; | ||
2287 | struct radeon_encoder_atom_dac *dac = kzalloc(sizeof(struct radeon_encoder_atom_dac), GFP_KERNEL); | ||
2288 | |||
2289 | if (!dac) | ||
2290 | return NULL; | ||
2291 | |||
2292 | dac->tv_std = radeon_atombios_get_tv_info(rdev); | ||
2293 | return dac; | ||
2294 | } | ||
2295 | |||
2296 | struct radeon_encoder_atom_dig * | ||
2297 | radeon_atombios_set_dig_info(struct radeon_encoder *radeon_encoder) | ||
2298 | { | ||
2299 | int encoder_enum = (radeon_encoder->encoder_enum & ENUM_ID_MASK) >> ENUM_ID_SHIFT; | ||
2300 | struct radeon_encoder_atom_dig *dig = kzalloc(sizeof(struct radeon_encoder_atom_dig), GFP_KERNEL); | ||
2301 | |||
2302 | if (!dig) | ||
2303 | return NULL; | ||
2304 | |||
2305 | /* coherent mode by default */ | ||
2306 | dig->coherent_mode = true; | ||
2307 | dig->dig_encoder = -1; | ||
2308 | |||
2309 | if (encoder_enum == 2) | ||
2310 | dig->linkb = true; | ||
2311 | else | ||
2312 | dig->linkb = false; | ||
2313 | |||
2314 | return dig; | ||
2315 | } | ||
2316 | |||
2317 | void | ||
2318 | radeon_add_atom_encoder(struct drm_device *dev, | ||
2319 | uint32_t encoder_enum, | ||
2320 | uint32_t supported_device, | ||
2321 | u16 caps) | ||
2322 | { | ||
2323 | struct radeon_device *rdev = dev->dev_private; | ||
2324 | struct drm_encoder *encoder; | ||
2325 | struct radeon_encoder *radeon_encoder; | ||
2326 | |||
2327 | /* see if we already added it */ | ||
2328 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { | ||
2329 | radeon_encoder = to_radeon_encoder(encoder); | ||
2330 | if (radeon_encoder->encoder_enum == encoder_enum) { | ||
2331 | radeon_encoder->devices |= supported_device; | ||
2332 | return; | ||
2333 | } | ||
2334 | |||
2335 | } | ||
2336 | |||
2337 | /* add a new one */ | ||
2338 | radeon_encoder = kzalloc(sizeof(struct radeon_encoder), GFP_KERNEL); | ||
2339 | if (!radeon_encoder) | ||
2340 | return; | ||
2341 | |||
2342 | encoder = &radeon_encoder->base; | ||
2343 | switch (rdev->num_crtc) { | ||
2344 | case 1: | ||
2345 | encoder->possible_crtcs = 0x1; | ||
2346 | break; | ||
2347 | case 2: | ||
2348 | default: | ||
2349 | encoder->possible_crtcs = 0x3; | ||
2350 | break; | ||
2351 | case 4: | ||
2352 | encoder->possible_crtcs = 0xf; | ||
2353 | break; | ||
2354 | case 6: | ||
2355 | encoder->possible_crtcs = 0x3f; | ||
2356 | break; | ||
2357 | } | ||
2358 | |||
2359 | radeon_encoder->enc_priv = NULL; | ||
2360 | |||
2361 | radeon_encoder->encoder_enum = encoder_enum; | ||
2362 | radeon_encoder->encoder_id = (encoder_enum & OBJECT_ID_MASK) >> OBJECT_ID_SHIFT; | ||
2363 | radeon_encoder->devices = supported_device; | ||
2364 | radeon_encoder->rmx_type = RMX_OFF; | ||
2365 | radeon_encoder->underscan_type = UNDERSCAN_OFF; | ||
2366 | radeon_encoder->is_ext_encoder = false; | ||
2367 | radeon_encoder->caps = caps; | ||
2368 | |||
2369 | switch (radeon_encoder->encoder_id) { | ||
2370 | case ENCODER_OBJECT_ID_INTERNAL_LVDS: | ||
2371 | case ENCODER_OBJECT_ID_INTERNAL_TMDS1: | ||
2372 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1: | ||
2373 | case ENCODER_OBJECT_ID_INTERNAL_LVTM1: | ||
2374 | if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) { | ||
2375 | radeon_encoder->rmx_type = RMX_FULL; | ||
2376 | drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_LVDS); | ||
2377 | radeon_encoder->enc_priv = radeon_atombios_get_lvds_info(radeon_encoder); | ||
2378 | } else { | ||
2379 | drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_TMDS); | ||
2380 | radeon_encoder->enc_priv = radeon_atombios_set_dig_info(radeon_encoder); | ||
2381 | } | ||
2382 | drm_encoder_helper_add(encoder, &radeon_atom_dig_helper_funcs); | ||
2383 | break; | ||
2384 | case ENCODER_OBJECT_ID_INTERNAL_DAC1: | ||
2385 | drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_DAC); | ||
2386 | radeon_encoder->enc_priv = radeon_atombios_set_dac_info(radeon_encoder); | ||
2387 | drm_encoder_helper_add(encoder, &radeon_atom_dac_helper_funcs); | ||
2388 | break; | ||
2389 | case ENCODER_OBJECT_ID_INTERNAL_DAC2: | ||
2390 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1: | ||
2391 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2: | ||
2392 | drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_TVDAC); | ||
2393 | radeon_encoder->enc_priv = radeon_atombios_set_dac_info(radeon_encoder); | ||
2394 | drm_encoder_helper_add(encoder, &radeon_atom_dac_helper_funcs); | ||
2395 | break; | ||
2396 | case ENCODER_OBJECT_ID_INTERNAL_DVO1: | ||
2397 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1: | ||
2398 | case ENCODER_OBJECT_ID_INTERNAL_DDI: | ||
2399 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: | ||
2400 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: | ||
2401 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: | ||
2402 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: | ||
2403 | if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) { | ||
2404 | radeon_encoder->rmx_type = RMX_FULL; | ||
2405 | drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_LVDS); | ||
2406 | radeon_encoder->enc_priv = radeon_atombios_get_lvds_info(radeon_encoder); | ||
2407 | } else if (radeon_encoder->devices & (ATOM_DEVICE_CRT_SUPPORT)) { | ||
2408 | drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_DAC); | ||
2409 | radeon_encoder->enc_priv = radeon_atombios_set_dig_info(radeon_encoder); | ||
2410 | } else { | ||
2411 | drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_TMDS); | ||
2412 | radeon_encoder->enc_priv = radeon_atombios_set_dig_info(radeon_encoder); | ||
2413 | } | ||
2414 | drm_encoder_helper_add(encoder, &radeon_atom_dig_helper_funcs); | ||
2415 | break; | ||
2416 | case ENCODER_OBJECT_ID_SI170B: | ||
2417 | case ENCODER_OBJECT_ID_CH7303: | ||
2418 | case ENCODER_OBJECT_ID_EXTERNAL_SDVOA: | ||
2419 | case ENCODER_OBJECT_ID_EXTERNAL_SDVOB: | ||
2420 | case ENCODER_OBJECT_ID_TITFP513: | ||
2421 | case ENCODER_OBJECT_ID_VT1623: | ||
2422 | case ENCODER_OBJECT_ID_HDMI_SI1930: | ||
2423 | case ENCODER_OBJECT_ID_TRAVIS: | ||
2424 | case ENCODER_OBJECT_ID_NUTMEG: | ||
2425 | /* these are handled by the primary encoders */ | ||
2426 | radeon_encoder->is_ext_encoder = true; | ||
2427 | if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) | ||
2428 | drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_LVDS); | ||
2429 | else if (radeon_encoder->devices & (ATOM_DEVICE_CRT_SUPPORT)) | ||
2430 | drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_DAC); | ||
2431 | else | ||
2432 | drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_TMDS); | ||
2433 | drm_encoder_helper_add(encoder, &radeon_atom_ext_helper_funcs); | ||
2434 | break; | ||
2435 | } | ||
2436 | } | ||
diff --git a/drivers/gpu/drm/radeon/radeon_gart.c b/drivers/gpu/drm/radeon/radeon_gart.c index fdc3a9a54bf8..ba7ab79e12c1 100644 --- a/drivers/gpu/drm/radeon/radeon_gart.c +++ b/drivers/gpu/drm/radeon/radeon_gart.c | |||
@@ -49,27 +49,27 @@ int radeon_gart_table_ram_alloc(struct radeon_device *rdev) | |||
49 | rdev->gart.table_size >> PAGE_SHIFT); | 49 | rdev->gart.table_size >> PAGE_SHIFT); |
50 | } | 50 | } |
51 | #endif | 51 | #endif |
52 | rdev->gart.table.ram.ptr = ptr; | 52 | rdev->gart.ptr = ptr; |
53 | memset((void *)rdev->gart.table.ram.ptr, 0, rdev->gart.table_size); | 53 | memset((void *)rdev->gart.ptr, 0, rdev->gart.table_size); |
54 | return 0; | 54 | return 0; |
55 | } | 55 | } |
56 | 56 | ||
57 | void radeon_gart_table_ram_free(struct radeon_device *rdev) | 57 | void radeon_gart_table_ram_free(struct radeon_device *rdev) |
58 | { | 58 | { |
59 | if (rdev->gart.table.ram.ptr == NULL) { | 59 | if (rdev->gart.ptr == NULL) { |
60 | return; | 60 | return; |
61 | } | 61 | } |
62 | #ifdef CONFIG_X86 | 62 | #ifdef CONFIG_X86 |
63 | if (rdev->family == CHIP_RS400 || rdev->family == CHIP_RS480 || | 63 | if (rdev->family == CHIP_RS400 || rdev->family == CHIP_RS480 || |
64 | rdev->family == CHIP_RS690 || rdev->family == CHIP_RS740) { | 64 | rdev->family == CHIP_RS690 || rdev->family == CHIP_RS740) { |
65 | set_memory_wb((unsigned long)rdev->gart.table.ram.ptr, | 65 | set_memory_wb((unsigned long)rdev->gart.ptr, |
66 | rdev->gart.table_size >> PAGE_SHIFT); | 66 | rdev->gart.table_size >> PAGE_SHIFT); |
67 | } | 67 | } |
68 | #endif | 68 | #endif |
69 | pci_free_consistent(rdev->pdev, rdev->gart.table_size, | 69 | pci_free_consistent(rdev->pdev, rdev->gart.table_size, |
70 | (void *)rdev->gart.table.ram.ptr, | 70 | (void *)rdev->gart.ptr, |
71 | rdev->gart.table_addr); | 71 | rdev->gart.table_addr); |
72 | rdev->gart.table.ram.ptr = NULL; | 72 | rdev->gart.ptr = NULL; |
73 | rdev->gart.table_addr = 0; | 73 | rdev->gart.table_addr = 0; |
74 | } | 74 | } |
75 | 75 | ||
@@ -77,10 +77,10 @@ int radeon_gart_table_vram_alloc(struct radeon_device *rdev) | |||
77 | { | 77 | { |
78 | int r; | 78 | int r; |
79 | 79 | ||
80 | if (rdev->gart.table.vram.robj == NULL) { | 80 | if (rdev->gart.robj == NULL) { |
81 | r = radeon_bo_create(rdev, rdev->gart.table_size, | 81 | r = radeon_bo_create(rdev, rdev->gart.table_size, |
82 | PAGE_SIZE, true, RADEON_GEM_DOMAIN_VRAM, | 82 | PAGE_SIZE, true, RADEON_GEM_DOMAIN_VRAM, |
83 | &rdev->gart.table.vram.robj); | 83 | &rdev->gart.robj); |
84 | if (r) { | 84 | if (r) { |
85 | return r; | 85 | return r; |
86 | } | 86 | } |
@@ -93,38 +93,46 @@ int radeon_gart_table_vram_pin(struct radeon_device *rdev) | |||
93 | uint64_t gpu_addr; | 93 | uint64_t gpu_addr; |
94 | int r; | 94 | int r; |
95 | 95 | ||
96 | r = radeon_bo_reserve(rdev->gart.table.vram.robj, false); | 96 | r = radeon_bo_reserve(rdev->gart.robj, false); |
97 | if (unlikely(r != 0)) | 97 | if (unlikely(r != 0)) |
98 | return r; | 98 | return r; |
99 | r = radeon_bo_pin(rdev->gart.table.vram.robj, | 99 | r = radeon_bo_pin(rdev->gart.robj, |
100 | RADEON_GEM_DOMAIN_VRAM, &gpu_addr); | 100 | RADEON_GEM_DOMAIN_VRAM, &gpu_addr); |
101 | if (r) { | 101 | if (r) { |
102 | radeon_bo_unreserve(rdev->gart.table.vram.robj); | 102 | radeon_bo_unreserve(rdev->gart.robj); |
103 | return r; | 103 | return r; |
104 | } | 104 | } |
105 | r = radeon_bo_kmap(rdev->gart.table.vram.robj, | 105 | r = radeon_bo_kmap(rdev->gart.robj, &rdev->gart.ptr); |
106 | (void **)&rdev->gart.table.vram.ptr); | ||
107 | if (r) | 106 | if (r) |
108 | radeon_bo_unpin(rdev->gart.table.vram.robj); | 107 | radeon_bo_unpin(rdev->gart.robj); |
109 | radeon_bo_unreserve(rdev->gart.table.vram.robj); | 108 | radeon_bo_unreserve(rdev->gart.robj); |
110 | rdev->gart.table_addr = gpu_addr; | 109 | rdev->gart.table_addr = gpu_addr; |
111 | return r; | 110 | return r; |
112 | } | 111 | } |
113 | 112 | ||
114 | void radeon_gart_table_vram_free(struct radeon_device *rdev) | 113 | void radeon_gart_table_vram_unpin(struct radeon_device *rdev) |
115 | { | 114 | { |
116 | int r; | 115 | int r; |
117 | 116 | ||
118 | if (rdev->gart.table.vram.robj == NULL) { | 117 | if (rdev->gart.robj == NULL) { |
119 | return; | 118 | return; |
120 | } | 119 | } |
121 | r = radeon_bo_reserve(rdev->gart.table.vram.robj, false); | 120 | r = radeon_bo_reserve(rdev->gart.robj, false); |
122 | if (likely(r == 0)) { | 121 | if (likely(r == 0)) { |
123 | radeon_bo_kunmap(rdev->gart.table.vram.robj); | 122 | radeon_bo_kunmap(rdev->gart.robj); |
124 | radeon_bo_unpin(rdev->gart.table.vram.robj); | 123 | radeon_bo_unpin(rdev->gart.robj); |
125 | radeon_bo_unreserve(rdev->gart.table.vram.robj); | 124 | radeon_bo_unreserve(rdev->gart.robj); |
125 | rdev->gart.ptr = NULL; | ||
126 | } | 126 | } |
127 | radeon_bo_unref(&rdev->gart.table.vram.robj); | 127 | } |
128 | |||
129 | void radeon_gart_table_vram_free(struct radeon_device *rdev) | ||
130 | { | ||
131 | if (rdev->gart.robj == NULL) { | ||
132 | return; | ||
133 | } | ||
134 | radeon_gart_table_vram_unpin(rdev); | ||
135 | radeon_bo_unref(&rdev->gart.robj); | ||
128 | } | 136 | } |
129 | 137 | ||
130 | 138 | ||
@@ -151,12 +159,14 @@ void radeon_gart_unbind(struct radeon_device *rdev, unsigned offset, | |||
151 | if (rdev->gart.pages[p]) { | 159 | if (rdev->gart.pages[p]) { |
152 | if (!rdev->gart.ttm_alloced[p]) | 160 | if (!rdev->gart.ttm_alloced[p]) |
153 | pci_unmap_page(rdev->pdev, rdev->gart.pages_addr[p], | 161 | pci_unmap_page(rdev->pdev, rdev->gart.pages_addr[p], |
154 | PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); | 162 | PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); |
155 | rdev->gart.pages[p] = NULL; | 163 | rdev->gart.pages[p] = NULL; |
156 | rdev->gart.pages_addr[p] = rdev->dummy_page.addr; | 164 | rdev->gart.pages_addr[p] = rdev->dummy_page.addr; |
157 | page_base = rdev->gart.pages_addr[p]; | 165 | page_base = rdev->gart.pages_addr[p]; |
158 | for (j = 0; j < (PAGE_SIZE / RADEON_GPU_PAGE_SIZE); j++, t++) { | 166 | for (j = 0; j < (PAGE_SIZE / RADEON_GPU_PAGE_SIZE); j++, t++) { |
159 | radeon_gart_set_page(rdev, t, page_base); | 167 | if (rdev->gart.ptr) { |
168 | radeon_gart_set_page(rdev, t, page_base); | ||
169 | } | ||
160 | page_base += RADEON_GPU_PAGE_SIZE; | 170 | page_base += RADEON_GPU_PAGE_SIZE; |
161 | } | 171 | } |
162 | } | 172 | } |
@@ -199,10 +209,12 @@ int radeon_gart_bind(struct radeon_device *rdev, unsigned offset, | |||
199 | } | 209 | } |
200 | } | 210 | } |
201 | rdev->gart.pages[p] = pagelist[i]; | 211 | rdev->gart.pages[p] = pagelist[i]; |
202 | page_base = rdev->gart.pages_addr[p]; | 212 | if (rdev->gart.ptr) { |
203 | for (j = 0; j < (PAGE_SIZE / RADEON_GPU_PAGE_SIZE); j++, t++) { | 213 | page_base = rdev->gart.pages_addr[p]; |
204 | radeon_gart_set_page(rdev, t, page_base); | 214 | for (j = 0; j < (PAGE_SIZE / RADEON_GPU_PAGE_SIZE); j++, t++) { |
205 | page_base += RADEON_GPU_PAGE_SIZE; | 215 | radeon_gart_set_page(rdev, t, page_base); |
216 | page_base += RADEON_GPU_PAGE_SIZE; | ||
217 | } | ||
206 | } | 218 | } |
207 | } | 219 | } |
208 | mb(); | 220 | mb(); |
@@ -215,6 +227,9 @@ void radeon_gart_restore(struct radeon_device *rdev) | |||
215 | int i, j, t; | 227 | int i, j, t; |
216 | u64 page_base; | 228 | u64 page_base; |
217 | 229 | ||
230 | if (!rdev->gart.ptr) { | ||
231 | return; | ||
232 | } | ||
218 | for (i = 0, t = 0; i < rdev->gart.num_cpu_pages; i++) { | 233 | for (i = 0, t = 0; i < rdev->gart.num_cpu_pages; i++) { |
219 | page_base = rdev->gart.pages_addr[i]; | 234 | page_base = rdev->gart.pages_addr[i]; |
220 | for (j = 0; j < (PAGE_SIZE / RADEON_GPU_PAGE_SIZE); j++, t++) { | 235 | for (j = 0; j < (PAGE_SIZE / RADEON_GPU_PAGE_SIZE); j++, t++) { |
diff --git a/drivers/gpu/drm/radeon/radeon_i2c.c b/drivers/gpu/drm/radeon/radeon_i2c.c index e6d110ce2331..7bb1b079f480 100644 --- a/drivers/gpu/drm/radeon/radeon_i2c.c +++ b/drivers/gpu/drm/radeon/radeon_i2c.c | |||
@@ -34,7 +34,7 @@ | |||
34 | * radeon_ddc_probe | 34 | * radeon_ddc_probe |
35 | * | 35 | * |
36 | */ | 36 | */ |
37 | bool radeon_ddc_probe(struct radeon_connector *radeon_connector, bool requires_extended_probe) | 37 | bool radeon_ddc_probe(struct radeon_connector *radeon_connector) |
38 | { | 38 | { |
39 | u8 out = 0x0; | 39 | u8 out = 0x0; |
40 | u8 buf[8]; | 40 | u8 buf[8]; |
@@ -49,15 +49,11 @@ bool radeon_ddc_probe(struct radeon_connector *radeon_connector, bool requires_e | |||
49 | { | 49 | { |
50 | .addr = 0x50, | 50 | .addr = 0x50, |
51 | .flags = I2C_M_RD, | 51 | .flags = I2C_M_RD, |
52 | .len = 1, | 52 | .len = 8, |
53 | .buf = buf, | 53 | .buf = buf, |
54 | } | 54 | } |
55 | }; | 55 | }; |
56 | 56 | ||
57 | /* Read 8 bytes from i2c for extended probe of EDID header */ | ||
58 | if (requires_extended_probe) | ||
59 | msgs[1].len = 8; | ||
60 | |||
61 | /* on hw with routers, select right port */ | 57 | /* on hw with routers, select right port */ |
62 | if (radeon_connector->router.ddc_valid) | 58 | if (radeon_connector->router.ddc_valid) |
63 | radeon_router_select_ddc_port(radeon_connector); | 59 | radeon_router_select_ddc_port(radeon_connector); |
@@ -66,17 +62,15 @@ bool radeon_ddc_probe(struct radeon_connector *radeon_connector, bool requires_e | |||
66 | if (ret != 2) | 62 | if (ret != 2) |
67 | /* Couldn't find an accessible DDC on this connector */ | 63 | /* Couldn't find an accessible DDC on this connector */ |
68 | return false; | 64 | return false; |
69 | if (requires_extended_probe) { | 65 | /* Probe also for valid EDID header |
70 | /* Probe also for valid EDID header | 66 | * EDID header starts with: |
71 | * EDID header starts with: | 67 | * 0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00. |
72 | * 0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00. | 68 | * Only the first 6 bytes must be valid as |
73 | * Only the first 6 bytes must be valid as | 69 | * drm_edid_block_valid() can fix the last 2 bytes */ |
74 | * drm_edid_block_valid() can fix the last 2 bytes */ | 70 | if (drm_edid_header_is_valid(buf) < 6) { |
75 | if (drm_edid_header_is_valid(buf) < 6) { | 71 | /* Couldn't find an accessible EDID on this |
76 | /* Couldn't find an accessible EDID on this | 72 | * connector */ |
77 | * connector */ | 73 | return false; |
78 | return false; | ||
79 | } | ||
80 | } | 74 | } |
81 | return true; | 75 | return true; |
82 | } | 76 | } |
diff --git a/drivers/gpu/drm/radeon/radeon_irq_kms.c b/drivers/gpu/drm/radeon/radeon_irq_kms.c index 9ec830c77af0..8f86aeb26693 100644 --- a/drivers/gpu/drm/radeon/radeon_irq_kms.c +++ b/drivers/gpu/drm/radeon/radeon_irq_kms.c | |||
@@ -67,10 +67,10 @@ void radeon_driver_irq_preinstall_kms(struct drm_device *dev) | |||
67 | /* Disable *all* interrupts */ | 67 | /* Disable *all* interrupts */ |
68 | rdev->irq.sw_int = false; | 68 | rdev->irq.sw_int = false; |
69 | rdev->irq.gui_idle = false; | 69 | rdev->irq.gui_idle = false; |
70 | for (i = 0; i < rdev->num_crtc; i++) | 70 | for (i = 0; i < RADEON_MAX_HPD_PINS; i++) |
71 | rdev->irq.crtc_vblank_int[i] = false; | ||
72 | for (i = 0; i < 6; i++) { | ||
73 | rdev->irq.hpd[i] = false; | 71 | rdev->irq.hpd[i] = false; |
72 | for (i = 0; i < RADEON_MAX_CRTCS; i++) { | ||
73 | rdev->irq.crtc_vblank_int[i] = false; | ||
74 | rdev->irq.pflip[i] = false; | 74 | rdev->irq.pflip[i] = false; |
75 | } | 75 | } |
76 | radeon_irq_set(rdev); | 76 | radeon_irq_set(rdev); |
@@ -99,15 +99,55 @@ void radeon_driver_irq_uninstall_kms(struct drm_device *dev) | |||
99 | /* Disable *all* interrupts */ | 99 | /* Disable *all* interrupts */ |
100 | rdev->irq.sw_int = false; | 100 | rdev->irq.sw_int = false; |
101 | rdev->irq.gui_idle = false; | 101 | rdev->irq.gui_idle = false; |
102 | for (i = 0; i < rdev->num_crtc; i++) | 102 | for (i = 0; i < RADEON_MAX_HPD_PINS; i++) |
103 | rdev->irq.crtc_vblank_int[i] = false; | ||
104 | for (i = 0; i < 6; i++) { | ||
105 | rdev->irq.hpd[i] = false; | 103 | rdev->irq.hpd[i] = false; |
104 | for (i = 0; i < RADEON_MAX_CRTCS; i++) { | ||
105 | rdev->irq.crtc_vblank_int[i] = false; | ||
106 | rdev->irq.pflip[i] = false; | 106 | rdev->irq.pflip[i] = false; |
107 | } | 107 | } |
108 | radeon_irq_set(rdev); | 108 | radeon_irq_set(rdev); |
109 | } | 109 | } |
110 | 110 | ||
111 | static bool radeon_msi_ok(struct radeon_device *rdev) | ||
112 | { | ||
113 | /* RV370/RV380 was first asic with MSI support */ | ||
114 | if (rdev->family < CHIP_RV380) | ||
115 | return false; | ||
116 | |||
117 | /* MSIs don't work on AGP */ | ||
118 | if (rdev->flags & RADEON_IS_AGP) | ||
119 | return false; | ||
120 | |||
121 | /* force MSI on */ | ||
122 | if (radeon_msi == 1) | ||
123 | return true; | ||
124 | else if (radeon_msi == 0) | ||
125 | return false; | ||
126 | |||
127 | /* Quirks */ | ||
128 | /* HP RS690 only seems to work with MSIs. */ | ||
129 | if ((rdev->pdev->device == 0x791f) && | ||
130 | (rdev->pdev->subsystem_vendor == 0x103c) && | ||
131 | (rdev->pdev->subsystem_device == 0x30c2)) | ||
132 | return true; | ||
133 | |||
134 | /* Dell RS690 only seems to work with MSIs. */ | ||
135 | if ((rdev->pdev->device == 0x791f) && | ||
136 | (rdev->pdev->subsystem_vendor == 0x1028) && | ||
137 | (rdev->pdev->subsystem_device == 0x01fd)) | ||
138 | return true; | ||
139 | |||
140 | if (rdev->flags & RADEON_IS_IGP) { | ||
141 | /* APUs work fine with MSIs */ | ||
142 | if (rdev->family >= CHIP_PALM) | ||
143 | return true; | ||
144 | /* lots of IGPs have problems with MSIs */ | ||
145 | return false; | ||
146 | } | ||
147 | |||
148 | return true; | ||
149 | } | ||
150 | |||
111 | int radeon_irq_kms_init(struct radeon_device *rdev) | 151 | int radeon_irq_kms_init(struct radeon_device *rdev) |
112 | { | 152 | { |
113 | int i; | 153 | int i; |
@@ -124,12 +164,8 @@ int radeon_irq_kms_init(struct radeon_device *rdev) | |||
124 | } | 164 | } |
125 | /* enable msi */ | 165 | /* enable msi */ |
126 | rdev->msi_enabled = 0; | 166 | rdev->msi_enabled = 0; |
127 | /* MSIs don't seem to work reliably on all IGP | 167 | |
128 | * chips. Disable MSI on them for now. | 168 | if (radeon_msi_ok(rdev)) { |
129 | */ | ||
130 | if ((rdev->family >= CHIP_RV380) && | ||
131 | ((!(rdev->flags & RADEON_IS_IGP)) || (rdev->family >= CHIP_PALM)) && | ||
132 | (!(rdev->flags & RADEON_IS_AGP))) { | ||
133 | int ret = pci_enable_msi(rdev->pdev); | 169 | int ret = pci_enable_msi(rdev->pdev); |
134 | if (!ret) { | 170 | if (!ret) { |
135 | rdev->msi_enabled = 1; | 171 | rdev->msi_enabled = 1; |
diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h index ed0178f03235..2c2e75ef8a37 100644 --- a/drivers/gpu/drm/radeon/radeon_mode.h +++ b/drivers/gpu/drm/radeon/radeon_mode.h | |||
@@ -438,9 +438,6 @@ struct radeon_connector { | |||
438 | struct radeon_i2c_chan *ddc_bus; | 438 | struct radeon_i2c_chan *ddc_bus; |
439 | /* some systems have an hdmi and vga port with a shared ddc line */ | 439 | /* some systems have an hdmi and vga port with a shared ddc line */ |
440 | bool shared_ddc; | 440 | bool shared_ddc; |
441 | /* for some Radeon chip families we apply an additional EDID header | ||
442 | check as part of the DDC probe */ | ||
443 | bool requires_extended_probe; | ||
444 | bool use_digital; | 441 | bool use_digital; |
445 | /* we need to mind the EDID between detect | 442 | /* we need to mind the EDID between detect |
446 | and get modes due to analog/digital/tvencoder */ | 443 | and get modes due to analog/digital/tvencoder */ |
@@ -459,6 +456,8 @@ struct radeon_framebuffer { | |||
459 | struct drm_gem_object *obj; | 456 | struct drm_gem_object *obj; |
460 | }; | 457 | }; |
461 | 458 | ||
459 | #define ENCODER_MODE_IS_DP(em) (((em) == ATOM_ENCODER_MODE_DP) || \ | ||
460 | ((em) == ATOM_ENCODER_MODE_DP_MST)) | ||
462 | 461 | ||
463 | extern enum radeon_tv_std | 462 | extern enum radeon_tv_std |
464 | radeon_combios_get_tv_info(struct radeon_device *rdev); | 463 | radeon_combios_get_tv_info(struct radeon_device *rdev); |
@@ -468,8 +467,8 @@ radeon_atombios_get_tv_info(struct radeon_device *rdev); | |||
468 | extern struct drm_connector * | 467 | extern struct drm_connector * |
469 | radeon_get_connector_for_encoder(struct drm_encoder *encoder); | 468 | radeon_get_connector_for_encoder(struct drm_encoder *encoder); |
470 | 469 | ||
471 | extern bool radeon_encoder_is_dp_bridge(struct drm_encoder *encoder); | 470 | extern u16 radeon_encoder_get_dp_bridge_encoder_id(struct drm_encoder *encoder); |
472 | extern bool radeon_connector_encoder_is_dp_bridge(struct drm_connector *connector); | 471 | extern u16 radeon_connector_encoder_get_dp_bridge_encoder_id(struct drm_connector *connector); |
473 | extern bool radeon_connector_encoder_is_hbr2(struct drm_connector *connector); | 472 | extern bool radeon_connector_encoder_is_hbr2(struct drm_connector *connector); |
474 | extern bool radeon_connector_is_dp12_capable(struct drm_connector *connector); | 473 | extern bool radeon_connector_is_dp12_capable(struct drm_connector *connector); |
475 | 474 | ||
@@ -489,7 +488,7 @@ extern void atombios_dig_transmitter_setup(struct drm_encoder *encoder, | |||
489 | int action, uint8_t lane_num, | 488 | int action, uint8_t lane_num, |
490 | uint8_t lane_set); | 489 | uint8_t lane_set); |
491 | extern void radeon_atom_ext_encoder_setup_ddc(struct drm_encoder *encoder); | 490 | extern void radeon_atom_ext_encoder_setup_ddc(struct drm_encoder *encoder); |
492 | extern struct drm_encoder *radeon_atom_get_external_encoder(struct drm_encoder *encoder); | 491 | extern struct drm_encoder *radeon_get_external_encoder(struct drm_encoder *encoder); |
493 | extern int radeon_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode, | 492 | extern int radeon_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode, |
494 | u8 write_byte, u8 *read_byte); | 493 | u8 write_byte, u8 *read_byte); |
495 | 494 | ||
@@ -519,8 +518,7 @@ extern void radeon_i2c_put_byte(struct radeon_i2c_chan *i2c, | |||
519 | u8 val); | 518 | u8 val); |
520 | extern void radeon_router_select_ddc_port(struct radeon_connector *radeon_connector); | 519 | extern void radeon_router_select_ddc_port(struct radeon_connector *radeon_connector); |
521 | extern void radeon_router_select_cd_port(struct radeon_connector *radeon_connector); | 520 | extern void radeon_router_select_cd_port(struct radeon_connector *radeon_connector); |
522 | extern bool radeon_ddc_probe(struct radeon_connector *radeon_connector, | 521 | extern bool radeon_ddc_probe(struct radeon_connector *radeon_connector); |
523 | bool requires_extended_probe); | ||
524 | extern int radeon_ddc_get_modes(struct radeon_connector *radeon_connector); | 522 | extern int radeon_ddc_get_modes(struct radeon_connector *radeon_connector); |
525 | 523 | ||
526 | extern struct drm_encoder *radeon_best_encoder(struct drm_connector *connector); | 524 | extern struct drm_encoder *radeon_best_encoder(struct drm_connector *connector); |
diff --git a/drivers/gpu/drm/radeon/rs400.c b/drivers/gpu/drm/radeon/rs400.c index 89a6e1ecea8d..06b90c87f8f3 100644 --- a/drivers/gpu/drm/radeon/rs400.c +++ b/drivers/gpu/drm/radeon/rs400.c | |||
@@ -77,7 +77,7 @@ int rs400_gart_init(struct radeon_device *rdev) | |||
77 | { | 77 | { |
78 | int r; | 78 | int r; |
79 | 79 | ||
80 | if (rdev->gart.table.ram.ptr) { | 80 | if (rdev->gart.ptr) { |
81 | WARN(1, "RS400 GART already initialized\n"); | 81 | WARN(1, "RS400 GART already initialized\n"); |
82 | return 0; | 82 | return 0; |
83 | } | 83 | } |
@@ -212,6 +212,7 @@ void rs400_gart_fini(struct radeon_device *rdev) | |||
212 | int rs400_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr) | 212 | int rs400_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr) |
213 | { | 213 | { |
214 | uint32_t entry; | 214 | uint32_t entry; |
215 | u32 *gtt = rdev->gart.ptr; | ||
215 | 216 | ||
216 | if (i < 0 || i > rdev->gart.num_gpu_pages) { | 217 | if (i < 0 || i > rdev->gart.num_gpu_pages) { |
217 | return -EINVAL; | 218 | return -EINVAL; |
@@ -221,7 +222,7 @@ int rs400_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr) | |||
221 | ((upper_32_bits(addr) & 0xff) << 4) | | 222 | ((upper_32_bits(addr) & 0xff) << 4) | |
222 | RS400_PTE_WRITEABLE | RS400_PTE_READABLE; | 223 | RS400_PTE_WRITEABLE | RS400_PTE_READABLE; |
223 | entry = cpu_to_le32(entry); | 224 | entry = cpu_to_le32(entry); |
224 | rdev->gart.table.ram.ptr[i] = entry; | 225 | gtt[i] = entry; |
225 | return 0; | 226 | return 0; |
226 | } | 227 | } |
227 | 228 | ||
diff --git a/drivers/gpu/drm/radeon/rs600.c b/drivers/gpu/drm/radeon/rs600.c index 9320dd6404f6..481b99e89f65 100644 --- a/drivers/gpu/drm/radeon/rs600.c +++ b/drivers/gpu/drm/radeon/rs600.c | |||
@@ -287,6 +287,7 @@ void rs600_hpd_init(struct radeon_device *rdev) | |||
287 | default: | 287 | default: |
288 | break; | 288 | break; |
289 | } | 289 | } |
290 | radeon_hpd_set_polarity(rdev, radeon_connector->hpd.hpd); | ||
290 | } | 291 | } |
291 | if (rdev->irq.installed) | 292 | if (rdev->irq.installed) |
292 | rs600_irq_set(rdev); | 293 | rs600_irq_set(rdev); |
@@ -413,7 +414,7 @@ int rs600_gart_init(struct radeon_device *rdev) | |||
413 | { | 414 | { |
414 | int r; | 415 | int r; |
415 | 416 | ||
416 | if (rdev->gart.table.vram.robj) { | 417 | if (rdev->gart.robj) { |
417 | WARN(1, "RS600 GART already initialized\n"); | 418 | WARN(1, "RS600 GART already initialized\n"); |
418 | return 0; | 419 | return 0; |
419 | } | 420 | } |
@@ -431,7 +432,7 @@ static int rs600_gart_enable(struct radeon_device *rdev) | |||
431 | u32 tmp; | 432 | u32 tmp; |
432 | int r, i; | 433 | int r, i; |
433 | 434 | ||
434 | if (rdev->gart.table.vram.robj == NULL) { | 435 | if (rdev->gart.robj == NULL) { |
435 | dev_err(rdev->dev, "No VRAM object for PCIE GART.\n"); | 436 | dev_err(rdev->dev, "No VRAM object for PCIE GART.\n"); |
436 | return -EINVAL; | 437 | return -EINVAL; |
437 | } | 438 | } |
@@ -494,20 +495,12 @@ static int rs600_gart_enable(struct radeon_device *rdev) | |||
494 | void rs600_gart_disable(struct radeon_device *rdev) | 495 | void rs600_gart_disable(struct radeon_device *rdev) |
495 | { | 496 | { |
496 | u32 tmp; | 497 | u32 tmp; |
497 | int r; | ||
498 | 498 | ||
499 | /* FIXME: disable out of gart access */ | 499 | /* FIXME: disable out of gart access */ |
500 | WREG32_MC(R_000100_MC_PT0_CNTL, 0); | 500 | WREG32_MC(R_000100_MC_PT0_CNTL, 0); |
501 | tmp = RREG32_MC(R_000009_MC_CNTL1); | 501 | tmp = RREG32_MC(R_000009_MC_CNTL1); |
502 | WREG32_MC(R_000009_MC_CNTL1, tmp & C_000009_ENABLE_PAGE_TABLES); | 502 | WREG32_MC(R_000009_MC_CNTL1, tmp & C_000009_ENABLE_PAGE_TABLES); |
503 | if (rdev->gart.table.vram.robj) { | 503 | radeon_gart_table_vram_unpin(rdev); |
504 | r = radeon_bo_reserve(rdev->gart.table.vram.robj, false); | ||
505 | if (r == 0) { | ||
506 | radeon_bo_kunmap(rdev->gart.table.vram.robj); | ||
507 | radeon_bo_unpin(rdev->gart.table.vram.robj); | ||
508 | radeon_bo_unreserve(rdev->gart.table.vram.robj); | ||
509 | } | ||
510 | } | ||
511 | } | 504 | } |
512 | 505 | ||
513 | void rs600_gart_fini(struct radeon_device *rdev) | 506 | void rs600_gart_fini(struct radeon_device *rdev) |
@@ -525,7 +518,7 @@ void rs600_gart_fini(struct radeon_device *rdev) | |||
525 | 518 | ||
526 | int rs600_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr) | 519 | int rs600_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr) |
527 | { | 520 | { |
528 | void __iomem *ptr = (void *)rdev->gart.table.vram.ptr; | 521 | void __iomem *ptr = (void *)rdev->gart.ptr; |
529 | 522 | ||
530 | if (i < 0 || i > rdev->gart.num_gpu_pages) { | 523 | if (i < 0 || i > rdev->gart.num_gpu_pages) { |
531 | return -EINVAL; | 524 | return -EINVAL; |
diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c index 87cc1feee3ac..a983f410ab89 100644 --- a/drivers/gpu/drm/radeon/rv770.c +++ b/drivers/gpu/drm/radeon/rv770.c | |||
@@ -124,7 +124,7 @@ int rv770_pcie_gart_enable(struct radeon_device *rdev) | |||
124 | u32 tmp; | 124 | u32 tmp; |
125 | int r, i; | 125 | int r, i; |
126 | 126 | ||
127 | if (rdev->gart.table.vram.robj == NULL) { | 127 | if (rdev->gart.robj == NULL) { |
128 | dev_err(rdev->dev, "No VRAM object for PCIE GART.\n"); | 128 | dev_err(rdev->dev, "No VRAM object for PCIE GART.\n"); |
129 | return -EINVAL; | 129 | return -EINVAL; |
130 | } | 130 | } |
@@ -171,7 +171,7 @@ int rv770_pcie_gart_enable(struct radeon_device *rdev) | |||
171 | void rv770_pcie_gart_disable(struct radeon_device *rdev) | 171 | void rv770_pcie_gart_disable(struct radeon_device *rdev) |
172 | { | 172 | { |
173 | u32 tmp; | 173 | u32 tmp; |
174 | int i, r; | 174 | int i; |
175 | 175 | ||
176 | /* Disable all tables */ | 176 | /* Disable all tables */ |
177 | for (i = 0; i < 7; i++) | 177 | for (i = 0; i < 7; i++) |
@@ -191,14 +191,7 @@ void rv770_pcie_gart_disable(struct radeon_device *rdev) | |||
191 | WREG32(MC_VM_MB_L1_TLB1_CNTL, tmp); | 191 | WREG32(MC_VM_MB_L1_TLB1_CNTL, tmp); |
192 | WREG32(MC_VM_MB_L1_TLB2_CNTL, tmp); | 192 | WREG32(MC_VM_MB_L1_TLB2_CNTL, tmp); |
193 | WREG32(MC_VM_MB_L1_TLB3_CNTL, tmp); | 193 | WREG32(MC_VM_MB_L1_TLB3_CNTL, tmp); |
194 | if (rdev->gart.table.vram.robj) { | 194 | radeon_gart_table_vram_unpin(rdev); |
195 | r = radeon_bo_reserve(rdev->gart.table.vram.robj, false); | ||
196 | if (likely(r == 0)) { | ||
197 | radeon_bo_kunmap(rdev->gart.table.vram.robj); | ||
198 | radeon_bo_unpin(rdev->gart.table.vram.robj); | ||
199 | radeon_bo_unreserve(rdev->gart.table.vram.robj); | ||
200 | } | ||
201 | } | ||
202 | } | 195 | } |
203 | 196 | ||
204 | void rv770_pcie_gart_fini(struct radeon_device *rdev) | 197 | void rv770_pcie_gart_fini(struct radeon_device *rdev) |
@@ -282,7 +275,7 @@ static void rv770_mc_program(struct radeon_device *rdev) | |||
282 | WREG32(MC_VM_SYSTEM_APERTURE_HIGH_ADDR, | 275 | WREG32(MC_VM_SYSTEM_APERTURE_HIGH_ADDR, |
283 | rdev->mc.vram_end >> 12); | 276 | rdev->mc.vram_end >> 12); |
284 | } | 277 | } |
285 | WREG32(MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR, 0); | 278 | WREG32(MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR, rdev->vram_scratch.gpu_addr >> 12); |
286 | tmp = ((rdev->mc.vram_end >> 24) & 0xFFFF) << 16; | 279 | tmp = ((rdev->mc.vram_end >> 24) & 0xFFFF) << 16; |
287 | tmp |= ((rdev->mc.vram_start >> 24) & 0xFFFF); | 280 | tmp |= ((rdev->mc.vram_start >> 24) & 0xFFFF); |
288 | WREG32(MC_VM_FB_LOCATION, tmp); | 281 | WREG32(MC_VM_FB_LOCATION, tmp); |
@@ -959,54 +952,6 @@ static void rv770_gpu_init(struct radeon_device *rdev) | |||
959 | 952 | ||
960 | } | 953 | } |
961 | 954 | ||
962 | static int rv770_vram_scratch_init(struct radeon_device *rdev) | ||
963 | { | ||
964 | int r; | ||
965 | u64 gpu_addr; | ||
966 | |||
967 | if (rdev->vram_scratch.robj == NULL) { | ||
968 | r = radeon_bo_create(rdev, RADEON_GPU_PAGE_SIZE, | ||
969 | PAGE_SIZE, true, RADEON_GEM_DOMAIN_VRAM, | ||
970 | &rdev->vram_scratch.robj); | ||
971 | if (r) { | ||
972 | return r; | ||
973 | } | ||
974 | } | ||
975 | |||
976 | r = radeon_bo_reserve(rdev->vram_scratch.robj, false); | ||
977 | if (unlikely(r != 0)) | ||
978 | return r; | ||
979 | r = radeon_bo_pin(rdev->vram_scratch.robj, | ||
980 | RADEON_GEM_DOMAIN_VRAM, &gpu_addr); | ||
981 | if (r) { | ||
982 | radeon_bo_unreserve(rdev->vram_scratch.robj); | ||
983 | return r; | ||
984 | } | ||
985 | r = radeon_bo_kmap(rdev->vram_scratch.robj, | ||
986 | (void **)&rdev->vram_scratch.ptr); | ||
987 | if (r) | ||
988 | radeon_bo_unpin(rdev->vram_scratch.robj); | ||
989 | radeon_bo_unreserve(rdev->vram_scratch.robj); | ||
990 | |||
991 | return r; | ||
992 | } | ||
993 | |||
994 | static void rv770_vram_scratch_fini(struct radeon_device *rdev) | ||
995 | { | ||
996 | int r; | ||
997 | |||
998 | if (rdev->vram_scratch.robj == NULL) { | ||
999 | return; | ||
1000 | } | ||
1001 | r = radeon_bo_reserve(rdev->vram_scratch.robj, false); | ||
1002 | if (likely(r == 0)) { | ||
1003 | radeon_bo_kunmap(rdev->vram_scratch.robj); | ||
1004 | radeon_bo_unpin(rdev->vram_scratch.robj); | ||
1005 | radeon_bo_unreserve(rdev->vram_scratch.robj); | ||
1006 | } | ||
1007 | radeon_bo_unref(&rdev->vram_scratch.robj); | ||
1008 | } | ||
1009 | |||
1010 | void r700_vram_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc) | 955 | void r700_vram_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc) |
1011 | { | 956 | { |
1012 | u64 size_bf, size_af; | 957 | u64 size_bf, size_af; |
@@ -1106,6 +1051,10 @@ static int rv770_startup(struct radeon_device *rdev) | |||
1106 | } | 1051 | } |
1107 | } | 1052 | } |
1108 | 1053 | ||
1054 | r = r600_vram_scratch_init(rdev); | ||
1055 | if (r) | ||
1056 | return r; | ||
1057 | |||
1109 | rv770_mc_program(rdev); | 1058 | rv770_mc_program(rdev); |
1110 | if (rdev->flags & RADEON_IS_AGP) { | 1059 | if (rdev->flags & RADEON_IS_AGP) { |
1111 | rv770_agp_enable(rdev); | 1060 | rv770_agp_enable(rdev); |
@@ -1114,9 +1063,7 @@ static int rv770_startup(struct radeon_device *rdev) | |||
1114 | if (r) | 1063 | if (r) |
1115 | return r; | 1064 | return r; |
1116 | } | 1065 | } |
1117 | r = rv770_vram_scratch_init(rdev); | 1066 | |
1118 | if (r) | ||
1119 | return r; | ||
1120 | rv770_gpu_init(rdev); | 1067 | rv770_gpu_init(rdev); |
1121 | r = r600_blit_init(rdev); | 1068 | r = r600_blit_init(rdev); |
1122 | if (r) { | 1069 | if (r) { |
@@ -1316,7 +1263,7 @@ void rv770_fini(struct radeon_device *rdev) | |||
1316 | radeon_ib_pool_fini(rdev); | 1263 | radeon_ib_pool_fini(rdev); |
1317 | radeon_irq_kms_fini(rdev); | 1264 | radeon_irq_kms_fini(rdev); |
1318 | rv770_pcie_gart_fini(rdev); | 1265 | rv770_pcie_gart_fini(rdev); |
1319 | rv770_vram_scratch_fini(rdev); | 1266 | r600_vram_scratch_fini(rdev); |
1320 | radeon_gem_fini(rdev); | 1267 | radeon_gem_fini(rdev); |
1321 | radeon_fence_driver_fini(rdev); | 1268 | radeon_fence_driver_fini(rdev); |
1322 | radeon_agp_fini(rdev); | 1269 | radeon_agp_fini(rdev); |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c index 1805b8c2a948..dff8fc767152 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c | |||
@@ -104,6 +104,9 @@ | |||
104 | #define DRM_IOCTL_VMW_PRESENT_READBACK \ | 104 | #define DRM_IOCTL_VMW_PRESENT_READBACK \ |
105 | DRM_IOW(DRM_COMMAND_BASE + DRM_VMW_PRESENT_READBACK, \ | 105 | DRM_IOW(DRM_COMMAND_BASE + DRM_VMW_PRESENT_READBACK, \ |
106 | struct drm_vmw_present_readback_arg) | 106 | struct drm_vmw_present_readback_arg) |
107 | #define DRM_IOCTL_VMW_UPDATE_LAYOUT \ | ||
108 | DRM_IOW(DRM_COMMAND_BASE + DRM_VMW_UPDATE_LAYOUT, \ | ||
109 | struct drm_vmw_update_layout_arg) | ||
107 | 110 | ||
108 | /** | 111 | /** |
109 | * The core DRM version of this macro doesn't account for | 112 | * The core DRM version of this macro doesn't account for |
@@ -166,6 +169,9 @@ static struct drm_ioctl_desc vmw_ioctls[] = { | |||
166 | VMW_IOCTL_DEF(VMW_PRESENT_READBACK, | 169 | VMW_IOCTL_DEF(VMW_PRESENT_READBACK, |
167 | vmw_present_readback_ioctl, | 170 | vmw_present_readback_ioctl, |
168 | DRM_MASTER | DRM_AUTH | DRM_UNLOCKED), | 171 | DRM_MASTER | DRM_AUTH | DRM_UNLOCKED), |
172 | VMW_IOCTL_DEF(VMW_UPDATE_LAYOUT, | ||
173 | vmw_kms_update_layout_ioctl, | ||
174 | DRM_MASTER | DRM_UNLOCKED), | ||
169 | }; | 175 | }; |
170 | 176 | ||
171 | static struct pci_device_id vmw_pci_id_list[] = { | 177 | static struct pci_device_id vmw_pci_id_list[] = { |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h index 30589d0aecd9..8cca91a93bde 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h | |||
@@ -40,9 +40,9 @@ | |||
40 | #include "ttm/ttm_module.h" | 40 | #include "ttm/ttm_module.h" |
41 | #include "vmwgfx_fence.h" | 41 | #include "vmwgfx_fence.h" |
42 | 42 | ||
43 | #define VMWGFX_DRIVER_DATE "20111008" | 43 | #define VMWGFX_DRIVER_DATE "20111025" |
44 | #define VMWGFX_DRIVER_MAJOR 2 | 44 | #define VMWGFX_DRIVER_MAJOR 2 |
45 | #define VMWGFX_DRIVER_MINOR 2 | 45 | #define VMWGFX_DRIVER_MINOR 3 |
46 | #define VMWGFX_DRIVER_PATCHLEVEL 0 | 46 | #define VMWGFX_DRIVER_PATCHLEVEL 0 |
47 | #define VMWGFX_FILE_PAGE_OFFSET 0x00100000 | 47 | #define VMWGFX_FILE_PAGE_OFFSET 0x00100000 |
48 | #define VMWGFX_FIFO_STATIC_SIZE (1024*1024) | 48 | #define VMWGFX_FIFO_STATIC_SIZE (1024*1024) |
@@ -633,6 +633,8 @@ int vmw_kms_readback(struct vmw_private *dev_priv, | |||
633 | struct drm_vmw_fence_rep __user *user_fence_rep, | 633 | struct drm_vmw_fence_rep __user *user_fence_rep, |
634 | struct drm_vmw_rect *clips, | 634 | struct drm_vmw_rect *clips, |
635 | uint32_t num_clips); | 635 | uint32_t num_clips); |
636 | int vmw_kms_update_layout_ioctl(struct drm_device *dev, void *data, | ||
637 | struct drm_file *file_priv); | ||
636 | 638 | ||
637 | /** | 639 | /** |
638 | * Overlay control - vmwgfx_overlay.c | 640 | * Overlay control - vmwgfx_overlay.c |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c index 8b14dfd513a1..03daefa73397 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | |||
@@ -111,6 +111,7 @@ int vmw_du_crtc_cursor_set(struct drm_crtc *crtc, struct drm_file *file_priv, | |||
111 | if (!ret) { | 111 | if (!ret) { |
112 | if (!surface->snooper.image) { | 112 | if (!surface->snooper.image) { |
113 | DRM_ERROR("surface not suitable for cursor\n"); | 113 | DRM_ERROR("surface not suitable for cursor\n"); |
114 | vmw_surface_unreference(&surface); | ||
114 | return -EINVAL; | 115 | return -EINVAL; |
115 | } | 116 | } |
116 | } else { | 117 | } else { |
@@ -176,7 +177,9 @@ err_unreserve: | |||
176 | return 0; | 177 | return 0; |
177 | } | 178 | } |
178 | 179 | ||
179 | vmw_cursor_update_position(dev_priv, true, du->cursor_x, du->cursor_y); | 180 | vmw_cursor_update_position(dev_priv, true, |
181 | du->cursor_x + du->hotspot_x, | ||
182 | du->cursor_y + du->hotspot_y); | ||
180 | 183 | ||
181 | return 0; | 184 | return 0; |
182 | } | 185 | } |
@@ -191,7 +194,8 @@ int vmw_du_crtc_cursor_move(struct drm_crtc *crtc, int x, int y) | |||
191 | du->cursor_y = y + crtc->y; | 194 | du->cursor_y = y + crtc->y; |
192 | 195 | ||
193 | vmw_cursor_update_position(dev_priv, shown, | 196 | vmw_cursor_update_position(dev_priv, shown, |
194 | du->cursor_x, du->cursor_y); | 197 | du->cursor_x + du->hotspot_x, |
198 | du->cursor_y + du->hotspot_y); | ||
195 | 199 | ||
196 | return 0; | 200 | return 0; |
197 | } | 201 | } |
@@ -212,7 +216,7 @@ void vmw_kms_cursor_snoop(struct vmw_surface *srf, | |||
212 | SVGA3dCmdHeader header; | 216 | SVGA3dCmdHeader header; |
213 | SVGA3dCmdSurfaceDMA dma; | 217 | SVGA3dCmdSurfaceDMA dma; |
214 | } *cmd; | 218 | } *cmd; |
215 | int ret; | 219 | int i, ret; |
216 | 220 | ||
217 | cmd = container_of(header, struct vmw_dma_cmd, header); | 221 | cmd = container_of(header, struct vmw_dma_cmd, header); |
218 | 222 | ||
@@ -234,16 +238,19 @@ void vmw_kms_cursor_snoop(struct vmw_surface *srf, | |||
234 | box_count = (cmd->header.size - sizeof(SVGA3dCmdSurfaceDMA)) / | 238 | box_count = (cmd->header.size - sizeof(SVGA3dCmdSurfaceDMA)) / |
235 | sizeof(SVGA3dCopyBox); | 239 | sizeof(SVGA3dCopyBox); |
236 | 240 | ||
237 | if (cmd->dma.guest.pitch != (64 * 4) || | 241 | if (cmd->dma.guest.ptr.offset % PAGE_SIZE || |
238 | cmd->dma.guest.ptr.offset % PAGE_SIZE || | ||
239 | box->x != 0 || box->y != 0 || box->z != 0 || | 242 | box->x != 0 || box->y != 0 || box->z != 0 || |
240 | box->srcx != 0 || box->srcy != 0 || box->srcz != 0 || | 243 | box->srcx != 0 || box->srcy != 0 || box->srcz != 0 || |
241 | box->w != 64 || box->h != 64 || box->d != 1 || | 244 | box->d != 1 || box_count != 1) { |
242 | box_count != 1) { | ||
243 | /* TODO handle none page aligned offsets */ | 245 | /* TODO handle none page aligned offsets */ |
244 | /* TODO handle partial uploads and pitch != 256 */ | 246 | /* TODO handle more dst & src != 0 */ |
245 | /* TODO handle more then one copy (size != 64) */ | 247 | /* TODO handle more then one copy */ |
246 | DRM_ERROR("lazy programmer, can't handle weird stuff\n"); | 248 | DRM_ERROR("Cant snoop dma request for cursor!\n"); |
249 | DRM_ERROR("(%u, %u, %u) (%u, %u, %u) (%ux%ux%u) %u %u\n", | ||
250 | box->srcx, box->srcy, box->srcz, | ||
251 | box->x, box->y, box->z, | ||
252 | box->w, box->h, box->d, box_count, | ||
253 | cmd->dma.guest.ptr.offset); | ||
247 | return; | 254 | return; |
248 | } | 255 | } |
249 | 256 | ||
@@ -262,7 +269,16 @@ void vmw_kms_cursor_snoop(struct vmw_surface *srf, | |||
262 | 269 | ||
263 | virtual = ttm_kmap_obj_virtual(&map, &dummy); | 270 | virtual = ttm_kmap_obj_virtual(&map, &dummy); |
264 | 271 | ||
265 | memcpy(srf->snooper.image, virtual, 64*64*4); | 272 | if (box->w == 64 && cmd->dma.guest.pitch == 64*4) { |
273 | memcpy(srf->snooper.image, virtual, 64*64*4); | ||
274 | } else { | ||
275 | /* Image is unsigned pointer. */ | ||
276 | for (i = 0; i < box->h; i++) | ||
277 | memcpy(srf->snooper.image + i * 64, | ||
278 | virtual + i * cmd->dma.guest.pitch, | ||
279 | box->w * 4); | ||
280 | } | ||
281 | |||
266 | srf->snooper.age++; | 282 | srf->snooper.age++; |
267 | 283 | ||
268 | /* we can't call this function from this function since execbuf has | 284 | /* we can't call this function from this function since execbuf has |
@@ -994,7 +1010,7 @@ static struct drm_framebuffer *vmw_kms_fb_create(struct drm_device *dev, | |||
994 | required_size = mode_cmd->pitch * mode_cmd->height; | 1010 | required_size = mode_cmd->pitch * mode_cmd->height; |
995 | if (unlikely(required_size > (u64) dev_priv->vram_size)) { | 1011 | if (unlikely(required_size > (u64) dev_priv->vram_size)) { |
996 | DRM_ERROR("VRAM size is too small for requested mode.\n"); | 1012 | DRM_ERROR("VRAM size is too small for requested mode.\n"); |
997 | return NULL; | 1013 | return ERR_PTR(-ENOMEM); |
998 | } | 1014 | } |
999 | 1015 | ||
1000 | /* | 1016 | /* |
@@ -1517,6 +1533,8 @@ int vmw_du_update_layout(struct vmw_private *dev_priv, unsigned num, | |||
1517 | du->pref_width = rects[du->unit].w; | 1533 | du->pref_width = rects[du->unit].w; |
1518 | du->pref_height = rects[du->unit].h; | 1534 | du->pref_height = rects[du->unit].h; |
1519 | du->pref_active = true; | 1535 | du->pref_active = true; |
1536 | du->gui_x = rects[du->unit].x; | ||
1537 | du->gui_y = rects[du->unit].y; | ||
1520 | } else { | 1538 | } else { |
1521 | du->pref_width = 800; | 1539 | du->pref_width = 800; |
1522 | du->pref_height = 600; | 1540 | du->pref_height = 600; |
@@ -1572,12 +1590,14 @@ vmw_du_connector_detect(struct drm_connector *connector, bool force) | |||
1572 | uint32_t num_displays; | 1590 | uint32_t num_displays; |
1573 | struct drm_device *dev = connector->dev; | 1591 | struct drm_device *dev = connector->dev; |
1574 | struct vmw_private *dev_priv = vmw_priv(dev); | 1592 | struct vmw_private *dev_priv = vmw_priv(dev); |
1593 | struct vmw_display_unit *du = vmw_connector_to_du(connector); | ||
1575 | 1594 | ||
1576 | mutex_lock(&dev_priv->hw_mutex); | 1595 | mutex_lock(&dev_priv->hw_mutex); |
1577 | num_displays = vmw_read(dev_priv, SVGA_REG_NUM_DISPLAYS); | 1596 | num_displays = vmw_read(dev_priv, SVGA_REG_NUM_DISPLAYS); |
1578 | mutex_unlock(&dev_priv->hw_mutex); | 1597 | mutex_unlock(&dev_priv->hw_mutex); |
1579 | 1598 | ||
1580 | return ((vmw_connector_to_du(connector)->unit < num_displays) ? | 1599 | return ((vmw_connector_to_du(connector)->unit < num_displays && |
1600 | du->pref_active) ? | ||
1581 | connector_status_connected : connector_status_disconnected); | 1601 | connector_status_connected : connector_status_disconnected); |
1582 | } | 1602 | } |
1583 | 1603 | ||
@@ -1658,6 +1678,28 @@ static struct drm_display_mode vmw_kms_connector_builtin[] = { | |||
1658 | { DRM_MODE("", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) }, | 1678 | { DRM_MODE("", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) }, |
1659 | }; | 1679 | }; |
1660 | 1680 | ||
1681 | /** | ||
1682 | * vmw_guess_mode_timing - Provide fake timings for a | ||
1683 | * 60Hz vrefresh mode. | ||
1684 | * | ||
1685 | * @mode - Pointer to a struct drm_display_mode with hdisplay and vdisplay | ||
1686 | * members filled in. | ||
1687 | */ | ||
1688 | static void vmw_guess_mode_timing(struct drm_display_mode *mode) | ||
1689 | { | ||
1690 | mode->hsync_start = mode->hdisplay + 50; | ||
1691 | mode->hsync_end = mode->hsync_start + 50; | ||
1692 | mode->htotal = mode->hsync_end + 50; | ||
1693 | |||
1694 | mode->vsync_start = mode->vdisplay + 50; | ||
1695 | mode->vsync_end = mode->vsync_start + 50; | ||
1696 | mode->vtotal = mode->vsync_end + 50; | ||
1697 | |||
1698 | mode->clock = (u32)mode->htotal * (u32)mode->vtotal / 100 * 6; | ||
1699 | mode->vrefresh = drm_mode_vrefresh(mode); | ||
1700 | } | ||
1701 | |||
1702 | |||
1661 | int vmw_du_connector_fill_modes(struct drm_connector *connector, | 1703 | int vmw_du_connector_fill_modes(struct drm_connector *connector, |
1662 | uint32_t max_width, uint32_t max_height) | 1704 | uint32_t max_width, uint32_t max_height) |
1663 | { | 1705 | { |
@@ -1680,18 +1722,23 @@ int vmw_du_connector_fill_modes(struct drm_connector *connector, | |||
1680 | return 0; | 1722 | return 0; |
1681 | mode->hdisplay = du->pref_width; | 1723 | mode->hdisplay = du->pref_width; |
1682 | mode->vdisplay = du->pref_height; | 1724 | mode->vdisplay = du->pref_height; |
1683 | mode->vrefresh = drm_mode_vrefresh(mode); | 1725 | vmw_guess_mode_timing(mode); |
1726 | |||
1684 | if (vmw_kms_validate_mode_vram(dev_priv, mode->hdisplay * 2, | 1727 | if (vmw_kms_validate_mode_vram(dev_priv, mode->hdisplay * 2, |
1685 | mode->vdisplay)) { | 1728 | mode->vdisplay)) { |
1686 | drm_mode_probed_add(connector, mode); | 1729 | drm_mode_probed_add(connector, mode); |
1730 | } else { | ||
1731 | drm_mode_destroy(dev, mode); | ||
1732 | mode = NULL; | ||
1733 | } | ||
1687 | 1734 | ||
1688 | if (du->pref_mode) { | 1735 | if (du->pref_mode) { |
1689 | list_del_init(&du->pref_mode->head); | 1736 | list_del_init(&du->pref_mode->head); |
1690 | drm_mode_destroy(dev, du->pref_mode); | 1737 | drm_mode_destroy(dev, du->pref_mode); |
1691 | } | ||
1692 | |||
1693 | du->pref_mode = mode; | ||
1694 | } | 1738 | } |
1739 | |||
1740 | /* mode might be null here, this is intended */ | ||
1741 | du->pref_mode = mode; | ||
1695 | } | 1742 | } |
1696 | 1743 | ||
1697 | for (i = 0; vmw_kms_connector_builtin[i].type != 0; i++) { | 1744 | for (i = 0; vmw_kms_connector_builtin[i].type != 0; i++) { |
@@ -1712,6 +1759,10 @@ int vmw_du_connector_fill_modes(struct drm_connector *connector, | |||
1712 | drm_mode_probed_add(connector, mode); | 1759 | drm_mode_probed_add(connector, mode); |
1713 | } | 1760 | } |
1714 | 1761 | ||
1762 | /* Move the prefered mode first, help apps pick the right mode. */ | ||
1763 | if (du->pref_mode) | ||
1764 | list_move(&du->pref_mode->head, &connector->probed_modes); | ||
1765 | |||
1715 | drm_mode_connector_list_update(connector); | 1766 | drm_mode_connector_list_update(connector); |
1716 | 1767 | ||
1717 | return 1; | 1768 | return 1; |
@@ -1723,3 +1774,63 @@ int vmw_du_connector_set_property(struct drm_connector *connector, | |||
1723 | { | 1774 | { |
1724 | return 0; | 1775 | return 0; |
1725 | } | 1776 | } |
1777 | |||
1778 | |||
1779 | int vmw_kms_update_layout_ioctl(struct drm_device *dev, void *data, | ||
1780 | struct drm_file *file_priv) | ||
1781 | { | ||
1782 | struct vmw_private *dev_priv = vmw_priv(dev); | ||
1783 | struct drm_vmw_update_layout_arg *arg = | ||
1784 | (struct drm_vmw_update_layout_arg *)data; | ||
1785 | struct vmw_master *vmaster = vmw_master(file_priv->master); | ||
1786 | void __user *user_rects; | ||
1787 | struct drm_vmw_rect *rects; | ||
1788 | unsigned rects_size; | ||
1789 | int ret; | ||
1790 | int i; | ||
1791 | struct drm_mode_config *mode_config = &dev->mode_config; | ||
1792 | |||
1793 | ret = ttm_read_lock(&vmaster->lock, true); | ||
1794 | if (unlikely(ret != 0)) | ||
1795 | return ret; | ||
1796 | |||
1797 | if (!arg->num_outputs) { | ||
1798 | struct drm_vmw_rect def_rect = {0, 0, 800, 600}; | ||
1799 | vmw_du_update_layout(dev_priv, 1, &def_rect); | ||
1800 | goto out_unlock; | ||
1801 | } | ||
1802 | |||
1803 | rects_size = arg->num_outputs * sizeof(struct drm_vmw_rect); | ||
1804 | rects = kzalloc(rects_size, GFP_KERNEL); | ||
1805 | if (unlikely(!rects)) { | ||
1806 | ret = -ENOMEM; | ||
1807 | goto out_unlock; | ||
1808 | } | ||
1809 | |||
1810 | user_rects = (void __user *)(unsigned long)arg->rects; | ||
1811 | ret = copy_from_user(rects, user_rects, rects_size); | ||
1812 | if (unlikely(ret != 0)) { | ||
1813 | DRM_ERROR("Failed to get rects.\n"); | ||
1814 | ret = -EFAULT; | ||
1815 | goto out_free; | ||
1816 | } | ||
1817 | |||
1818 | for (i = 0; i < arg->num_outputs; ++i) { | ||
1819 | if (rects->x < 0 || | ||
1820 | rects->y < 0 || | ||
1821 | rects->x + rects->w > mode_config->max_width || | ||
1822 | rects->y + rects->h > mode_config->max_height) { | ||
1823 | DRM_ERROR("Invalid GUI layout.\n"); | ||
1824 | ret = -EINVAL; | ||
1825 | goto out_free; | ||
1826 | } | ||
1827 | } | ||
1828 | |||
1829 | vmw_du_update_layout(dev_priv, arg->num_outputs, rects); | ||
1830 | |||
1831 | out_free: | ||
1832 | kfree(rects); | ||
1833 | out_unlock: | ||
1834 | ttm_read_unlock(&vmaster->lock); | ||
1835 | return ret; | ||
1836 | } | ||
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h index db0b901f8c3f..af8e6e5bd964 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h | |||
@@ -96,6 +96,13 @@ struct vmw_display_unit { | |||
96 | unsigned pref_height; | 96 | unsigned pref_height; |
97 | bool pref_active; | 97 | bool pref_active; |
98 | struct drm_display_mode *pref_mode; | 98 | struct drm_display_mode *pref_mode; |
99 | |||
100 | /* | ||
101 | * Gui positioning | ||
102 | */ | ||
103 | int gui_x; | ||
104 | int gui_y; | ||
105 | bool is_implicit; | ||
99 | }; | 106 | }; |
100 | 107 | ||
101 | #define vmw_crtc_to_du(x) \ | 108 | #define vmw_crtc_to_du(x) \ |
@@ -126,8 +133,7 @@ int vmw_du_connector_fill_modes(struct drm_connector *connector, | |||
126 | int vmw_du_connector_set_property(struct drm_connector *connector, | 133 | int vmw_du_connector_set_property(struct drm_connector *connector, |
127 | struct drm_property *property, | 134 | struct drm_property *property, |
128 | uint64_t val); | 135 | uint64_t val); |
129 | int vmw_du_update_layout(struct vmw_private *dev_priv, unsigned num, | 136 | |
130 | struct drm_vmw_rect *rects); | ||
131 | 137 | ||
132 | /* | 138 | /* |
133 | * Legacy display unit functions - vmwgfx_ldu.c | 139 | * Legacy display unit functions - vmwgfx_ldu.c |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c index 92f56bc594eb..90c5e3928491 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c | |||
@@ -337,13 +337,14 @@ static int vmw_ldu_init(struct vmw_private *dev_priv, unsigned unit) | |||
337 | ldu->base.pref_width = 800; | 337 | ldu->base.pref_width = 800; |
338 | ldu->base.pref_height = 600; | 338 | ldu->base.pref_height = 600; |
339 | ldu->base.pref_mode = NULL; | 339 | ldu->base.pref_mode = NULL; |
340 | ldu->base.is_implicit = true; | ||
340 | 341 | ||
341 | drm_connector_init(dev, connector, &vmw_legacy_connector_funcs, | 342 | drm_connector_init(dev, connector, &vmw_legacy_connector_funcs, |
342 | DRM_MODE_CONNECTOR_LVDS); | 343 | DRM_MODE_CONNECTOR_VIRTUAL); |
343 | connector->status = vmw_du_connector_detect(connector, true); | 344 | connector->status = vmw_du_connector_detect(connector, true); |
344 | 345 | ||
345 | drm_encoder_init(dev, encoder, &vmw_legacy_encoder_funcs, | 346 | drm_encoder_init(dev, encoder, &vmw_legacy_encoder_funcs, |
346 | DRM_MODE_ENCODER_LVDS); | 347 | DRM_MODE_ENCODER_VIRTUAL); |
347 | drm_mode_connector_attach_encoder(connector, encoder); | 348 | drm_mode_connector_attach_encoder(connector, encoder); |
348 | encoder->possible_crtcs = (1 << unit); | 349 | encoder->possible_crtcs = (1 << unit); |
349 | encoder->possible_clones = 0; | 350 | encoder->possible_clones = 0; |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c b/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c index 477b2a9eb3c2..4defdcf1c72e 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c | |||
@@ -36,12 +36,9 @@ | |||
36 | container_of(x, struct vmw_screen_object_unit, base.connector) | 36 | container_of(x, struct vmw_screen_object_unit, base.connector) |
37 | 37 | ||
38 | struct vmw_screen_object_display { | 38 | struct vmw_screen_object_display { |
39 | struct list_head active; | 39 | unsigned num_implicit; |
40 | 40 | ||
41 | unsigned num_active; | 41 | struct vmw_framebuffer *implicit_fb; |
42 | unsigned last_num_active; | ||
43 | |||
44 | struct vmw_framebuffer *fb; | ||
45 | }; | 42 | }; |
46 | 43 | ||
47 | /** | 44 | /** |
@@ -54,13 +51,11 @@ struct vmw_screen_object_unit { | |||
54 | struct vmw_dma_buffer *buffer; /**< Backing store buffer */ | 51 | struct vmw_dma_buffer *buffer; /**< Backing store buffer */ |
55 | 52 | ||
56 | bool defined; | 53 | bool defined; |
57 | 54 | bool active_implicit; | |
58 | struct list_head active; | ||
59 | }; | 55 | }; |
60 | 56 | ||
61 | static void vmw_sou_destroy(struct vmw_screen_object_unit *sou) | 57 | static void vmw_sou_destroy(struct vmw_screen_object_unit *sou) |
62 | { | 58 | { |
63 | list_del_init(&sou->active); | ||
64 | vmw_display_unit_cleanup(&sou->base); | 59 | vmw_display_unit_cleanup(&sou->base); |
65 | kfree(sou); | 60 | kfree(sou); |
66 | } | 61 | } |
@@ -75,58 +70,31 @@ static void vmw_sou_crtc_destroy(struct drm_crtc *crtc) | |||
75 | vmw_sou_destroy(vmw_crtc_to_sou(crtc)); | 70 | vmw_sou_destroy(vmw_crtc_to_sou(crtc)); |
76 | } | 71 | } |
77 | 72 | ||
78 | static int vmw_sou_del_active(struct vmw_private *vmw_priv, | 73 | static void vmw_sou_del_active(struct vmw_private *vmw_priv, |
79 | struct vmw_screen_object_unit *sou) | 74 | struct vmw_screen_object_unit *sou) |
80 | { | 75 | { |
81 | struct vmw_screen_object_display *ld = vmw_priv->sou_priv; | 76 | struct vmw_screen_object_display *ld = vmw_priv->sou_priv; |
82 | if (list_empty(&sou->active)) | ||
83 | return 0; | ||
84 | 77 | ||
85 | /* Must init otherwise list_empty(&sou->active) will not work. */ | 78 | if (sou->active_implicit) { |
86 | list_del_init(&sou->active); | 79 | if (--(ld->num_implicit) == 0) |
87 | if (--(ld->num_active) == 0) { | 80 | ld->implicit_fb = NULL; |
88 | BUG_ON(!ld->fb); | 81 | sou->active_implicit = false; |
89 | if (ld->fb->unpin) | ||
90 | ld->fb->unpin(ld->fb); | ||
91 | ld->fb = NULL; | ||
92 | } | 82 | } |
93 | |||
94 | return 0; | ||
95 | } | 83 | } |
96 | 84 | ||
97 | static int vmw_sou_add_active(struct vmw_private *vmw_priv, | 85 | static void vmw_sou_add_active(struct vmw_private *vmw_priv, |
98 | struct vmw_screen_object_unit *sou, | 86 | struct vmw_screen_object_unit *sou, |
99 | struct vmw_framebuffer *vfb) | 87 | struct vmw_framebuffer *vfb) |
100 | { | 88 | { |
101 | struct vmw_screen_object_display *ld = vmw_priv->sou_priv; | 89 | struct vmw_screen_object_display *ld = vmw_priv->sou_priv; |
102 | struct vmw_screen_object_unit *entry; | ||
103 | struct list_head *at; | ||
104 | |||
105 | BUG_ON(!ld->num_active && ld->fb); | ||
106 | if (vfb != ld->fb) { | ||
107 | if (ld->fb && ld->fb->unpin) | ||
108 | ld->fb->unpin(ld->fb); | ||
109 | if (vfb->pin) | ||
110 | vfb->pin(vfb); | ||
111 | ld->fb = vfb; | ||
112 | } | ||
113 | |||
114 | if (!list_empty(&sou->active)) | ||
115 | return 0; | ||
116 | 90 | ||
117 | at = &ld->active; | 91 | BUG_ON(!ld->num_implicit && ld->implicit_fb); |
118 | list_for_each_entry(entry, &ld->active, active) { | ||
119 | if (entry->base.unit > sou->base.unit) | ||
120 | break; | ||
121 | 92 | ||
122 | at = &entry->active; | 93 | if (!sou->active_implicit && sou->base.is_implicit) { |
94 | ld->implicit_fb = vfb; | ||
95 | sou->active_implicit = true; | ||
96 | ld->num_implicit++; | ||
123 | } | 97 | } |
124 | |||
125 | list_add(&sou->active, at); | ||
126 | |||
127 | ld->num_active++; | ||
128 | |||
129 | return 0; | ||
130 | } | 98 | } |
131 | 99 | ||
132 | /** | 100 | /** |
@@ -164,8 +132,13 @@ static int vmw_sou_fifo_create(struct vmw_private *dev_priv, | |||
164 | (sou->base.unit == 0 ? SVGA_SCREEN_IS_PRIMARY : 0); | 132 | (sou->base.unit == 0 ? SVGA_SCREEN_IS_PRIMARY : 0); |
165 | cmd->obj.size.width = mode->hdisplay; | 133 | cmd->obj.size.width = mode->hdisplay; |
166 | cmd->obj.size.height = mode->vdisplay; | 134 | cmd->obj.size.height = mode->vdisplay; |
167 | cmd->obj.root.x = x; | 135 | if (sou->base.is_implicit) { |
168 | cmd->obj.root.y = y; | 136 | cmd->obj.root.x = x; |
137 | cmd->obj.root.y = y; | ||
138 | } else { | ||
139 | cmd->obj.root.x = sou->base.gui_x; | ||
140 | cmd->obj.root.y = sou->base.gui_y; | ||
141 | } | ||
169 | 142 | ||
170 | /* Ok to assume that buffer is pinned in vram */ | 143 | /* Ok to assume that buffer is pinned in vram */ |
171 | vmw_bo_get_guest_ptr(&sou->buffer->base, &cmd->obj.backingStore.ptr); | 144 | vmw_bo_get_guest_ptr(&sou->buffer->base, &cmd->obj.backingStore.ptr); |
@@ -312,10 +285,11 @@ static int vmw_sou_crtc_set_config(struct drm_mode_set *set) | |||
312 | } | 285 | } |
313 | 286 | ||
314 | /* sou only supports one fb active at the time */ | 287 | /* sou only supports one fb active at the time */ |
315 | if (dev_priv->sou_priv->fb && vfb && | 288 | if (sou->base.is_implicit && |
316 | !(dev_priv->sou_priv->num_active == 1 && | 289 | dev_priv->sou_priv->implicit_fb && vfb && |
317 | !list_empty(&sou->active)) && | 290 | !(dev_priv->sou_priv->num_implicit == 1 && |
318 | dev_priv->sou_priv->fb != vfb) { | 291 | sou->active_implicit) && |
292 | dev_priv->sou_priv->implicit_fb != vfb) { | ||
319 | DRM_ERROR("Multiple framebuffers not supported\n"); | 293 | DRM_ERROR("Multiple framebuffers not supported\n"); |
320 | return -EINVAL; | 294 | return -EINVAL; |
321 | } | 295 | } |
@@ -471,19 +445,20 @@ static int vmw_sou_init(struct vmw_private *dev_priv, unsigned unit) | |||
471 | encoder = &sou->base.encoder; | 445 | encoder = &sou->base.encoder; |
472 | connector = &sou->base.connector; | 446 | connector = &sou->base.connector; |
473 | 447 | ||
474 | INIT_LIST_HEAD(&sou->active); | 448 | sou->active_implicit = false; |
475 | 449 | ||
476 | sou->base.pref_active = (unit == 0); | 450 | sou->base.pref_active = (unit == 0); |
477 | sou->base.pref_width = 800; | 451 | sou->base.pref_width = 800; |
478 | sou->base.pref_height = 600; | 452 | sou->base.pref_height = 600; |
479 | sou->base.pref_mode = NULL; | 453 | sou->base.pref_mode = NULL; |
454 | sou->base.is_implicit = true; | ||
480 | 455 | ||
481 | drm_connector_init(dev, connector, &vmw_legacy_connector_funcs, | 456 | drm_connector_init(dev, connector, &vmw_legacy_connector_funcs, |
482 | DRM_MODE_CONNECTOR_LVDS); | 457 | DRM_MODE_CONNECTOR_VIRTUAL); |
483 | connector->status = vmw_du_connector_detect(connector, true); | 458 | connector->status = vmw_du_connector_detect(connector, true); |
484 | 459 | ||
485 | drm_encoder_init(dev, encoder, &vmw_screen_object_encoder_funcs, | 460 | drm_encoder_init(dev, encoder, &vmw_screen_object_encoder_funcs, |
486 | DRM_MODE_ENCODER_LVDS); | 461 | DRM_MODE_ENCODER_VIRTUAL); |
487 | drm_mode_connector_attach_encoder(connector, encoder); | 462 | drm_mode_connector_attach_encoder(connector, encoder); |
488 | encoder->possible_crtcs = (1 << unit); | 463 | encoder->possible_crtcs = (1 << unit); |
489 | encoder->possible_clones = 0; | 464 | encoder->possible_clones = 0; |
@@ -520,10 +495,8 @@ int vmw_kms_init_screen_object_display(struct vmw_private *dev_priv) | |||
520 | if (unlikely(!dev_priv->sou_priv)) | 495 | if (unlikely(!dev_priv->sou_priv)) |
521 | goto err_no_mem; | 496 | goto err_no_mem; |
522 | 497 | ||
523 | INIT_LIST_HEAD(&dev_priv->sou_priv->active); | 498 | dev_priv->sou_priv->num_implicit = 0; |
524 | dev_priv->sou_priv->num_active = 0; | 499 | dev_priv->sou_priv->implicit_fb = NULL; |
525 | dev_priv->sou_priv->last_num_active = 0; | ||
526 | dev_priv->sou_priv->fb = NULL; | ||
527 | 500 | ||
528 | ret = drm_vblank_init(dev, VMWGFX_NUM_DISPLAY_UNITS); | 501 | ret = drm_vblank_init(dev, VMWGFX_NUM_DISPLAY_UNITS); |
529 | if (unlikely(ret != 0)) | 502 | if (unlikely(ret != 0)) |
@@ -558,9 +531,6 @@ int vmw_kms_close_screen_object_display(struct vmw_private *dev_priv) | |||
558 | 531 | ||
559 | drm_vblank_cleanup(dev); | 532 | drm_vblank_cleanup(dev); |
560 | 533 | ||
561 | if (!list_empty(&dev_priv->sou_priv->active)) | ||
562 | DRM_ERROR("Still have active outputs when unloading driver"); | ||
563 | |||
564 | kfree(dev_priv->sou_priv); | 534 | kfree(dev_priv->sou_priv); |
565 | 535 | ||
566 | return 0; | 536 | return 0; |
diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h index 0d2f727e96be..93df2d72750b 100644 --- a/include/drm/drm_dp_helper.h +++ b/include/drm/drm_dp_helper.h | |||
@@ -72,6 +72,7 @@ | |||
72 | 72 | ||
73 | #define DP_MAIN_LINK_CHANNEL_CODING 0x006 | 73 | #define DP_MAIN_LINK_CHANNEL_CODING 0x006 |
74 | 74 | ||
75 | #define DP_EDP_CONFIGURATION_CAP 0x00d | ||
75 | #define DP_TRAINING_AUX_RD_INTERVAL 0x00e | 76 | #define DP_TRAINING_AUX_RD_INTERVAL 0x00e |
76 | 77 | ||
77 | #define DP_PSR_SUPPORT 0x070 | 78 | #define DP_PSR_SUPPORT 0x070 |
@@ -159,6 +160,8 @@ | |||
159 | # define DP_CP_IRQ (1 << 2) | 160 | # define DP_CP_IRQ (1 << 2) |
160 | # define DP_SINK_SPECIFIC_IRQ (1 << 6) | 161 | # define DP_SINK_SPECIFIC_IRQ (1 << 6) |
161 | 162 | ||
163 | #define DP_EDP_CONFIGURATION_SET 0x10a | ||
164 | |||
162 | #define DP_LANE0_1_STATUS 0x202 | 165 | #define DP_LANE0_1_STATUS 0x202 |
163 | #define DP_LANE2_3_STATUS 0x203 | 166 | #define DP_LANE2_3_STATUS 0x203 |
164 | # define DP_LANE_CR_DONE (1 << 0) | 167 | # define DP_LANE_CR_DONE (1 << 0) |
diff --git a/include/drm/drm_mode.h b/include/drm/drm_mode.h index c4961ea50a49..d30bedfeb7ef 100644 --- a/include/drm/drm_mode.h +++ b/include/drm/drm_mode.h | |||
@@ -120,11 +120,12 @@ struct drm_mode_crtc { | |||
120 | struct drm_mode_modeinfo mode; | 120 | struct drm_mode_modeinfo mode; |
121 | }; | 121 | }; |
122 | 122 | ||
123 | #define DRM_MODE_ENCODER_NONE 0 | 123 | #define DRM_MODE_ENCODER_NONE 0 |
124 | #define DRM_MODE_ENCODER_DAC 1 | 124 | #define DRM_MODE_ENCODER_DAC 1 |
125 | #define DRM_MODE_ENCODER_TMDS 2 | 125 | #define DRM_MODE_ENCODER_TMDS 2 |
126 | #define DRM_MODE_ENCODER_LVDS 3 | 126 | #define DRM_MODE_ENCODER_LVDS 3 |
127 | #define DRM_MODE_ENCODER_TVDAC 4 | 127 | #define DRM_MODE_ENCODER_TVDAC 4 |
128 | #define DRM_MODE_ENCODER_VIRTUAL 5 | ||
128 | 129 | ||
129 | struct drm_mode_get_encoder { | 130 | struct drm_mode_get_encoder { |
130 | __u32 encoder_id; | 131 | __u32 encoder_id; |
@@ -162,6 +163,7 @@ struct drm_mode_get_encoder { | |||
162 | #define DRM_MODE_CONNECTOR_HDMIB 12 | 163 | #define DRM_MODE_CONNECTOR_HDMIB 12 |
163 | #define DRM_MODE_CONNECTOR_TV 13 | 164 | #define DRM_MODE_CONNECTOR_TV 13 |
164 | #define DRM_MODE_CONNECTOR_eDP 14 | 165 | #define DRM_MODE_CONNECTOR_eDP 14 |
166 | #define DRM_MODE_CONNECTOR_VIRTUAL 15 | ||
165 | 167 | ||
166 | struct drm_mode_get_connector { | 168 | struct drm_mode_get_connector { |
167 | 169 | ||
diff --git a/include/drm/vmwgfx_drm.h b/include/drm/vmwgfx_drm.h index cd7cd8162ed6..bcb0912afe7a 100644 --- a/include/drm/vmwgfx_drm.h +++ b/include/drm/vmwgfx_drm.h | |||
@@ -54,7 +54,7 @@ | |||
54 | #define DRM_VMW_FENCE_EVENT 17 | 54 | #define DRM_VMW_FENCE_EVENT 17 |
55 | #define DRM_VMW_PRESENT 18 | 55 | #define DRM_VMW_PRESENT 18 |
56 | #define DRM_VMW_PRESENT_READBACK 19 | 56 | #define DRM_VMW_PRESENT_READBACK 19 |
57 | 57 | #define DRM_VMW_UPDATE_LAYOUT 20 | |
58 | 58 | ||
59 | /*************************************************************************/ | 59 | /*************************************************************************/ |
60 | /** | 60 | /** |
@@ -552,31 +552,6 @@ struct drm_vmw_get_3d_cap_arg { | |||
552 | 552 | ||
553 | /*************************************************************************/ | 553 | /*************************************************************************/ |
554 | /** | 554 | /** |
555 | * DRM_VMW_UPDATE_LAYOUT - Update layout | ||
556 | * | ||
557 | * Updates the preferred modes and connection status for connectors. The | ||
558 | * command conisits of one drm_vmw_update_layout_arg pointing out a array | ||
559 | * of num_outputs drm_vmw_rect's. | ||
560 | */ | ||
561 | |||
562 | /** | ||
563 | * struct drm_vmw_update_layout_arg | ||
564 | * | ||
565 | * @num_outputs: number of active | ||
566 | * @rects: pointer to array of drm_vmw_rect | ||
567 | * | ||
568 | * Input argument to the DRM_VMW_UPDATE_LAYOUT Ioctl. | ||
569 | */ | ||
570 | |||
571 | struct drm_vmw_update_layout_arg { | ||
572 | uint32_t num_outputs; | ||
573 | uint32_t pad64; | ||
574 | uint64_t rects; | ||
575 | }; | ||
576 | |||
577 | |||
578 | /*************************************************************************/ | ||
579 | /** | ||
580 | * DRM_VMW_FENCE_WAIT | 555 | * DRM_VMW_FENCE_WAIT |
581 | * | 556 | * |
582 | * Waits for a fence object to signal. The wait is interruptible, so that | 557 | * Waits for a fence object to signal. The wait is interruptible, so that |
@@ -788,4 +763,28 @@ struct drm_vmw_present_readback_arg { | |||
788 | uint64_t clips_ptr; | 763 | uint64_t clips_ptr; |
789 | uint64_t fence_rep; | 764 | uint64_t fence_rep; |
790 | }; | 765 | }; |
766 | |||
767 | /*************************************************************************/ | ||
768 | /** | ||
769 | * DRM_VMW_UPDATE_LAYOUT - Update layout | ||
770 | * | ||
771 | * Updates the preferred modes and connection status for connectors. The | ||
772 | * command consists of one drm_vmw_update_layout_arg pointing to an array | ||
773 | * of num_outputs drm_vmw_rect's. | ||
774 | */ | ||
775 | |||
776 | /** | ||
777 | * struct drm_vmw_update_layout_arg | ||
778 | * | ||
779 | * @num_outputs: number of active connectors | ||
780 | * @rects: pointer to array of drm_vmw_rect cast to an uint64_t | ||
781 | * | ||
782 | * Input argument to the DRM_VMW_UPDATE_LAYOUT Ioctl. | ||
783 | */ | ||
784 | struct drm_vmw_update_layout_arg { | ||
785 | uint32_t num_outputs; | ||
786 | uint32_t pad64; | ||
787 | uint64_t rects; | ||
788 | }; | ||
789 | |||
791 | #endif | 790 | #endif |