2 * Copyright 2007-8 Advanced Micro Devices, Inc.
3 * Copyright 2008 Red Hat Inc.
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:
12 * The above copyright notice and this permission notice shall be included in
13 * all copies or substantial portions of the Software.
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.
23 * Authors: Dave Airlie
27 #include <drm/drm_crtc_helper.h>
28 #include <drm/amdgpu_drm.h>
30 #include "amdgpu_connectors.h"
31 #include "amdgpu_display.h"
33 #include "atombios_encoders.h"
36 amdgpu_link_encoder_connector(struct drm_device
*dev
)
38 struct amdgpu_device
*adev
= dev
->dev_private
;
39 struct drm_connector
*connector
;
40 struct drm_connector_list_iter iter
;
41 struct amdgpu_connector
*amdgpu_connector
;
42 struct drm_encoder
*encoder
;
43 struct amdgpu_encoder
*amdgpu_encoder
;
45 drm_connector_list_iter_begin(dev
, &iter
);
46 /* walk the list and link encoders to connectors */
47 drm_for_each_connector_iter(connector
, &iter
) {
48 amdgpu_connector
= to_amdgpu_connector(connector
);
49 list_for_each_entry(encoder
, &dev
->mode_config
.encoder_list
, head
) {
50 amdgpu_encoder
= to_amdgpu_encoder(encoder
);
51 if (amdgpu_encoder
->devices
& amdgpu_connector
->devices
) {
52 drm_connector_attach_encoder(connector
, encoder
);
53 if (amdgpu_encoder
->devices
& (ATOM_DEVICE_LCD_SUPPORT
)) {
54 amdgpu_atombios_encoder_init_backlight(amdgpu_encoder
, connector
);
55 adev
->mode_info
.bl_encoder
= amdgpu_encoder
;
60 drm_connector_list_iter_end(&iter
);
63 void amdgpu_encoder_set_active_device(struct drm_encoder
*encoder
)
65 struct drm_device
*dev
= encoder
->dev
;
66 struct amdgpu_encoder
*amdgpu_encoder
= to_amdgpu_encoder(encoder
);
67 struct drm_connector
*connector
;
68 struct drm_connector_list_iter iter
;
70 drm_connector_list_iter_begin(dev
, &iter
);
71 drm_for_each_connector_iter(connector
, &iter
) {
72 if (connector
->encoder
== encoder
) {
73 struct amdgpu_connector
*amdgpu_connector
= to_amdgpu_connector(connector
);
74 amdgpu_encoder
->active_device
= amdgpu_encoder
->devices
& amdgpu_connector
->devices
;
75 DRM_DEBUG_KMS("setting active device to %08x from %08x %08x for encoder %d\n",
76 amdgpu_encoder
->active_device
, amdgpu_encoder
->devices
,
77 amdgpu_connector
->devices
, encoder
->encoder_type
);
80 drm_connector_list_iter_end(&iter
);
83 struct drm_connector
*
84 amdgpu_get_connector_for_encoder(struct drm_encoder
*encoder
)
86 struct drm_device
*dev
= encoder
->dev
;
87 struct amdgpu_encoder
*amdgpu_encoder
= to_amdgpu_encoder(encoder
);
88 struct drm_connector
*connector
, *found
= NULL
;
89 struct drm_connector_list_iter iter
;
90 struct amdgpu_connector
*amdgpu_connector
;
92 drm_connector_list_iter_begin(dev
, &iter
);
93 drm_for_each_connector_iter(connector
, &iter
) {
94 amdgpu_connector
= to_amdgpu_connector(connector
);
95 if (amdgpu_encoder
->active_device
& amdgpu_connector
->devices
) {
100 drm_connector_list_iter_end(&iter
);
104 struct drm_connector
*
105 amdgpu_get_connector_for_encoder_init(struct drm_encoder
*encoder
)
107 struct drm_device
*dev
= encoder
->dev
;
108 struct amdgpu_encoder
*amdgpu_encoder
= to_amdgpu_encoder(encoder
);
109 struct drm_connector
*connector
, *found
= NULL
;
110 struct drm_connector_list_iter iter
;
111 struct amdgpu_connector
*amdgpu_connector
;
113 drm_connector_list_iter_begin(dev
, &iter
);
114 drm_for_each_connector_iter(connector
, &iter
) {
115 amdgpu_connector
= to_amdgpu_connector(connector
);
116 if (amdgpu_encoder
->devices
& amdgpu_connector
->devices
) {
121 drm_connector_list_iter_end(&iter
);
125 struct drm_encoder
*amdgpu_get_external_encoder(struct drm_encoder
*encoder
)
127 struct drm_device
*dev
= encoder
->dev
;
128 struct amdgpu_encoder
*amdgpu_encoder
= to_amdgpu_encoder(encoder
);
129 struct drm_encoder
*other_encoder
;
130 struct amdgpu_encoder
*other_amdgpu_encoder
;
132 if (amdgpu_encoder
->is_ext_encoder
)
135 list_for_each_entry(other_encoder
, &dev
->mode_config
.encoder_list
, head
) {
136 if (other_encoder
== encoder
)
138 other_amdgpu_encoder
= to_amdgpu_encoder(other_encoder
);
139 if (other_amdgpu_encoder
->is_ext_encoder
&&
140 (amdgpu_encoder
->devices
& other_amdgpu_encoder
->devices
))
141 return other_encoder
;
146 u16
amdgpu_encoder_get_dp_bridge_encoder_id(struct drm_encoder
*encoder
)
148 struct drm_encoder
*other_encoder
= amdgpu_get_external_encoder(encoder
);
151 struct amdgpu_encoder
*amdgpu_encoder
= to_amdgpu_encoder(other_encoder
);
153 switch (amdgpu_encoder
->encoder_id
) {
154 case ENCODER_OBJECT_ID_TRAVIS
:
155 case ENCODER_OBJECT_ID_NUTMEG
:
156 return amdgpu_encoder
->encoder_id
;
158 return ENCODER_OBJECT_ID_NONE
;
161 return ENCODER_OBJECT_ID_NONE
;
164 void amdgpu_panel_mode_fixup(struct drm_encoder
*encoder
,
165 struct drm_display_mode
*adjusted_mode
)
167 struct amdgpu_encoder
*amdgpu_encoder
= to_amdgpu_encoder(encoder
);
168 struct drm_display_mode
*native_mode
= &amdgpu_encoder
->native_mode
;
169 unsigned hblank
= native_mode
->htotal
- native_mode
->hdisplay
;
170 unsigned vblank
= native_mode
->vtotal
- native_mode
->vdisplay
;
171 unsigned hover
= native_mode
->hsync_start
- native_mode
->hdisplay
;
172 unsigned vover
= native_mode
->vsync_start
- native_mode
->vdisplay
;
173 unsigned hsync_width
= native_mode
->hsync_end
- native_mode
->hsync_start
;
174 unsigned vsync_width
= native_mode
->vsync_end
- native_mode
->vsync_start
;
176 adjusted_mode
->clock
= native_mode
->clock
;
177 adjusted_mode
->flags
= native_mode
->flags
;
179 adjusted_mode
->hdisplay
= native_mode
->hdisplay
;
180 adjusted_mode
->vdisplay
= native_mode
->vdisplay
;
182 adjusted_mode
->htotal
= native_mode
->hdisplay
+ hblank
;
183 adjusted_mode
->hsync_start
= native_mode
->hdisplay
+ hover
;
184 adjusted_mode
->hsync_end
= adjusted_mode
->hsync_start
+ hsync_width
;
186 adjusted_mode
->vtotal
= native_mode
->vdisplay
+ vblank
;
187 adjusted_mode
->vsync_start
= native_mode
->vdisplay
+ vover
;
188 adjusted_mode
->vsync_end
= adjusted_mode
->vsync_start
+ vsync_width
;
190 drm_mode_set_crtcinfo(adjusted_mode
, CRTC_INTERLACE_HALVE_V
);
192 adjusted_mode
->crtc_hdisplay
= native_mode
->hdisplay
;
193 adjusted_mode
->crtc_vdisplay
= native_mode
->vdisplay
;
195 adjusted_mode
->crtc_htotal
= adjusted_mode
->crtc_hdisplay
+ hblank
;
196 adjusted_mode
->crtc_hsync_start
= adjusted_mode
->crtc_hdisplay
+ hover
;
197 adjusted_mode
->crtc_hsync_end
= adjusted_mode
->crtc_hsync_start
+ hsync_width
;
199 adjusted_mode
->crtc_vtotal
= adjusted_mode
->crtc_vdisplay
+ vblank
;
200 adjusted_mode
->crtc_vsync_start
= adjusted_mode
->crtc_vdisplay
+ vover
;
201 adjusted_mode
->crtc_vsync_end
= adjusted_mode
->crtc_vsync_start
+ vsync_width
;
205 bool amdgpu_dig_monitor_is_duallink(struct drm_encoder
*encoder
,
208 struct drm_connector
*connector
;
209 struct amdgpu_connector
*amdgpu_connector
;
210 struct amdgpu_connector_atom_dig
*dig_connector
;
212 connector
= amdgpu_get_connector_for_encoder(encoder
);
213 /* if we don't have an active device yet, just use one of
214 * the connectors tied to the encoder.
217 connector
= amdgpu_get_connector_for_encoder_init(encoder
);
218 amdgpu_connector
= to_amdgpu_connector(connector
);
220 switch (connector
->connector_type
) {
221 case DRM_MODE_CONNECTOR_DVII
:
222 case DRM_MODE_CONNECTOR_HDMIB
:
223 if (amdgpu_connector
->use_digital
) {
224 /* HDMI 1.3 supports up to 340 Mhz over single link */
225 if (drm_detect_hdmi_monitor(amdgpu_connector_edid(connector
))) {
226 if (pixel_clock
> 340000)
231 if (pixel_clock
> 165000)
238 case DRM_MODE_CONNECTOR_DVID
:
239 case DRM_MODE_CONNECTOR_HDMIA
:
240 case DRM_MODE_CONNECTOR_DisplayPort
:
241 dig_connector
= amdgpu_connector
->con_priv
;
242 if ((dig_connector
->dp_sink_type
== CONNECTOR_OBJECT_ID_DISPLAYPORT
) ||
243 (dig_connector
->dp_sink_type
== CONNECTOR_OBJECT_ID_eDP
))
246 /* HDMI 1.3 supports up to 340 Mhz over single link */
247 if (drm_detect_hdmi_monitor(amdgpu_connector_edid(connector
))) {
248 if (pixel_clock
> 340000)
253 if (pixel_clock
> 165000)