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"
32 #include "atombios_encoders.h"
35 amdgpu_link_encoder_connector(struct drm_device
*dev
)
37 struct amdgpu_device
*adev
= dev
->dev_private
;
38 struct drm_connector
*connector
;
39 struct amdgpu_connector
*amdgpu_connector
;
40 struct drm_encoder
*encoder
;
41 struct amdgpu_encoder
*amdgpu_encoder
;
43 /* walk the list and link encoders to connectors */
44 list_for_each_entry(connector
, &dev
->mode_config
.connector_list
, head
) {
45 amdgpu_connector
= to_amdgpu_connector(connector
);
46 list_for_each_entry(encoder
, &dev
->mode_config
.encoder_list
, head
) {
47 amdgpu_encoder
= to_amdgpu_encoder(encoder
);
48 if (amdgpu_encoder
->devices
& amdgpu_connector
->devices
) {
49 drm_connector_attach_encoder(connector
, encoder
);
50 if (amdgpu_encoder
->devices
& (ATOM_DEVICE_LCD_SUPPORT
)) {
51 amdgpu_atombios_encoder_init_backlight(amdgpu_encoder
, connector
);
52 adev
->mode_info
.bl_encoder
= amdgpu_encoder
;
59 void amdgpu_encoder_set_active_device(struct drm_encoder
*encoder
)
61 struct drm_device
*dev
= encoder
->dev
;
62 struct amdgpu_encoder
*amdgpu_encoder
= to_amdgpu_encoder(encoder
);
63 struct drm_connector
*connector
;
65 list_for_each_entry(connector
, &dev
->mode_config
.connector_list
, head
) {
66 if (connector
->encoder
== encoder
) {
67 struct amdgpu_connector
*amdgpu_connector
= to_amdgpu_connector(connector
);
68 amdgpu_encoder
->active_device
= amdgpu_encoder
->devices
& amdgpu_connector
->devices
;
69 DRM_DEBUG_KMS("setting active device to %08x from %08x %08x for encoder %d\n",
70 amdgpu_encoder
->active_device
, amdgpu_encoder
->devices
,
71 amdgpu_connector
->devices
, encoder
->encoder_type
);
76 struct drm_connector
*
77 amdgpu_get_connector_for_encoder(struct drm_encoder
*encoder
)
79 struct drm_device
*dev
= encoder
->dev
;
80 struct amdgpu_encoder
*amdgpu_encoder
= to_amdgpu_encoder(encoder
);
81 struct drm_connector
*connector
;
82 struct amdgpu_connector
*amdgpu_connector
;
84 list_for_each_entry(connector
, &dev
->mode_config
.connector_list
, head
) {
85 amdgpu_connector
= to_amdgpu_connector(connector
);
86 if (amdgpu_encoder
->active_device
& amdgpu_connector
->devices
)
92 struct drm_connector
*
93 amdgpu_get_connector_for_encoder_init(struct drm_encoder
*encoder
)
95 struct drm_device
*dev
= encoder
->dev
;
96 struct amdgpu_encoder
*amdgpu_encoder
= to_amdgpu_encoder(encoder
);
97 struct drm_connector
*connector
;
98 struct amdgpu_connector
*amdgpu_connector
;
100 list_for_each_entry(connector
, &dev
->mode_config
.connector_list
, head
) {
101 amdgpu_connector
= to_amdgpu_connector(connector
);
102 if (amdgpu_encoder
->devices
& amdgpu_connector
->devices
)
108 struct drm_encoder
*amdgpu_get_external_encoder(struct drm_encoder
*encoder
)
110 struct drm_device
*dev
= encoder
->dev
;
111 struct amdgpu_encoder
*amdgpu_encoder
= to_amdgpu_encoder(encoder
);
112 struct drm_encoder
*other_encoder
;
113 struct amdgpu_encoder
*other_amdgpu_encoder
;
115 if (amdgpu_encoder
->is_ext_encoder
)
118 list_for_each_entry(other_encoder
, &dev
->mode_config
.encoder_list
, head
) {
119 if (other_encoder
== encoder
)
121 other_amdgpu_encoder
= to_amdgpu_encoder(other_encoder
);
122 if (other_amdgpu_encoder
->is_ext_encoder
&&
123 (amdgpu_encoder
->devices
& other_amdgpu_encoder
->devices
))
124 return other_encoder
;
129 u16
amdgpu_encoder_get_dp_bridge_encoder_id(struct drm_encoder
*encoder
)
131 struct drm_encoder
*other_encoder
= amdgpu_get_external_encoder(encoder
);
134 struct amdgpu_encoder
*amdgpu_encoder
= to_amdgpu_encoder(other_encoder
);
136 switch (amdgpu_encoder
->encoder_id
) {
137 case ENCODER_OBJECT_ID_TRAVIS
:
138 case ENCODER_OBJECT_ID_NUTMEG
:
139 return amdgpu_encoder
->encoder_id
;
141 return ENCODER_OBJECT_ID_NONE
;
144 return ENCODER_OBJECT_ID_NONE
;
147 void amdgpu_panel_mode_fixup(struct drm_encoder
*encoder
,
148 struct drm_display_mode
*adjusted_mode
)
150 struct amdgpu_encoder
*amdgpu_encoder
= to_amdgpu_encoder(encoder
);
151 struct drm_display_mode
*native_mode
= &amdgpu_encoder
->native_mode
;
152 unsigned hblank
= native_mode
->htotal
- native_mode
->hdisplay
;
153 unsigned vblank
= native_mode
->vtotal
- native_mode
->vdisplay
;
154 unsigned hover
= native_mode
->hsync_start
- native_mode
->hdisplay
;
155 unsigned vover
= native_mode
->vsync_start
- native_mode
->vdisplay
;
156 unsigned hsync_width
= native_mode
->hsync_end
- native_mode
->hsync_start
;
157 unsigned vsync_width
= native_mode
->vsync_end
- native_mode
->vsync_start
;
159 adjusted_mode
->clock
= native_mode
->clock
;
160 adjusted_mode
->flags
= native_mode
->flags
;
162 adjusted_mode
->hdisplay
= native_mode
->hdisplay
;
163 adjusted_mode
->vdisplay
= native_mode
->vdisplay
;
165 adjusted_mode
->htotal
= native_mode
->hdisplay
+ hblank
;
166 adjusted_mode
->hsync_start
= native_mode
->hdisplay
+ hover
;
167 adjusted_mode
->hsync_end
= adjusted_mode
->hsync_start
+ hsync_width
;
169 adjusted_mode
->vtotal
= native_mode
->vdisplay
+ vblank
;
170 adjusted_mode
->vsync_start
= native_mode
->vdisplay
+ vover
;
171 adjusted_mode
->vsync_end
= adjusted_mode
->vsync_start
+ vsync_width
;
173 drm_mode_set_crtcinfo(adjusted_mode
, CRTC_INTERLACE_HALVE_V
);
175 adjusted_mode
->crtc_hdisplay
= native_mode
->hdisplay
;
176 adjusted_mode
->crtc_vdisplay
= native_mode
->vdisplay
;
178 adjusted_mode
->crtc_htotal
= adjusted_mode
->crtc_hdisplay
+ hblank
;
179 adjusted_mode
->crtc_hsync_start
= adjusted_mode
->crtc_hdisplay
+ hover
;
180 adjusted_mode
->crtc_hsync_end
= adjusted_mode
->crtc_hsync_start
+ hsync_width
;
182 adjusted_mode
->crtc_vtotal
= adjusted_mode
->crtc_vdisplay
+ vblank
;
183 adjusted_mode
->crtc_vsync_start
= adjusted_mode
->crtc_vdisplay
+ vover
;
184 adjusted_mode
->crtc_vsync_end
= adjusted_mode
->crtc_vsync_start
+ vsync_width
;
188 bool amdgpu_dig_monitor_is_duallink(struct drm_encoder
*encoder
,
191 struct drm_connector
*connector
;
192 struct amdgpu_connector
*amdgpu_connector
;
193 struct amdgpu_connector_atom_dig
*dig_connector
;
195 connector
= amdgpu_get_connector_for_encoder(encoder
);
196 /* if we don't have an active device yet, just use one of
197 * the connectors tied to the encoder.
200 connector
= amdgpu_get_connector_for_encoder_init(encoder
);
201 amdgpu_connector
= to_amdgpu_connector(connector
);
203 switch (connector
->connector_type
) {
204 case DRM_MODE_CONNECTOR_DVII
:
205 case DRM_MODE_CONNECTOR_HDMIB
:
206 if (amdgpu_connector
->use_digital
) {
207 /* HDMI 1.3 supports up to 340 Mhz over single link */
208 if (drm_detect_hdmi_monitor(amdgpu_connector_edid(connector
))) {
209 if (pixel_clock
> 340000)
214 if (pixel_clock
> 165000)
221 case DRM_MODE_CONNECTOR_DVID
:
222 case DRM_MODE_CONNECTOR_HDMIA
:
223 case DRM_MODE_CONNECTOR_DisplayPort
:
224 dig_connector
= amdgpu_connector
->con_priv
;
225 if ((dig_connector
->dp_sink_type
== CONNECTOR_OBJECT_ID_DISPLAYPORT
) ||
226 (dig_connector
->dp_sink_type
== CONNECTOR_OBJECT_ID_eDP
))
229 /* HDMI 1.3 supports up to 340 Mhz over single link */
230 if (drm_detect_hdmi_monitor(amdgpu_connector_edid(connector
))) {
231 if (pixel_clock
> 340000)
236 if (pixel_clock
> 165000)