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 amdgpu_connector
*amdgpu_connector
;
41 struct drm_encoder
*encoder
;
42 struct amdgpu_encoder
*amdgpu_encoder
;
44 /* walk the list and link encoders to connectors */
45 list_for_each_entry(connector
, &dev
->mode_config
.connector_list
, head
) {
46 amdgpu_connector
= to_amdgpu_connector(connector
);
47 list_for_each_entry(encoder
, &dev
->mode_config
.encoder_list
, head
) {
48 amdgpu_encoder
= to_amdgpu_encoder(encoder
);
49 if (amdgpu_encoder
->devices
& amdgpu_connector
->devices
) {
50 drm_connector_attach_encoder(connector
, encoder
);
51 if (amdgpu_encoder
->devices
& (ATOM_DEVICE_LCD_SUPPORT
)) {
52 amdgpu_atombios_encoder_init_backlight(amdgpu_encoder
, connector
);
53 adev
->mode_info
.bl_encoder
= amdgpu_encoder
;
60 void amdgpu_encoder_set_active_device(struct drm_encoder
*encoder
)
62 struct drm_device
*dev
= encoder
->dev
;
63 struct amdgpu_encoder
*amdgpu_encoder
= to_amdgpu_encoder(encoder
);
64 struct drm_connector
*connector
;
66 list_for_each_entry(connector
, &dev
->mode_config
.connector_list
, head
) {
67 if (connector
->encoder
== encoder
) {
68 struct amdgpu_connector
*amdgpu_connector
= to_amdgpu_connector(connector
);
69 amdgpu_encoder
->active_device
= amdgpu_encoder
->devices
& amdgpu_connector
->devices
;
70 DRM_DEBUG_KMS("setting active device to %08x from %08x %08x for encoder %d\n",
71 amdgpu_encoder
->active_device
, amdgpu_encoder
->devices
,
72 amdgpu_connector
->devices
, encoder
->encoder_type
);
77 struct drm_connector
*
78 amdgpu_get_connector_for_encoder(struct drm_encoder
*encoder
)
80 struct drm_device
*dev
= encoder
->dev
;
81 struct amdgpu_encoder
*amdgpu_encoder
= to_amdgpu_encoder(encoder
);
82 struct drm_connector
*connector
;
83 struct amdgpu_connector
*amdgpu_connector
;
85 list_for_each_entry(connector
, &dev
->mode_config
.connector_list
, head
) {
86 amdgpu_connector
= to_amdgpu_connector(connector
);
87 if (amdgpu_encoder
->active_device
& amdgpu_connector
->devices
)
93 struct drm_connector
*
94 amdgpu_get_connector_for_encoder_init(struct drm_encoder
*encoder
)
96 struct drm_device
*dev
= encoder
->dev
;
97 struct amdgpu_encoder
*amdgpu_encoder
= to_amdgpu_encoder(encoder
);
98 struct drm_connector
*connector
;
99 struct amdgpu_connector
*amdgpu_connector
;
101 list_for_each_entry(connector
, &dev
->mode_config
.connector_list
, head
) {
102 amdgpu_connector
= to_amdgpu_connector(connector
);
103 if (amdgpu_encoder
->devices
& amdgpu_connector
->devices
)
109 struct drm_encoder
*amdgpu_get_external_encoder(struct drm_encoder
*encoder
)
111 struct drm_device
*dev
= encoder
->dev
;
112 struct amdgpu_encoder
*amdgpu_encoder
= to_amdgpu_encoder(encoder
);
113 struct drm_encoder
*other_encoder
;
114 struct amdgpu_encoder
*other_amdgpu_encoder
;
116 if (amdgpu_encoder
->is_ext_encoder
)
119 list_for_each_entry(other_encoder
, &dev
->mode_config
.encoder_list
, head
) {
120 if (other_encoder
== encoder
)
122 other_amdgpu_encoder
= to_amdgpu_encoder(other_encoder
);
123 if (other_amdgpu_encoder
->is_ext_encoder
&&
124 (amdgpu_encoder
->devices
& other_amdgpu_encoder
->devices
))
125 return other_encoder
;
130 u16
amdgpu_encoder_get_dp_bridge_encoder_id(struct drm_encoder
*encoder
)
132 struct drm_encoder
*other_encoder
= amdgpu_get_external_encoder(encoder
);
135 struct amdgpu_encoder
*amdgpu_encoder
= to_amdgpu_encoder(other_encoder
);
137 switch (amdgpu_encoder
->encoder_id
) {
138 case ENCODER_OBJECT_ID_TRAVIS
:
139 case ENCODER_OBJECT_ID_NUTMEG
:
140 return amdgpu_encoder
->encoder_id
;
142 return ENCODER_OBJECT_ID_NONE
;
145 return ENCODER_OBJECT_ID_NONE
;
148 void amdgpu_panel_mode_fixup(struct drm_encoder
*encoder
,
149 struct drm_display_mode
*adjusted_mode
)
151 struct amdgpu_encoder
*amdgpu_encoder
= to_amdgpu_encoder(encoder
);
152 struct drm_display_mode
*native_mode
= &amdgpu_encoder
->native_mode
;
153 unsigned hblank
= native_mode
->htotal
- native_mode
->hdisplay
;
154 unsigned vblank
= native_mode
->vtotal
- native_mode
->vdisplay
;
155 unsigned hover
= native_mode
->hsync_start
- native_mode
->hdisplay
;
156 unsigned vover
= native_mode
->vsync_start
- native_mode
->vdisplay
;
157 unsigned hsync_width
= native_mode
->hsync_end
- native_mode
->hsync_start
;
158 unsigned vsync_width
= native_mode
->vsync_end
- native_mode
->vsync_start
;
160 adjusted_mode
->clock
= native_mode
->clock
;
161 adjusted_mode
->flags
= native_mode
->flags
;
163 adjusted_mode
->hdisplay
= native_mode
->hdisplay
;
164 adjusted_mode
->vdisplay
= native_mode
->vdisplay
;
166 adjusted_mode
->htotal
= native_mode
->hdisplay
+ hblank
;
167 adjusted_mode
->hsync_start
= native_mode
->hdisplay
+ hover
;
168 adjusted_mode
->hsync_end
= adjusted_mode
->hsync_start
+ hsync_width
;
170 adjusted_mode
->vtotal
= native_mode
->vdisplay
+ vblank
;
171 adjusted_mode
->vsync_start
= native_mode
->vdisplay
+ vover
;
172 adjusted_mode
->vsync_end
= adjusted_mode
->vsync_start
+ vsync_width
;
174 drm_mode_set_crtcinfo(adjusted_mode
, CRTC_INTERLACE_HALVE_V
);
176 adjusted_mode
->crtc_hdisplay
= native_mode
->hdisplay
;
177 adjusted_mode
->crtc_vdisplay
= native_mode
->vdisplay
;
179 adjusted_mode
->crtc_htotal
= adjusted_mode
->crtc_hdisplay
+ hblank
;
180 adjusted_mode
->crtc_hsync_start
= adjusted_mode
->crtc_hdisplay
+ hover
;
181 adjusted_mode
->crtc_hsync_end
= adjusted_mode
->crtc_hsync_start
+ hsync_width
;
183 adjusted_mode
->crtc_vtotal
= adjusted_mode
->crtc_vdisplay
+ vblank
;
184 adjusted_mode
->crtc_vsync_start
= adjusted_mode
->crtc_vdisplay
+ vover
;
185 adjusted_mode
->crtc_vsync_end
= adjusted_mode
->crtc_vsync_start
+ vsync_width
;
189 bool amdgpu_dig_monitor_is_duallink(struct drm_encoder
*encoder
,
192 struct drm_connector
*connector
;
193 struct amdgpu_connector
*amdgpu_connector
;
194 struct amdgpu_connector_atom_dig
*dig_connector
;
196 connector
= amdgpu_get_connector_for_encoder(encoder
);
197 /* if we don't have an active device yet, just use one of
198 * the connectors tied to the encoder.
201 connector
= amdgpu_get_connector_for_encoder_init(encoder
);
202 amdgpu_connector
= to_amdgpu_connector(connector
);
204 switch (connector
->connector_type
) {
205 case DRM_MODE_CONNECTOR_DVII
:
206 case DRM_MODE_CONNECTOR_HDMIB
:
207 if (amdgpu_connector
->use_digital
) {
208 /* HDMI 1.3 supports up to 340 Mhz over single link */
209 if (drm_detect_hdmi_monitor(amdgpu_connector_edid(connector
))) {
210 if (pixel_clock
> 340000)
215 if (pixel_clock
> 165000)
222 case DRM_MODE_CONNECTOR_DVID
:
223 case DRM_MODE_CONNECTOR_HDMIA
:
224 case DRM_MODE_CONNECTOR_DisplayPort
:
225 dig_connector
= amdgpu_connector
->con_priv
;
226 if ((dig_connector
->dp_sink_type
== CONNECTOR_OBJECT_ID_DISPLAYPORT
) ||
227 (dig_connector
->dp_sink_type
== CONNECTOR_OBJECT_ID_eDP
))
230 /* HDMI 1.3 supports up to 340 Mhz over single link */
231 if (drm_detect_hdmi_monitor(amdgpu_connector_edid(connector
))) {
232 if (pixel_clock
> 340000)
237 if (pixel_clock
> 165000)