diff options
author | Andrea Bastoni <bastoni@cs.unc.edu> | 2010-05-30 19:16:45 -0400 |
---|---|---|
committer | Andrea Bastoni <bastoni@cs.unc.edu> | 2010-05-30 19:16:45 -0400 |
commit | ada47b5fe13d89735805b566185f4885f5a3f750 (patch) | |
tree | 644b88f8a71896307d71438e9b3af49126ffb22b /drivers/gpu/drm/radeon/radeon_encoders.c | |
parent | 43e98717ad40a4ae64545b5ba047c7b86aa44f4f (diff) | |
parent | 3280f21d43ee541f97f8cda5792150d2dbec20d5 (diff) |
Merge branch 'wip-2.6.34' into old-private-masterarchived-private-master
Diffstat (limited to 'drivers/gpu/drm/radeon/radeon_encoders.c')
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_encoders.c | 800 |
1 files changed, 550 insertions, 250 deletions
diff --git a/drivers/gpu/drm/radeon/radeon_encoders.c b/drivers/gpu/drm/radeon/radeon_encoders.c index d42bc512d75a..c5ddaf58563a 100644 --- a/drivers/gpu/drm/radeon/radeon_encoders.c +++ b/drivers/gpu/drm/radeon/radeon_encoders.c | |||
@@ -35,6 +35,51 @@ extern int atom_debug; | |||
35 | bool radeon_atom_get_tv_timings(struct radeon_device *rdev, int index, | 35 | bool radeon_atom_get_tv_timings(struct radeon_device *rdev, int index, |
36 | struct drm_display_mode *mode); | 36 | struct drm_display_mode *mode); |
37 | 37 | ||
38 | static uint32_t radeon_encoder_clones(struct drm_encoder *encoder) | ||
39 | { | ||
40 | struct drm_device *dev = encoder->dev; | ||
41 | struct radeon_device *rdev = dev->dev_private; | ||
42 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
43 | struct drm_encoder *clone_encoder; | ||
44 | uint32_t index_mask = 0; | ||
45 | int count; | ||
46 | |||
47 | /* DIG routing gets problematic */ | ||
48 | if (rdev->family >= CHIP_R600) | ||
49 | return index_mask; | ||
50 | /* LVDS/TV are too wacky */ | ||
51 | if (radeon_encoder->devices & ATOM_DEVICE_LCD_SUPPORT) | ||
52 | return index_mask; | ||
53 | /* DVO requires 2x ppll clocks depending on tmds chip */ | ||
54 | if (radeon_encoder->devices & ATOM_DEVICE_DFP2_SUPPORT) | ||
55 | return index_mask; | ||
56 | |||
57 | count = -1; | ||
58 | list_for_each_entry(clone_encoder, &dev->mode_config.encoder_list, head) { | ||
59 | struct radeon_encoder *radeon_clone = to_radeon_encoder(clone_encoder); | ||
60 | count++; | ||
61 | |||
62 | if (clone_encoder == encoder) | ||
63 | continue; | ||
64 | if (radeon_clone->devices & (ATOM_DEVICE_LCD_SUPPORT)) | ||
65 | continue; | ||
66 | if (radeon_clone->devices & ATOM_DEVICE_DFP2_SUPPORT) | ||
67 | continue; | ||
68 | else | ||
69 | index_mask |= (1 << count); | ||
70 | } | ||
71 | return index_mask; | ||
72 | } | ||
73 | |||
74 | void radeon_setup_encoder_clones(struct drm_device *dev) | ||
75 | { | ||
76 | struct drm_encoder *encoder; | ||
77 | |||
78 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { | ||
79 | encoder->possible_clones = radeon_encoder_clones(encoder); | ||
80 | } | ||
81 | } | ||
82 | |||
38 | uint32_t | 83 | uint32_t |
39 | radeon_get_encoder_id(struct drm_device *dev, uint32_t supported_device, uint8_t dac) | 84 | radeon_get_encoder_id(struct drm_device *dev, uint32_t supported_device, uint8_t dac) |
40 | { | 85 | { |
@@ -111,6 +156,26 @@ radeon_get_encoder_id(struct drm_device *dev, uint32_t supported_device, uint8_t | |||
111 | return ret; | 156 | return ret; |
112 | } | 157 | } |
113 | 158 | ||
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 | } | ||
114 | void | 179 | void |
115 | radeon_link_encoder_connector(struct drm_device *dev) | 180 | radeon_link_encoder_connector(struct drm_device *dev) |
116 | { | 181 | { |
@@ -157,34 +222,84 @@ radeon_get_connector_for_encoder(struct drm_encoder *encoder) | |||
157 | 222 | ||
158 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { | 223 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { |
159 | radeon_connector = to_radeon_connector(connector); | 224 | radeon_connector = to_radeon_connector(connector); |
160 | if (radeon_encoder->devices & radeon_connector->devices) | 225 | if (radeon_encoder->active_device & radeon_connector->devices) |
161 | return connector; | 226 | return connector; |
162 | } | 227 | } |
163 | return NULL; | 228 | return NULL; |
164 | } | 229 | } |
165 | 230 | ||
166 | /* used for both atom and legacy */ | 231 | static struct radeon_connector_atom_dig * |
167 | void radeon_rmx_mode_fixup(struct drm_encoder *encoder, | 232 | radeon_get_atom_connector_priv_from_encoder(struct drm_encoder *encoder) |
168 | struct drm_display_mode *mode, | 233 | { |
169 | struct drm_display_mode *adjusted_mode) | 234 | struct drm_device *dev = encoder->dev; |
235 | struct radeon_device *rdev = dev->dev_private; | ||
236 | struct drm_connector *connector; | ||
237 | struct radeon_connector *radeon_connector; | ||
238 | struct radeon_connector_atom_dig *dig_connector; | ||
239 | |||
240 | if (!rdev->is_atom_bios) | ||
241 | return NULL; | ||
242 | |||
243 | connector = radeon_get_connector_for_encoder(encoder); | ||
244 | if (!connector) | ||
245 | return NULL; | ||
246 | |||
247 | radeon_connector = to_radeon_connector(connector); | ||
248 | |||
249 | if (!radeon_connector->con_priv) | ||
250 | return NULL; | ||
251 | |||
252 | dig_connector = radeon_connector->con_priv; | ||
253 | |||
254 | return dig_connector; | ||
255 | } | ||
256 | |||
257 | void radeon_panel_mode_fixup(struct drm_encoder *encoder, | ||
258 | struct drm_display_mode *adjusted_mode) | ||
170 | { | 259 | { |
171 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | 260 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
172 | struct drm_device *dev = encoder->dev; | 261 | struct drm_device *dev = encoder->dev; |
173 | struct radeon_device *rdev = dev->dev_private; | 262 | struct radeon_device *rdev = dev->dev_private; |
174 | struct drm_display_mode *native_mode = &radeon_encoder->native_mode; | 263 | struct drm_display_mode *native_mode = &radeon_encoder->native_mode; |
264 | unsigned hblank = native_mode->htotal - native_mode->hdisplay; | ||
265 | unsigned vblank = native_mode->vtotal - native_mode->vdisplay; | ||
266 | unsigned hover = native_mode->hsync_start - native_mode->hdisplay; | ||
267 | unsigned vover = native_mode->vsync_start - native_mode->vdisplay; | ||
268 | unsigned hsync_width = native_mode->hsync_end - native_mode->hsync_start; | ||
269 | unsigned vsync_width = native_mode->vsync_end - native_mode->vsync_start; | ||
175 | 270 | ||
176 | if (mode->hdisplay < native_mode->hdisplay || | 271 | adjusted_mode->clock = native_mode->clock; |
177 | mode->vdisplay < native_mode->vdisplay) { | 272 | adjusted_mode->flags = native_mode->flags; |
178 | int mode_id = adjusted_mode->base.id; | 273 | |
179 | *adjusted_mode = *native_mode; | 274 | if (ASIC_IS_AVIVO(rdev)) { |
180 | if (!ASIC_IS_AVIVO(rdev)) { | 275 | adjusted_mode->hdisplay = native_mode->hdisplay; |
181 | adjusted_mode->hdisplay = mode->hdisplay; | 276 | adjusted_mode->vdisplay = native_mode->vdisplay; |
182 | adjusted_mode->vdisplay = mode->vdisplay; | ||
183 | } | ||
184 | adjusted_mode->base.id = mode_id; | ||
185 | } | 277 | } |
186 | } | ||
187 | 278 | ||
279 | adjusted_mode->htotal = native_mode->hdisplay + hblank; | ||
280 | adjusted_mode->hsync_start = native_mode->hdisplay + hover; | ||
281 | adjusted_mode->hsync_end = adjusted_mode->hsync_start + hsync_width; | ||
282 | |||
283 | adjusted_mode->vtotal = native_mode->vdisplay + vblank; | ||
284 | adjusted_mode->vsync_start = native_mode->vdisplay + vover; | ||
285 | adjusted_mode->vsync_end = adjusted_mode->vsync_start + vsync_width; | ||
286 | |||
287 | drm_mode_set_crtcinfo(adjusted_mode, CRTC_INTERLACE_HALVE_V); | ||
288 | |||
289 | if (ASIC_IS_AVIVO(rdev)) { | ||
290 | adjusted_mode->crtc_hdisplay = native_mode->hdisplay; | ||
291 | adjusted_mode->crtc_vdisplay = native_mode->vdisplay; | ||
292 | } | ||
293 | |||
294 | adjusted_mode->crtc_htotal = adjusted_mode->crtc_hdisplay + hblank; | ||
295 | adjusted_mode->crtc_hsync_start = adjusted_mode->crtc_hdisplay + hover; | ||
296 | adjusted_mode->crtc_hsync_end = adjusted_mode->crtc_hsync_start + hsync_width; | ||
297 | |||
298 | adjusted_mode->crtc_vtotal = adjusted_mode->crtc_vdisplay + vblank; | ||
299 | adjusted_mode->crtc_vsync_start = adjusted_mode->crtc_vdisplay + vover; | ||
300 | adjusted_mode->crtc_vsync_end = adjusted_mode->crtc_vsync_start + vsync_width; | ||
301 | |||
302 | } | ||
188 | 303 | ||
189 | static bool radeon_atom_mode_fixup(struct drm_encoder *encoder, | 304 | static bool radeon_atom_mode_fixup(struct drm_encoder *encoder, |
190 | struct drm_display_mode *mode, | 305 | struct drm_display_mode *mode, |
@@ -194,18 +309,23 @@ static bool radeon_atom_mode_fixup(struct drm_encoder *encoder, | |||
194 | struct drm_device *dev = encoder->dev; | 309 | struct drm_device *dev = encoder->dev; |
195 | struct radeon_device *rdev = dev->dev_private; | 310 | struct radeon_device *rdev = dev->dev_private; |
196 | 311 | ||
312 | /* adjust pm to upcoming mode change */ | ||
313 | radeon_pm_compute_clocks(rdev); | ||
314 | |||
197 | /* set the active encoder to connector routing */ | 315 | /* set the active encoder to connector routing */ |
198 | radeon_encoder_set_active_device(encoder); | 316 | radeon_encoder_set_active_device(encoder); |
199 | drm_mode_set_crtcinfo(adjusted_mode, 0); | 317 | drm_mode_set_crtcinfo(adjusted_mode, 0); |
200 | 318 | ||
201 | if (radeon_encoder->rmx_type != RMX_OFF) | ||
202 | radeon_rmx_mode_fixup(encoder, mode, adjusted_mode); | ||
203 | |||
204 | /* hw bug */ | 319 | /* hw bug */ |
205 | if ((mode->flags & DRM_MODE_FLAG_INTERLACE) | 320 | if ((mode->flags & DRM_MODE_FLAG_INTERLACE) |
206 | && (mode->crtc_vsync_start < (mode->crtc_vdisplay + 2))) | 321 | && (mode->crtc_vsync_start < (mode->crtc_vdisplay + 2))) |
207 | adjusted_mode->crtc_vsync_start = adjusted_mode->crtc_vdisplay + 2; | 322 | adjusted_mode->crtc_vsync_start = adjusted_mode->crtc_vdisplay + 2; |
208 | 323 | ||
324 | /* get the native mode for LVDS */ | ||
325 | if (radeon_encoder->active_device & (ATOM_DEVICE_LCD_SUPPORT)) | ||
326 | radeon_panel_mode_fixup(encoder, adjusted_mode); | ||
327 | |||
328 | /* get the native mode for TV */ | ||
209 | if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT)) { | 329 | if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT)) { |
210 | struct radeon_encoder_atom_dac *tv_dac = radeon_encoder->enc_priv; | 330 | struct radeon_encoder_atom_dac *tv_dac = radeon_encoder->enc_priv; |
211 | if (tv_dac) { | 331 | if (tv_dac) { |
@@ -218,6 +338,12 @@ static bool radeon_atom_mode_fixup(struct drm_encoder *encoder, | |||
218 | } | 338 | } |
219 | } | 339 | } |
220 | 340 | ||
341 | if (ASIC_IS_DCE3(rdev) && | ||
342 | (radeon_encoder->active_device & (ATOM_DEVICE_DFP_SUPPORT | ATOM_DEVICE_LCD_SUPPORT))) { | ||
343 | struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); | ||
344 | radeon_dp_set_link_config(connector, mode); | ||
345 | } | ||
346 | |||
221 | return true; | 347 | return true; |
222 | } | 348 | } |
223 | 349 | ||
@@ -228,12 +354,8 @@ atombios_dac_setup(struct drm_encoder *encoder, int action) | |||
228 | struct radeon_device *rdev = dev->dev_private; | 354 | struct radeon_device *rdev = dev->dev_private; |
229 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | 355 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
230 | DAC_ENCODER_CONTROL_PS_ALLOCATION args; | 356 | DAC_ENCODER_CONTROL_PS_ALLOCATION args; |
231 | int index = 0, num = 0; | 357 | int index = 0; |
232 | struct radeon_encoder_atom_dac *dac_info = radeon_encoder->enc_priv; | 358 | struct radeon_encoder_atom_dac *dac_info = radeon_encoder->enc_priv; |
233 | enum radeon_tv_std tv_std = TV_STD_NTSC; | ||
234 | |||
235 | if (dac_info->tv_std) | ||
236 | tv_std = dac_info->tv_std; | ||
237 | 359 | ||
238 | memset(&args, 0, sizeof(args)); | 360 | memset(&args, 0, sizeof(args)); |
239 | 361 | ||
@@ -241,12 +363,10 @@ atombios_dac_setup(struct drm_encoder *encoder, int action) | |||
241 | case ENCODER_OBJECT_ID_INTERNAL_DAC1: | 363 | case ENCODER_OBJECT_ID_INTERNAL_DAC1: |
242 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1: | 364 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1: |
243 | index = GetIndexIntoMasterTable(COMMAND, DAC1EncoderControl); | 365 | index = GetIndexIntoMasterTable(COMMAND, DAC1EncoderControl); |
244 | num = 1; | ||
245 | break; | 366 | break; |
246 | case ENCODER_OBJECT_ID_INTERNAL_DAC2: | 367 | case ENCODER_OBJECT_ID_INTERNAL_DAC2: |
247 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2: | 368 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2: |
248 | index = GetIndexIntoMasterTable(COMMAND, DAC2EncoderControl); | 369 | index = GetIndexIntoMasterTable(COMMAND, DAC2EncoderControl); |
249 | num = 2; | ||
250 | break; | 370 | break; |
251 | } | 371 | } |
252 | 372 | ||
@@ -257,7 +377,7 @@ atombios_dac_setup(struct drm_encoder *encoder, int action) | |||
257 | else if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT)) | 377 | else if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT)) |
258 | args.ucDacStandard = ATOM_DAC1_CV; | 378 | args.ucDacStandard = ATOM_DAC1_CV; |
259 | else { | 379 | else { |
260 | switch (tv_std) { | 380 | switch (dac_info->tv_std) { |
261 | case TV_STD_PAL: | 381 | case TV_STD_PAL: |
262 | case TV_STD_PAL_M: | 382 | case TV_STD_PAL_M: |
263 | case TV_STD_SCART_PAL: | 383 | case TV_STD_SCART_PAL: |
@@ -288,10 +408,6 @@ atombios_tv_setup(struct drm_encoder *encoder, int action) | |||
288 | TV_ENCODER_CONTROL_PS_ALLOCATION args; | 408 | TV_ENCODER_CONTROL_PS_ALLOCATION args; |
289 | int index = 0; | 409 | int index = 0; |
290 | struct radeon_encoder_atom_dac *dac_info = radeon_encoder->enc_priv; | 410 | struct radeon_encoder_atom_dac *dac_info = radeon_encoder->enc_priv; |
291 | enum radeon_tv_std tv_std = TV_STD_NTSC; | ||
292 | |||
293 | if (dac_info->tv_std) | ||
294 | tv_std = dac_info->tv_std; | ||
295 | 411 | ||
296 | memset(&args, 0, sizeof(args)); | 412 | memset(&args, 0, sizeof(args)); |
297 | 413 | ||
@@ -302,7 +418,7 @@ atombios_tv_setup(struct drm_encoder *encoder, int action) | |||
302 | if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT)) | 418 | if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT)) |
303 | args.sTVEncoder.ucTvStandard = ATOM_TV_CV; | 419 | args.sTVEncoder.ucTvStandard = ATOM_TV_CV; |
304 | else { | 420 | else { |
305 | switch (tv_std) { | 421 | switch (dac_info->tv_std) { |
306 | case TV_STD_NTSC: | 422 | case TV_STD_NTSC: |
307 | args.sTVEncoder.ucTvStandard = ATOM_TV_NTSC; | 423 | args.sTVEncoder.ucTvStandard = ATOM_TV_NTSC; |
308 | break; | 424 | break; |
@@ -392,35 +508,25 @@ union lvds_encoder_control { | |||
392 | LVDS_ENCODER_CONTROL_PS_ALLOCATION_V2 v2; | 508 | LVDS_ENCODER_CONTROL_PS_ALLOCATION_V2 v2; |
393 | }; | 509 | }; |
394 | 510 | ||
395 | static void | 511 | void |
396 | atombios_digital_setup(struct drm_encoder *encoder, int action) | 512 | atombios_digital_setup(struct drm_encoder *encoder, int action) |
397 | { | 513 | { |
398 | struct drm_device *dev = encoder->dev; | 514 | struct drm_device *dev = encoder->dev; |
399 | struct radeon_device *rdev = dev->dev_private; | 515 | struct radeon_device *rdev = dev->dev_private; |
400 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | 516 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
517 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; | ||
518 | struct radeon_connector_atom_dig *dig_connector = | ||
519 | radeon_get_atom_connector_priv_from_encoder(encoder); | ||
401 | union lvds_encoder_control args; | 520 | union lvds_encoder_control args; |
402 | int index = 0; | 521 | int index = 0; |
522 | int hdmi_detected = 0; | ||
403 | uint8_t frev, crev; | 523 | uint8_t frev, crev; |
404 | struct radeon_encoder_atom_dig *dig; | ||
405 | struct drm_connector *connector; | ||
406 | struct radeon_connector *radeon_connector; | ||
407 | struct radeon_connector_atom_dig *dig_connector; | ||
408 | |||
409 | connector = radeon_get_connector_for_encoder(encoder); | ||
410 | if (!connector) | ||
411 | return; | ||
412 | |||
413 | radeon_connector = to_radeon_connector(connector); | ||
414 | |||
415 | if (!radeon_encoder->enc_priv) | ||
416 | return; | ||
417 | |||
418 | dig = radeon_encoder->enc_priv; | ||
419 | 524 | ||
420 | if (!radeon_connector->con_priv) | 525 | if (!dig || !dig_connector) |
421 | return; | 526 | return; |
422 | 527 | ||
423 | dig_connector = radeon_connector->con_priv; | 528 | if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_HDMI) |
529 | hdmi_detected = 1; | ||
424 | 530 | ||
425 | memset(&args, 0, sizeof(args)); | 531 | memset(&args, 0, sizeof(args)); |
426 | 532 | ||
@@ -440,7 +546,8 @@ atombios_digital_setup(struct drm_encoder *encoder, int action) | |||
440 | break; | 546 | break; |
441 | } | 547 | } |
442 | 548 | ||
443 | atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev); | 549 | if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev)) |
550 | return; | ||
444 | 551 | ||
445 | switch (frev) { | 552 | switch (frev) { |
446 | case 1: | 553 | case 1: |
@@ -449,13 +556,13 @@ atombios_digital_setup(struct drm_encoder *encoder, int action) | |||
449 | case 1: | 556 | case 1: |
450 | args.v1.ucMisc = 0; | 557 | args.v1.ucMisc = 0; |
451 | args.v1.ucAction = action; | 558 | args.v1.ucAction = action; |
452 | if (drm_detect_hdmi_monitor(radeon_connector->edid)) | 559 | if (hdmi_detected) |
453 | args.v1.ucMisc |= PANEL_ENCODER_MISC_HDMI_TYPE; | 560 | args.v1.ucMisc |= PANEL_ENCODER_MISC_HDMI_TYPE; |
454 | args.v1.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); | 561 | args.v1.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); |
455 | if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) { | 562 | if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) { |
456 | if (dig->lvds_misc & (1 << 0)) | 563 | if (dig->lvds_misc & ATOM_PANEL_MISC_DUAL) |
457 | args.v1.ucMisc |= PANEL_ENCODER_MISC_DUAL; | 564 | args.v1.ucMisc |= PANEL_ENCODER_MISC_DUAL; |
458 | if (dig->lvds_misc & (1 << 1)) | 565 | if (dig->lvds_misc & ATOM_PANEL_MISC_888RGB) |
459 | args.v1.ucMisc |= (1 << 1); | 566 | args.v1.ucMisc |= (1 << 1); |
460 | } else { | 567 | } else { |
461 | if (dig_connector->linkb) | 568 | if (dig_connector->linkb) |
@@ -474,7 +581,7 @@ atombios_digital_setup(struct drm_encoder *encoder, int action) | |||
474 | if (dig->coherent_mode) | 581 | if (dig->coherent_mode) |
475 | args.v2.ucMisc |= PANEL_ENCODER_MISC_COHERENT; | 582 | args.v2.ucMisc |= PANEL_ENCODER_MISC_COHERENT; |
476 | } | 583 | } |
477 | if (drm_detect_hdmi_monitor(radeon_connector->edid)) | 584 | if (hdmi_detected) |
478 | args.v2.ucMisc |= PANEL_ENCODER_MISC_HDMI_TYPE; | 585 | args.v2.ucMisc |= PANEL_ENCODER_MISC_HDMI_TYPE; |
479 | args.v2.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); | 586 | args.v2.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); |
480 | args.v2.ucTruncate = 0; | 587 | args.v2.ucTruncate = 0; |
@@ -482,18 +589,18 @@ atombios_digital_setup(struct drm_encoder *encoder, int action) | |||
482 | args.v2.ucTemporal = 0; | 589 | args.v2.ucTemporal = 0; |
483 | args.v2.ucFRC = 0; | 590 | args.v2.ucFRC = 0; |
484 | if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) { | 591 | if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) { |
485 | if (dig->lvds_misc & (1 << 0)) | 592 | if (dig->lvds_misc & ATOM_PANEL_MISC_DUAL) |
486 | args.v2.ucMisc |= PANEL_ENCODER_MISC_DUAL; | 593 | args.v2.ucMisc |= PANEL_ENCODER_MISC_DUAL; |
487 | if (dig->lvds_misc & (1 << 5)) { | 594 | if (dig->lvds_misc & ATOM_PANEL_MISC_SPATIAL) { |
488 | args.v2.ucSpatial = PANEL_ENCODER_SPATIAL_DITHER_EN; | 595 | args.v2.ucSpatial = PANEL_ENCODER_SPATIAL_DITHER_EN; |
489 | if (dig->lvds_misc & (1 << 1)) | 596 | if (dig->lvds_misc & ATOM_PANEL_MISC_888RGB) |
490 | args.v2.ucSpatial |= PANEL_ENCODER_SPATIAL_DITHER_DEPTH; | 597 | args.v2.ucSpatial |= PANEL_ENCODER_SPATIAL_DITHER_DEPTH; |
491 | } | 598 | } |
492 | if (dig->lvds_misc & (1 << 6)) { | 599 | if (dig->lvds_misc & ATOM_PANEL_MISC_TEMPORAL) { |
493 | args.v2.ucTemporal = PANEL_ENCODER_TEMPORAL_DITHER_EN; | 600 | args.v2.ucTemporal = PANEL_ENCODER_TEMPORAL_DITHER_EN; |
494 | if (dig->lvds_misc & (1 << 1)) | 601 | if (dig->lvds_misc & ATOM_PANEL_MISC_888RGB) |
495 | args.v2.ucTemporal |= PANEL_ENCODER_TEMPORAL_DITHER_DEPTH; | 602 | args.v2.ucTemporal |= PANEL_ENCODER_TEMPORAL_DITHER_DEPTH; |
496 | if (((dig->lvds_misc >> 2) & 0x3) == 2) | 603 | if (((dig->lvds_misc >> ATOM_PANEL_MISC_GREY_LEVEL_SHIFT) & 0x3) == 2) |
497 | args.v2.ucTemporal |= PANEL_ENCODER_TEMPORAL_LEVEL_4; | 604 | args.v2.ucTemporal |= PANEL_ENCODER_TEMPORAL_LEVEL_4; |
498 | } | 605 | } |
499 | } else { | 606 | } else { |
@@ -514,7 +621,6 @@ atombios_digital_setup(struct drm_encoder *encoder, int action) | |||
514 | } | 621 | } |
515 | 622 | ||
516 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); | 623 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); |
517 | |||
518 | } | 624 | } |
519 | 625 | ||
520 | int | 626 | int |
@@ -522,6 +628,7 @@ atombios_get_encoder_mode(struct drm_encoder *encoder) | |||
522 | { | 628 | { |
523 | struct drm_connector *connector; | 629 | struct drm_connector *connector; |
524 | struct radeon_connector *radeon_connector; | 630 | struct radeon_connector *radeon_connector; |
631 | struct radeon_connector_atom_dig *dig_connector; | ||
525 | 632 | ||
526 | connector = radeon_get_connector_for_encoder(encoder); | 633 | connector = radeon_get_connector_for_encoder(encoder); |
527 | if (!connector) | 634 | if (!connector) |
@@ -551,21 +658,23 @@ atombios_get_encoder_mode(struct drm_encoder *encoder) | |||
551 | return ATOM_ENCODER_MODE_LVDS; | 658 | return ATOM_ENCODER_MODE_LVDS; |
552 | break; | 659 | break; |
553 | case DRM_MODE_CONNECTOR_DisplayPort: | 660 | case DRM_MODE_CONNECTOR_DisplayPort: |
554 | /*if (radeon_output->MonType == MT_DP) | 661 | case DRM_MODE_CONNECTOR_eDP: |
555 | return ATOM_ENCODER_MODE_DP; | 662 | dig_connector = radeon_connector->con_priv; |
556 | else*/ | 663 | if ((dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) || |
557 | if (drm_detect_hdmi_monitor(radeon_connector->edid)) | 664 | (dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_eDP)) |
665 | return ATOM_ENCODER_MODE_DP; | ||
666 | else if (drm_detect_hdmi_monitor(radeon_connector->edid)) | ||
558 | return ATOM_ENCODER_MODE_HDMI; | 667 | return ATOM_ENCODER_MODE_HDMI; |
559 | else | 668 | else |
560 | return ATOM_ENCODER_MODE_DVI; | 669 | return ATOM_ENCODER_MODE_DVI; |
561 | break; | 670 | break; |
562 | case CONNECTOR_DVI_A: | 671 | case DRM_MODE_CONNECTOR_DVIA: |
563 | case CONNECTOR_VGA: | 672 | case DRM_MODE_CONNECTOR_VGA: |
564 | return ATOM_ENCODER_MODE_CRT; | 673 | return ATOM_ENCODER_MODE_CRT; |
565 | break; | 674 | break; |
566 | case CONNECTOR_STV: | 675 | case DRM_MODE_CONNECTOR_Composite: |
567 | case CONNECTOR_CTV: | 676 | case DRM_MODE_CONNECTOR_SVIDEO: |
568 | case CONNECTOR_DIN: | 677 | case DRM_MODE_CONNECTOR_9PinDIN: |
569 | /* fix me */ | 678 | /* fix me */ |
570 | return ATOM_ENCODER_MODE_TV; | 679 | return ATOM_ENCODER_MODE_TV; |
571 | /*return ATOM_ENCODER_MODE_CV;*/ | 680 | /*return ATOM_ENCODER_MODE_CV;*/ |
@@ -573,98 +682,114 @@ atombios_get_encoder_mode(struct drm_encoder *encoder) | |||
573 | } | 682 | } |
574 | } | 683 | } |
575 | 684 | ||
576 | static void | 685 | /* |
686 | * DIG Encoder/Transmitter Setup | ||
687 | * | ||
688 | * DCE 3.0/3.1 | ||
689 | * - 2 DIG transmitter blocks. UNIPHY (links A and B) and LVTMA. | ||
690 | * Supports up to 3 digital outputs | ||
691 | * - 2 DIG encoder blocks. | ||
692 | * DIG1 can drive UNIPHY link A or link B | ||
693 | * DIG2 can drive UNIPHY link B or LVTMA | ||
694 | * | ||
695 | * DCE 3.2 | ||
696 | * - 3 DIG transmitter blocks. UNIPHY0/1/2 (links A and B). | ||
697 | * Supports up to 5 digital outputs | ||
698 | * - 2 DIG encoder blocks. | ||
699 | * DIG1/2 can drive UNIPHY0/1/2 link A or link B | ||
700 | * | ||
701 | * DCE 4.0 | ||
702 | * - 3 DIG transmitter blocks UNPHY0/1/2 (links A and B). | ||
703 | * Supports up to 6 digital outputs | ||
704 | * - 6 DIG encoder blocks. | ||
705 | * - DIG to PHY mapping is hardcoded | ||
706 | * DIG1 drives UNIPHY0 link A, A+B | ||
707 | * DIG2 drives UNIPHY0 link B | ||
708 | * DIG3 drives UNIPHY1 link A, A+B | ||
709 | * DIG4 drives UNIPHY1 link B | ||
710 | * DIG5 drives UNIPHY2 link A, A+B | ||
711 | * DIG6 drives UNIPHY2 link B | ||
712 | * | ||
713 | * Routing | ||
714 | * crtc -> dig encoder -> UNIPHY/LVTMA (1 or 2 links) | ||
715 | * Examples: | ||
716 | * crtc0 -> dig2 -> LVTMA links A+B -> TMDS/HDMI | ||
717 | * crtc1 -> dig1 -> UNIPHY0 link B -> DP | ||
718 | * crtc0 -> dig1 -> UNIPHY2 link A -> LVDS | ||
719 | * crtc1 -> dig2 -> UNIPHY1 link B+A -> TMDS/HDMI | ||
720 | */ | ||
721 | |||
722 | union dig_encoder_control { | ||
723 | DIG_ENCODER_CONTROL_PS_ALLOCATION v1; | ||
724 | DIG_ENCODER_CONTROL_PARAMETERS_V2 v2; | ||
725 | DIG_ENCODER_CONTROL_PARAMETERS_V3 v3; | ||
726 | }; | ||
727 | |||
728 | void | ||
577 | atombios_dig_encoder_setup(struct drm_encoder *encoder, int action) | 729 | atombios_dig_encoder_setup(struct drm_encoder *encoder, int action) |
578 | { | 730 | { |
579 | struct drm_device *dev = encoder->dev; | 731 | struct drm_device *dev = encoder->dev; |
580 | struct radeon_device *rdev = dev->dev_private; | 732 | struct radeon_device *rdev = dev->dev_private; |
581 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | 733 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
582 | DIG_ENCODER_CONTROL_PS_ALLOCATION args; | 734 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; |
583 | int index = 0, num = 0; | 735 | struct radeon_connector_atom_dig *dig_connector = |
736 | radeon_get_atom_connector_priv_from_encoder(encoder); | ||
737 | union dig_encoder_control args; | ||
738 | int index = 0; | ||
584 | uint8_t frev, crev; | 739 | uint8_t frev, crev; |
585 | struct radeon_encoder_atom_dig *dig; | ||
586 | struct drm_connector *connector; | ||
587 | struct radeon_connector *radeon_connector; | ||
588 | struct radeon_connector_atom_dig *dig_connector; | ||
589 | |||
590 | connector = radeon_get_connector_for_encoder(encoder); | ||
591 | if (!connector) | ||
592 | return; | ||
593 | 740 | ||
594 | radeon_connector = to_radeon_connector(connector); | 741 | if (!dig || !dig_connector) |
595 | |||
596 | if (!radeon_connector->con_priv) | ||
597 | return; | 742 | return; |
598 | 743 | ||
599 | dig_connector = radeon_connector->con_priv; | ||
600 | |||
601 | if (!radeon_encoder->enc_priv) | ||
602 | return; | ||
603 | |||
604 | dig = radeon_encoder->enc_priv; | ||
605 | |||
606 | memset(&args, 0, sizeof(args)); | 744 | memset(&args, 0, sizeof(args)); |
607 | 745 | ||
608 | if (ASIC_IS_DCE32(rdev)) { | 746 | if (ASIC_IS_DCE4(rdev)) |
609 | if (dig->dig_block) | 747 | index = GetIndexIntoMasterTable(COMMAND, DIGxEncoderControl); |
748 | else { | ||
749 | if (dig->dig_encoder) | ||
610 | index = GetIndexIntoMasterTable(COMMAND, DIG2EncoderControl); | 750 | index = GetIndexIntoMasterTable(COMMAND, DIG2EncoderControl); |
611 | else | 751 | else |
612 | index = GetIndexIntoMasterTable(COMMAND, DIG1EncoderControl); | 752 | index = GetIndexIntoMasterTable(COMMAND, DIG1EncoderControl); |
613 | num = dig->dig_block + 1; | ||
614 | } else { | ||
615 | switch (radeon_encoder->encoder_id) { | ||
616 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: | ||
617 | index = GetIndexIntoMasterTable(COMMAND, DIG1EncoderControl); | ||
618 | num = 1; | ||
619 | break; | ||
620 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: | ||
621 | index = GetIndexIntoMasterTable(COMMAND, DIG2EncoderControl); | ||
622 | num = 2; | ||
623 | break; | ||
624 | } | ||
625 | } | 753 | } |
626 | 754 | ||
627 | atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev); | 755 | if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev)) |
756 | return; | ||
628 | 757 | ||
629 | args.ucAction = action; | 758 | args.v1.ucAction = action; |
630 | args.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); | 759 | args.v1.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); |
760 | args.v1.ucEncoderMode = atombios_get_encoder_mode(encoder); | ||
761 | |||
762 | if (args.v1.ucEncoderMode == ATOM_ENCODER_MODE_DP) { | ||
763 | if (dig_connector->dp_clock == 270000) | ||
764 | args.v1.ucConfig |= ATOM_ENCODER_CONFIG_DPLINKRATE_2_70GHZ; | ||
765 | args.v1.ucLaneNum = dig_connector->dp_lane_count; | ||
766 | } else if (radeon_encoder->pixel_clock > 165000) | ||
767 | args.v1.ucLaneNum = 8; | ||
768 | else | ||
769 | args.v1.ucLaneNum = 4; | ||
631 | 770 | ||
632 | if (ASIC_IS_DCE32(rdev)) { | 771 | if (ASIC_IS_DCE4(rdev)) { |
772 | args.v3.acConfig.ucDigSel = dig->dig_encoder; | ||
773 | args.v3.ucBitPerColor = PANEL_8BIT_PER_COLOR; | ||
774 | } else { | ||
633 | switch (radeon_encoder->encoder_id) { | 775 | switch (radeon_encoder->encoder_id) { |
634 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: | 776 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: |
635 | args.ucConfig = ATOM_ENCODER_CONFIG_V2_TRANSMITTER1; | 777 | args.v1.ucConfig = ATOM_ENCODER_CONFIG_V2_TRANSMITTER1; |
636 | break; | 778 | break; |
637 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: | 779 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: |
638 | args.ucConfig = ATOM_ENCODER_CONFIG_V2_TRANSMITTER2; | 780 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: |
781 | args.v1.ucConfig = ATOM_ENCODER_CONFIG_V2_TRANSMITTER2; | ||
639 | break; | 782 | break; |
640 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: | 783 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: |
641 | args.ucConfig = ATOM_ENCODER_CONFIG_V2_TRANSMITTER3; | 784 | args.v1.ucConfig = ATOM_ENCODER_CONFIG_V2_TRANSMITTER3; |
642 | break; | 785 | break; |
643 | } | 786 | } |
644 | } else { | ||
645 | switch (radeon_encoder->encoder_id) { | ||
646 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: | ||
647 | args.ucConfig = ATOM_ENCODER_CONFIG_TRANSMITTER1; | ||
648 | break; | ||
649 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: | ||
650 | args.ucConfig = ATOM_ENCODER_CONFIG_TRANSMITTER2; | ||
651 | break; | ||
652 | } | ||
653 | } | ||
654 | |||
655 | if (radeon_encoder->pixel_clock > 165000) { | ||
656 | args.ucConfig |= ATOM_ENCODER_CONFIG_LINKA_B; | ||
657 | args.ucLaneNum = 8; | ||
658 | } else { | ||
659 | if (dig_connector->linkb) | 787 | if (dig_connector->linkb) |
660 | args.ucConfig |= ATOM_ENCODER_CONFIG_LINKB; | 788 | args.v1.ucConfig |= ATOM_ENCODER_CONFIG_LINKB; |
661 | else | 789 | else |
662 | args.ucConfig |= ATOM_ENCODER_CONFIG_LINKA; | 790 | args.v1.ucConfig |= ATOM_ENCODER_CONFIG_LINKA; |
663 | args.ucLaneNum = 4; | ||
664 | } | 791 | } |
665 | 792 | ||
666 | args.ucEncoderMode = atombios_get_encoder_mode(encoder); | ||
667 | |||
668 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); | 793 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); |
669 | 794 | ||
670 | } | 795 | } |
@@ -672,41 +797,38 @@ atombios_dig_encoder_setup(struct drm_encoder *encoder, int action) | |||
672 | union dig_transmitter_control { | 797 | union dig_transmitter_control { |
673 | DIG_TRANSMITTER_CONTROL_PS_ALLOCATION v1; | 798 | DIG_TRANSMITTER_CONTROL_PS_ALLOCATION v1; |
674 | DIG_TRANSMITTER_CONTROL_PARAMETERS_V2 v2; | 799 | DIG_TRANSMITTER_CONTROL_PARAMETERS_V2 v2; |
800 | DIG_TRANSMITTER_CONTROL_PARAMETERS_V3 v3; | ||
675 | }; | 801 | }; |
676 | 802 | ||
677 | static void | 803 | void |
678 | atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action) | 804 | atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t lane_num, uint8_t lane_set) |
679 | { | 805 | { |
680 | struct drm_device *dev = encoder->dev; | 806 | struct drm_device *dev = encoder->dev; |
681 | struct radeon_device *rdev = dev->dev_private; | 807 | struct radeon_device *rdev = dev->dev_private; |
682 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | 808 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
683 | union dig_transmitter_control args; | 809 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; |
684 | int index = 0, num = 0; | 810 | struct radeon_connector_atom_dig *dig_connector = |
685 | uint8_t frev, crev; | 811 | radeon_get_atom_connector_priv_from_encoder(encoder); |
686 | struct radeon_encoder_atom_dig *dig; | ||
687 | struct drm_connector *connector; | 812 | struct drm_connector *connector; |
688 | struct radeon_connector *radeon_connector; | 813 | struct radeon_connector *radeon_connector; |
689 | struct radeon_connector_atom_dig *dig_connector; | 814 | union dig_transmitter_control args; |
815 | int index = 0; | ||
816 | uint8_t frev, crev; | ||
817 | bool is_dp = false; | ||
818 | int pll_id = 0; | ||
690 | 819 | ||
691 | connector = radeon_get_connector_for_encoder(encoder); | 820 | if (!dig || !dig_connector) |
692 | if (!connector) | ||
693 | return; | 821 | return; |
694 | 822 | ||
823 | connector = radeon_get_connector_for_encoder(encoder); | ||
695 | radeon_connector = to_radeon_connector(connector); | 824 | radeon_connector = to_radeon_connector(connector); |
696 | 825 | ||
697 | if (!radeon_encoder->enc_priv) | 826 | if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_DP) |
698 | return; | 827 | is_dp = true; |
699 | |||
700 | dig = radeon_encoder->enc_priv; | ||
701 | |||
702 | if (!radeon_connector->con_priv) | ||
703 | return; | ||
704 | |||
705 | dig_connector = radeon_connector->con_priv; | ||
706 | 828 | ||
707 | memset(&args, 0, sizeof(args)); | 829 | memset(&args, 0, sizeof(args)); |
708 | 830 | ||
709 | if (ASIC_IS_DCE32(rdev)) | 831 | if (ASIC_IS_DCE32(rdev) || ASIC_IS_DCE4(rdev)) |
710 | index = GetIndexIntoMasterTable(COMMAND, UNIPHYTransmitterControl); | 832 | index = GetIndexIntoMasterTable(COMMAND, UNIPHYTransmitterControl); |
711 | else { | 833 | else { |
712 | switch (radeon_encoder->encoder_id) { | 834 | switch (radeon_encoder->encoder_id) { |
@@ -719,103 +841,138 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action) | |||
719 | } | 841 | } |
720 | } | 842 | } |
721 | 843 | ||
722 | atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev); | 844 | if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev)) |
845 | return; | ||
723 | 846 | ||
724 | args.v1.ucAction = action; | 847 | args.v1.ucAction = action; |
725 | if (action == ATOM_TRANSMITTER_ACTION_INIT) { | 848 | if (action == ATOM_TRANSMITTER_ACTION_INIT) { |
726 | args.v1.usInitInfo = radeon_connector->connector_object_id; | 849 | args.v1.usInitInfo = radeon_connector->connector_object_id; |
850 | } else if (action == ATOM_TRANSMITTER_ACTION_SETUP_VSEMPH) { | ||
851 | args.v1.asMode.ucLaneSel = lane_num; | ||
852 | args.v1.asMode.ucLaneSet = lane_set; | ||
727 | } else { | 853 | } else { |
728 | if (radeon_encoder->pixel_clock > 165000) | 854 | if (is_dp) |
855 | args.v1.usPixelClock = | ||
856 | cpu_to_le16(dig_connector->dp_clock / 10); | ||
857 | else if (radeon_encoder->pixel_clock > 165000) | ||
729 | args.v1.usPixelClock = cpu_to_le16((radeon_encoder->pixel_clock / 2) / 10); | 858 | args.v1.usPixelClock = cpu_to_le16((radeon_encoder->pixel_clock / 2) / 10); |
730 | else | 859 | else |
731 | args.v1.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); | 860 | args.v1.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); |
732 | } | 861 | } |
733 | if (ASIC_IS_DCE32(rdev)) { | 862 | if (ASIC_IS_DCE4(rdev)) { |
734 | if (radeon_encoder->pixel_clock > 165000) | 863 | if (is_dp) |
735 | args.v2.usPixelClock = cpu_to_le16((radeon_encoder->pixel_clock / 2) / 10); | 864 | args.v3.ucLaneNum = dig_connector->dp_lane_count; |
736 | if (dig->dig_block) | 865 | else if (radeon_encoder->pixel_clock > 165000) |
737 | args.v2.acConfig.ucEncoderSel = 1; | 866 | args.v3.ucLaneNum = 8; |
867 | else | ||
868 | args.v3.ucLaneNum = 4; | ||
869 | |||
870 | if (dig_connector->linkb) { | ||
871 | args.v3.acConfig.ucLinkSel = 1; | ||
872 | args.v3.acConfig.ucEncoderSel = 1; | ||
873 | } | ||
874 | |||
875 | /* Select the PLL for the PHY | ||
876 | * DP PHY should be clocked from external src if there is | ||
877 | * one. | ||
878 | */ | ||
879 | if (encoder->crtc) { | ||
880 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc); | ||
881 | pll_id = radeon_crtc->pll_id; | ||
882 | } | ||
883 | if (is_dp && rdev->clock.dp_extclk) | ||
884 | args.v3.acConfig.ucRefClkSource = 2; /* external src */ | ||
885 | else | ||
886 | args.v3.acConfig.ucRefClkSource = pll_id; | ||
887 | |||
888 | switch (radeon_encoder->encoder_id) { | ||
889 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: | ||
890 | args.v3.acConfig.ucTransmitterSel = 0; | ||
891 | break; | ||
892 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: | ||
893 | args.v3.acConfig.ucTransmitterSel = 1; | ||
894 | break; | ||
895 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: | ||
896 | args.v3.acConfig.ucTransmitterSel = 2; | ||
897 | break; | ||
898 | } | ||
899 | |||
900 | if (is_dp) | ||
901 | args.v3.acConfig.fCoherentMode = 1; /* DP requires coherent */ | ||
902 | else if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) { | ||
903 | if (dig->coherent_mode) | ||
904 | args.v3.acConfig.fCoherentMode = 1; | ||
905 | if (radeon_encoder->pixel_clock > 165000) | ||
906 | args.v3.acConfig.fDualLinkConnector = 1; | ||
907 | } | ||
908 | } else if (ASIC_IS_DCE32(rdev)) { | ||
909 | args.v2.acConfig.ucEncoderSel = dig->dig_encoder; | ||
910 | if (dig_connector->linkb) | ||
911 | args.v2.acConfig.ucLinkSel = 1; | ||
738 | 912 | ||
739 | switch (radeon_encoder->encoder_id) { | 913 | switch (radeon_encoder->encoder_id) { |
740 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: | 914 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: |
741 | args.v2.acConfig.ucTransmitterSel = 0; | 915 | args.v2.acConfig.ucTransmitterSel = 0; |
742 | num = 0; | ||
743 | break; | 916 | break; |
744 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: | 917 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: |
745 | args.v2.acConfig.ucTransmitterSel = 1; | 918 | args.v2.acConfig.ucTransmitterSel = 1; |
746 | num = 1; | ||
747 | break; | 919 | break; |
748 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: | 920 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: |
749 | args.v2.acConfig.ucTransmitterSel = 2; | 921 | args.v2.acConfig.ucTransmitterSel = 2; |
750 | num = 2; | ||
751 | break; | 922 | break; |
752 | } | 923 | } |
753 | 924 | ||
754 | if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) { | 925 | if (is_dp) |
926 | args.v2.acConfig.fCoherentMode = 1; | ||
927 | else if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) { | ||
755 | if (dig->coherent_mode) | 928 | if (dig->coherent_mode) |
756 | args.v2.acConfig.fCoherentMode = 1; | 929 | args.v2.acConfig.fCoherentMode = 1; |
930 | if (radeon_encoder->pixel_clock > 165000) | ||
931 | args.v2.acConfig.fDualLinkConnector = 1; | ||
757 | } | 932 | } |
758 | } else { | 933 | } else { |
759 | args.v1.ucConfig = ATOM_TRANSMITTER_CONFIG_CLKSRC_PPLL; | 934 | args.v1.ucConfig = ATOM_TRANSMITTER_CONFIG_CLKSRC_PPLL; |
760 | 935 | ||
761 | switch (radeon_encoder->encoder_id) { | 936 | if (dig->dig_encoder) |
762 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: | 937 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_DIG2_ENCODER; |
938 | else | ||
763 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_DIG1_ENCODER; | 939 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_DIG1_ENCODER; |
764 | if (rdev->flags & RADEON_IS_IGP) { | 940 | |
765 | if (radeon_encoder->pixel_clock > 165000) { | 941 | if ((rdev->flags & RADEON_IS_IGP) && |
766 | args.v1.ucConfig |= (ATOM_TRANSMITTER_CONFIG_8LANE_LINK | | 942 | (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_UNIPHY)) { |
767 | ATOM_TRANSMITTER_CONFIG_LINKA_B); | 943 | if (is_dp || (radeon_encoder->pixel_clock <= 165000)) { |
768 | if (dig_connector->igp_lane_info & 0x3) | 944 | if (dig_connector->igp_lane_info & 0x1) |
769 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_0_7; | 945 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_0_3; |
770 | else if (dig_connector->igp_lane_info & 0xc) | 946 | else if (dig_connector->igp_lane_info & 0x2) |
771 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_8_15; | 947 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_4_7; |
772 | } else { | 948 | else if (dig_connector->igp_lane_info & 0x4) |
773 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKA; | 949 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_8_11; |
774 | if (dig_connector->igp_lane_info & 0x1) | 950 | else if (dig_connector->igp_lane_info & 0x8) |
775 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_0_3; | 951 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_12_15; |
776 | else if (dig_connector->igp_lane_info & 0x2) | ||
777 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_4_7; | ||
778 | else if (dig_connector->igp_lane_info & 0x4) | ||
779 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_8_11; | ||
780 | else if (dig_connector->igp_lane_info & 0x8) | ||
781 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_12_15; | ||
782 | } | ||
783 | } else { | 952 | } else { |
784 | if (radeon_encoder->pixel_clock > 165000) | 953 | if (dig_connector->igp_lane_info & 0x3) |
785 | args.v1.ucConfig |= (ATOM_TRANSMITTER_CONFIG_8LANE_LINK | | 954 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_0_7; |
786 | ATOM_TRANSMITTER_CONFIG_LINKA_B | | 955 | else if (dig_connector->igp_lane_info & 0xc) |
787 | ATOM_TRANSMITTER_CONFIG_LANE_0_7); | 956 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_8_15; |
788 | else { | ||
789 | if (dig_connector->linkb) | ||
790 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKB | ATOM_TRANSMITTER_CONFIG_LANE_0_3; | ||
791 | else | ||
792 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKA | ATOM_TRANSMITTER_CONFIG_LANE_0_3; | ||
793 | } | ||
794 | } | ||
795 | break; | ||
796 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: | ||
797 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_DIG2_ENCODER; | ||
798 | if (radeon_encoder->pixel_clock > 165000) | ||
799 | args.v1.ucConfig |= (ATOM_TRANSMITTER_CONFIG_8LANE_LINK | | ||
800 | ATOM_TRANSMITTER_CONFIG_LINKA_B | | ||
801 | ATOM_TRANSMITTER_CONFIG_LANE_0_7); | ||
802 | else { | ||
803 | if (dig_connector->linkb) | ||
804 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKB | ATOM_TRANSMITTER_CONFIG_LANE_0_3; | ||
805 | else | ||
806 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKA | ATOM_TRANSMITTER_CONFIG_LANE_0_3; | ||
807 | } | 957 | } |
808 | break; | ||
809 | } | 958 | } |
810 | 959 | ||
811 | if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) { | 960 | if (dig_connector->linkb) |
961 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKB; | ||
962 | else | ||
963 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKA; | ||
964 | |||
965 | if (is_dp) | ||
966 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_COHERENT; | ||
967 | else if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) { | ||
812 | if (dig->coherent_mode) | 968 | if (dig->coherent_mode) |
813 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_COHERENT; | 969 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_COHERENT; |
970 | if (radeon_encoder->pixel_clock > 165000) | ||
971 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_8LANE_LINK; | ||
814 | } | 972 | } |
815 | } | 973 | } |
816 | 974 | ||
817 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); | 975 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); |
818 | |||
819 | } | 976 | } |
820 | 977 | ||
821 | static void | 978 | static void |
@@ -918,12 +1075,25 @@ radeon_atom_encoder_dpms(struct drm_encoder *encoder, int mode) | |||
918 | if (is_dig) { | 1075 | if (is_dig) { |
919 | switch (mode) { | 1076 | switch (mode) { |
920 | case DRM_MODE_DPMS_ON: | 1077 | case DRM_MODE_DPMS_ON: |
921 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE); | 1078 | if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_DP) { |
1079 | struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); | ||
1080 | |||
1081 | dp_link_train(encoder, connector); | ||
1082 | if (ASIC_IS_DCE4(rdev)) | ||
1083 | atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_VIDEO_ON); | ||
1084 | } | ||
1085 | if (!ASIC_IS_DCE4(rdev)) | ||
1086 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE_OUTPUT, 0, 0); | ||
922 | break; | 1087 | break; |
923 | case DRM_MODE_DPMS_STANDBY: | 1088 | case DRM_MODE_DPMS_STANDBY: |
924 | case DRM_MODE_DPMS_SUSPEND: | 1089 | case DRM_MODE_DPMS_SUSPEND: |
925 | case DRM_MODE_DPMS_OFF: | 1090 | case DRM_MODE_DPMS_OFF: |
926 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE); | 1091 | if (!ASIC_IS_DCE4(rdev)) |
1092 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE_OUTPUT, 0, 0); | ||
1093 | if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_DP) { | ||
1094 | if (ASIC_IS_DCE4(rdev)) | ||
1095 | atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_VIDEO_OFF); | ||
1096 | } | ||
927 | break; | 1097 | break; |
928 | } | 1098 | } |
929 | } else { | 1099 | } else { |
@@ -940,9 +1110,12 @@ radeon_atom_encoder_dpms(struct drm_encoder *encoder, int mode) | |||
940 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); | 1110 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); |
941 | } | 1111 | } |
942 | radeon_atombios_encoder_dpms_scratch_regs(encoder, (mode == DRM_MODE_DPMS_ON) ? true : false); | 1112 | radeon_atombios_encoder_dpms_scratch_regs(encoder, (mode == DRM_MODE_DPMS_ON) ? true : false); |
1113 | |||
1114 | /* adjust pm to dpms change */ | ||
1115 | radeon_pm_compute_clocks(rdev); | ||
943 | } | 1116 | } |
944 | 1117 | ||
945 | union crtc_sourc_param { | 1118 | union crtc_source_param { |
946 | SELECT_CRTC_SOURCE_PS_ALLOCATION v1; | 1119 | SELECT_CRTC_SOURCE_PS_ALLOCATION v1; |
947 | SELECT_CRTC_SOURCE_PARAMETERS_V2 v2; | 1120 | SELECT_CRTC_SOURCE_PARAMETERS_V2 v2; |
948 | }; | 1121 | }; |
@@ -954,13 +1127,15 @@ atombios_set_encoder_crtc_source(struct drm_encoder *encoder) | |||
954 | struct radeon_device *rdev = dev->dev_private; | 1127 | struct radeon_device *rdev = dev->dev_private; |
955 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | 1128 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
956 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc); | 1129 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc); |
957 | union crtc_sourc_param args; | 1130 | union crtc_source_param args; |
958 | int index = GetIndexIntoMasterTable(COMMAND, SelectCRTC_Source); | 1131 | int index = GetIndexIntoMasterTable(COMMAND, SelectCRTC_Source); |
959 | uint8_t frev, crev; | 1132 | uint8_t frev, crev; |
1133 | struct radeon_encoder_atom_dig *dig; | ||
960 | 1134 | ||
961 | memset(&args, 0, sizeof(args)); | 1135 | memset(&args, 0, sizeof(args)); |
962 | 1136 | ||
963 | atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev); | 1137 | if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev)) |
1138 | return; | ||
964 | 1139 | ||
965 | switch (frev) { | 1140 | switch (frev) { |
966 | case 1: | 1141 | case 1: |
@@ -1020,20 +1195,32 @@ atombios_set_encoder_crtc_source(struct drm_encoder *encoder) | |||
1020 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: | 1195 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: |
1021 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: | 1196 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: |
1022 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: | 1197 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: |
1023 | if (ASIC_IS_DCE32(rdev)) { | 1198 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: |
1024 | if (radeon_crtc->crtc_id) | 1199 | dig = radeon_encoder->enc_priv; |
1025 | args.v2.ucEncoderID = ASIC_INT_DIG2_ENCODER_ID; | 1200 | switch (dig->dig_encoder) { |
1026 | else | 1201 | case 0: |
1027 | args.v2.ucEncoderID = ASIC_INT_DIG1_ENCODER_ID; | ||
1028 | } else | ||
1029 | args.v2.ucEncoderID = ASIC_INT_DIG1_ENCODER_ID; | 1202 | args.v2.ucEncoderID = ASIC_INT_DIG1_ENCODER_ID; |
1203 | break; | ||
1204 | case 1: | ||
1205 | args.v2.ucEncoderID = ASIC_INT_DIG2_ENCODER_ID; | ||
1206 | break; | ||
1207 | case 2: | ||
1208 | args.v2.ucEncoderID = ASIC_INT_DIG3_ENCODER_ID; | ||
1209 | break; | ||
1210 | case 3: | ||
1211 | args.v2.ucEncoderID = ASIC_INT_DIG4_ENCODER_ID; | ||
1212 | break; | ||
1213 | case 4: | ||
1214 | args.v2.ucEncoderID = ASIC_INT_DIG5_ENCODER_ID; | ||
1215 | break; | ||
1216 | case 5: | ||
1217 | args.v2.ucEncoderID = ASIC_INT_DIG6_ENCODER_ID; | ||
1218 | break; | ||
1219 | } | ||
1030 | break; | 1220 | break; |
1031 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1: | 1221 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1: |
1032 | args.v2.ucEncoderID = ASIC_INT_DVO_ENCODER_ID; | 1222 | args.v2.ucEncoderID = ASIC_INT_DVO_ENCODER_ID; |
1033 | break; | 1223 | break; |
1034 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: | ||
1035 | args.v2.ucEncoderID = ASIC_INT_DIG2_ENCODER_ID; | ||
1036 | break; | ||
1037 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1: | 1224 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1: |
1038 | if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT)) | 1225 | if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT)) |
1039 | args.v2.ucEncoderID = ASIC_INT_TV_ENCODER_ID; | 1226 | args.v2.ucEncoderID = ASIC_INT_TV_ENCODER_ID; |
@@ -1061,6 +1248,8 @@ atombios_set_encoder_crtc_source(struct drm_encoder *encoder) | |||
1061 | 1248 | ||
1062 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); | 1249 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); |
1063 | 1250 | ||
1251 | /* update scratch regs with new routing */ | ||
1252 | radeon_atombios_encoder_crtc_scratch_regs(encoder, radeon_crtc->crtc_id); | ||
1064 | } | 1253 | } |
1065 | 1254 | ||
1066 | static void | 1255 | static void |
@@ -1087,6 +1276,7 @@ atombios_apply_encoder_quirks(struct drm_encoder *encoder, | |||
1087 | } | 1276 | } |
1088 | 1277 | ||
1089 | /* set scaler clears this on some chips */ | 1278 | /* set scaler clears this on some chips */ |
1279 | /* XXX check DCE4 */ | ||
1090 | if (!(radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT))) { | 1280 | if (!(radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT))) { |
1091 | if (ASIC_IS_AVIVO(rdev) && (mode->flags & DRM_MODE_FLAG_INTERLACE)) | 1281 | if (ASIC_IS_AVIVO(rdev) && (mode->flags & DRM_MODE_FLAG_INTERLACE)) |
1092 | WREG32(AVIVO_D1MODE_DATA_FORMAT + radeon_crtc->crtc_offset, | 1282 | WREG32(AVIVO_D1MODE_DATA_FORMAT + radeon_crtc->crtc_offset, |
@@ -1094,6 +1284,74 @@ atombios_apply_encoder_quirks(struct drm_encoder *encoder, | |||
1094 | } | 1284 | } |
1095 | } | 1285 | } |
1096 | 1286 | ||
1287 | static int radeon_atom_pick_dig_encoder(struct drm_encoder *encoder) | ||
1288 | { | ||
1289 | struct drm_device *dev = encoder->dev; | ||
1290 | struct radeon_device *rdev = dev->dev_private; | ||
1291 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc); | ||
1292 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
1293 | struct drm_encoder *test_encoder; | ||
1294 | struct radeon_encoder_atom_dig *dig; | ||
1295 | uint32_t dig_enc_in_use = 0; | ||
1296 | |||
1297 | if (ASIC_IS_DCE4(rdev)) { | ||
1298 | struct radeon_connector_atom_dig *dig_connector = | ||
1299 | radeon_get_atom_connector_priv_from_encoder(encoder); | ||
1300 | |||
1301 | switch (radeon_encoder->encoder_id) { | ||
1302 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: | ||
1303 | if (dig_connector->linkb) | ||
1304 | return 1; | ||
1305 | else | ||
1306 | return 0; | ||
1307 | break; | ||
1308 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: | ||
1309 | if (dig_connector->linkb) | ||
1310 | return 3; | ||
1311 | else | ||
1312 | return 2; | ||
1313 | break; | ||
1314 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: | ||
1315 | if (dig_connector->linkb) | ||
1316 | return 5; | ||
1317 | else | ||
1318 | return 4; | ||
1319 | break; | ||
1320 | } | ||
1321 | } | ||
1322 | |||
1323 | /* on DCE32 and encoder can driver any block so just crtc id */ | ||
1324 | if (ASIC_IS_DCE32(rdev)) { | ||
1325 | return radeon_crtc->crtc_id; | ||
1326 | } | ||
1327 | |||
1328 | /* on DCE3 - LVTMA can only be driven by DIGB */ | ||
1329 | list_for_each_entry(test_encoder, &dev->mode_config.encoder_list, head) { | ||
1330 | struct radeon_encoder *radeon_test_encoder; | ||
1331 | |||
1332 | if (encoder == test_encoder) | ||
1333 | continue; | ||
1334 | |||
1335 | if (!radeon_encoder_is_digital(test_encoder)) | ||
1336 | continue; | ||
1337 | |||
1338 | radeon_test_encoder = to_radeon_encoder(test_encoder); | ||
1339 | dig = radeon_test_encoder->enc_priv; | ||
1340 | |||
1341 | if (dig->dig_encoder >= 0) | ||
1342 | dig_enc_in_use |= (1 << dig->dig_encoder); | ||
1343 | } | ||
1344 | |||
1345 | if (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA) { | ||
1346 | if (dig_enc_in_use & 0x2) | ||
1347 | DRM_ERROR("LVDS required digital encoder 2 but it was in use - stealing\n"); | ||
1348 | return 1; | ||
1349 | } | ||
1350 | if (!(dig_enc_in_use & 1)) | ||
1351 | return 0; | ||
1352 | return 1; | ||
1353 | } | ||
1354 | |||
1097 | static void | 1355 | static void |
1098 | radeon_atom_encoder_mode_set(struct drm_encoder *encoder, | 1356 | radeon_atom_encoder_mode_set(struct drm_encoder *encoder, |
1099 | struct drm_display_mode *mode, | 1357 | struct drm_display_mode *mode, |
@@ -1102,20 +1360,10 @@ radeon_atom_encoder_mode_set(struct drm_encoder *encoder, | |||
1102 | struct drm_device *dev = encoder->dev; | 1360 | struct drm_device *dev = encoder->dev; |
1103 | struct radeon_device *rdev = dev->dev_private; | 1361 | struct radeon_device *rdev = dev->dev_private; |
1104 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | 1362 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
1105 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc); | ||
1106 | |||
1107 | if (radeon_encoder->enc_priv) { | ||
1108 | struct radeon_encoder_atom_dig *dig; | ||
1109 | 1363 | ||
1110 | dig = radeon_encoder->enc_priv; | ||
1111 | dig->dig_block = radeon_crtc->crtc_id; | ||
1112 | } | ||
1113 | radeon_encoder->pixel_clock = adjusted_mode->clock; | 1364 | radeon_encoder->pixel_clock = adjusted_mode->clock; |
1114 | 1365 | ||
1115 | radeon_atombios_encoder_crtc_scratch_regs(encoder, radeon_crtc->crtc_id); | 1366 | if (ASIC_IS_AVIVO(rdev) && !ASIC_IS_DCE4(rdev)) { |
1116 | atombios_set_encoder_crtc_source(encoder); | ||
1117 | |||
1118 | if (ASIC_IS_AVIVO(rdev)) { | ||
1119 | if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT | ATOM_DEVICE_TV_SUPPORT)) | 1367 | if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT | ATOM_DEVICE_TV_SUPPORT)) |
1120 | atombios_yuv_setup(encoder, true); | 1368 | atombios_yuv_setup(encoder, true); |
1121 | else | 1369 | else |
@@ -1133,15 +1381,26 @@ radeon_atom_encoder_mode_set(struct drm_encoder *encoder, | |||
1133 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: | 1381 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: |
1134 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: | 1382 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: |
1135 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: | 1383 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: |
1136 | /* disable the encoder and transmitter */ | 1384 | if (ASIC_IS_DCE4(rdev)) { |
1137 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE); | 1385 | /* disable the transmitter */ |
1138 | atombios_dig_encoder_setup(encoder, ATOM_DISABLE); | 1386 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0); |
1139 | 1387 | /* setup and enable the encoder */ | |
1140 | /* setup and enable the encoder and transmitter */ | 1388 | atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_SETUP); |
1141 | atombios_dig_encoder_setup(encoder, ATOM_ENABLE); | 1389 | |
1142 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_INIT); | 1390 | /* init and enable the transmitter */ |
1143 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_SETUP); | 1391 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_INIT, 0, 0); |
1144 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE); | 1392 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0); |
1393 | } else { | ||
1394 | /* disable the encoder and transmitter */ | ||
1395 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0); | ||
1396 | atombios_dig_encoder_setup(encoder, ATOM_DISABLE); | ||
1397 | |||
1398 | /* setup and enable the encoder and transmitter */ | ||
1399 | atombios_dig_encoder_setup(encoder, ATOM_ENABLE); | ||
1400 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_INIT, 0, 0); | ||
1401 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_SETUP, 0, 0); | ||
1402 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0); | ||
1403 | } | ||
1145 | break; | 1404 | break; |
1146 | case ENCODER_OBJECT_ID_INTERNAL_DDI: | 1405 | case ENCODER_OBJECT_ID_INTERNAL_DDI: |
1147 | atombios_ddia_setup(encoder, ATOM_ENABLE); | 1406 | atombios_ddia_setup(encoder, ATOM_ENABLE); |
@@ -1155,11 +1414,20 @@ radeon_atom_encoder_mode_set(struct drm_encoder *encoder, | |||
1155 | case ENCODER_OBJECT_ID_INTERNAL_DAC2: | 1414 | case ENCODER_OBJECT_ID_INTERNAL_DAC2: |
1156 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2: | 1415 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2: |
1157 | atombios_dac_setup(encoder, ATOM_ENABLE); | 1416 | atombios_dac_setup(encoder, ATOM_ENABLE); |
1158 | if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT | ATOM_DEVICE_CV_SUPPORT)) | 1417 | if (radeon_encoder->devices & (ATOM_DEVICE_TV_SUPPORT | ATOM_DEVICE_CV_SUPPORT)) { |
1159 | atombios_tv_setup(encoder, ATOM_ENABLE); | 1418 | if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT | ATOM_DEVICE_CV_SUPPORT)) |
1419 | atombios_tv_setup(encoder, ATOM_ENABLE); | ||
1420 | else | ||
1421 | atombios_tv_setup(encoder, ATOM_DISABLE); | ||
1422 | } | ||
1160 | break; | 1423 | break; |
1161 | } | 1424 | } |
1162 | atombios_apply_encoder_quirks(encoder, adjusted_mode); | 1425 | atombios_apply_encoder_quirks(encoder, adjusted_mode); |
1426 | |||
1427 | if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_HDMI) { | ||
1428 | r600_hdmi_enable(encoder); | ||
1429 | r600_hdmi_setmode(encoder, adjusted_mode); | ||
1430 | } | ||
1163 | } | 1431 | } |
1164 | 1432 | ||
1165 | static bool | 1433 | static bool |
@@ -1179,7 +1447,8 @@ atombios_dac_load_detect(struct drm_encoder *encoder, struct drm_connector *conn | |||
1179 | 1447 | ||
1180 | memset(&args, 0, sizeof(args)); | 1448 | memset(&args, 0, sizeof(args)); |
1181 | 1449 | ||
1182 | atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev); | 1450 | if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev)) |
1451 | return false; | ||
1183 | 1452 | ||
1184 | args.sDacload.ucMisc = 0; | 1453 | args.sDacload.ucMisc = 0; |
1185 | 1454 | ||
@@ -1253,8 +1522,20 @@ radeon_atom_dac_detect(struct drm_encoder *encoder, struct drm_connector *connec | |||
1253 | 1522 | ||
1254 | static void radeon_atom_encoder_prepare(struct drm_encoder *encoder) | 1523 | static void radeon_atom_encoder_prepare(struct drm_encoder *encoder) |
1255 | { | 1524 | { |
1525 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
1526 | |||
1527 | if (radeon_encoder->active_device & | ||
1528 | (ATOM_DEVICE_DFP_SUPPORT | ATOM_DEVICE_LCD_SUPPORT)) { | ||
1529 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; | ||
1530 | if (dig) | ||
1531 | dig->dig_encoder = radeon_atom_pick_dig_encoder(encoder); | ||
1532 | } | ||
1533 | |||
1256 | radeon_atom_output_lock(encoder, true); | 1534 | radeon_atom_output_lock(encoder, true); |
1257 | radeon_atom_encoder_dpms(encoder, DRM_MODE_DPMS_OFF); | 1535 | radeon_atom_encoder_dpms(encoder, DRM_MODE_DPMS_OFF); |
1536 | |||
1537 | /* this is needed for the pll/ss setup to work correctly in some cases */ | ||
1538 | atombios_set_encoder_crtc_source(encoder); | ||
1258 | } | 1539 | } |
1259 | 1540 | ||
1260 | static void radeon_atom_encoder_commit(struct drm_encoder *encoder) | 1541 | static void radeon_atom_encoder_commit(struct drm_encoder *encoder) |
@@ -1266,7 +1547,15 @@ static void radeon_atom_encoder_commit(struct drm_encoder *encoder) | |||
1266 | static void radeon_atom_encoder_disable(struct drm_encoder *encoder) | 1547 | static void radeon_atom_encoder_disable(struct drm_encoder *encoder) |
1267 | { | 1548 | { |
1268 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | 1549 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
1550 | struct radeon_encoder_atom_dig *dig; | ||
1269 | radeon_atom_encoder_dpms(encoder, DRM_MODE_DPMS_OFF); | 1551 | radeon_atom_encoder_dpms(encoder, DRM_MODE_DPMS_OFF); |
1552 | |||
1553 | if (radeon_encoder_is_digital(encoder)) { | ||
1554 | if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_HDMI) | ||
1555 | r600_hdmi_disable(encoder); | ||
1556 | dig = radeon_encoder->enc_priv; | ||
1557 | dig->dig_encoder = -1; | ||
1558 | } | ||
1270 | radeon_encoder->active_device = 0; | 1559 | radeon_encoder->active_device = 0; |
1271 | } | 1560 | } |
1272 | 1561 | ||
@@ -1304,12 +1593,14 @@ static const struct drm_encoder_funcs radeon_atom_enc_funcs = { | |||
1304 | struct radeon_encoder_atom_dac * | 1593 | struct radeon_encoder_atom_dac * |
1305 | radeon_atombios_set_dac_info(struct radeon_encoder *radeon_encoder) | 1594 | radeon_atombios_set_dac_info(struct radeon_encoder *radeon_encoder) |
1306 | { | 1595 | { |
1596 | struct drm_device *dev = radeon_encoder->base.dev; | ||
1597 | struct radeon_device *rdev = dev->dev_private; | ||
1307 | struct radeon_encoder_atom_dac *dac = kzalloc(sizeof(struct radeon_encoder_atom_dac), GFP_KERNEL); | 1598 | struct radeon_encoder_atom_dac *dac = kzalloc(sizeof(struct radeon_encoder_atom_dac), GFP_KERNEL); |
1308 | 1599 | ||
1309 | if (!dac) | 1600 | if (!dac) |
1310 | return NULL; | 1601 | return NULL; |
1311 | 1602 | ||
1312 | dac->tv_std = TV_STD_NTSC; | 1603 | dac->tv_std = radeon_atombios_get_tv_info(rdev); |
1313 | return dac; | 1604 | return dac; |
1314 | } | 1605 | } |
1315 | 1606 | ||
@@ -1323,6 +1614,7 @@ radeon_atombios_set_dig_info(struct radeon_encoder *radeon_encoder) | |||
1323 | 1614 | ||
1324 | /* coherent mode by default */ | 1615 | /* coherent mode by default */ |
1325 | dig->coherent_mode = true; | 1616 | dig->coherent_mode = true; |
1617 | dig->dig_encoder = -1; | ||
1326 | 1618 | ||
1327 | return dig; | 1619 | return dig; |
1328 | } | 1620 | } |
@@ -1350,11 +1642,18 @@ radeon_add_atom_encoder(struct drm_device *dev, uint32_t encoder_id, uint32_t su | |||
1350 | return; | 1642 | return; |
1351 | 1643 | ||
1352 | encoder = &radeon_encoder->base; | 1644 | encoder = &radeon_encoder->base; |
1353 | if (rdev->flags & RADEON_SINGLE_CRTC) | 1645 | switch (rdev->num_crtc) { |
1646 | case 1: | ||
1354 | encoder->possible_crtcs = 0x1; | 1647 | encoder->possible_crtcs = 0x1; |
1355 | else | 1648 | break; |
1649 | case 2: | ||
1650 | default: | ||
1356 | encoder->possible_crtcs = 0x3; | 1651 | encoder->possible_crtcs = 0x3; |
1357 | encoder->possible_clones = 0; | 1652 | break; |
1653 | case 6: | ||
1654 | encoder->possible_crtcs = 0x3f; | ||
1655 | break; | ||
1656 | } | ||
1358 | 1657 | ||
1359 | radeon_encoder->enc_priv = NULL; | 1658 | radeon_encoder->enc_priv = NULL; |
1360 | 1659 | ||
@@ -1379,6 +1678,7 @@ radeon_add_atom_encoder(struct drm_device *dev, uint32_t encoder_id, uint32_t su | |||
1379 | break; | 1678 | break; |
1380 | case ENCODER_OBJECT_ID_INTERNAL_DAC1: | 1679 | case ENCODER_OBJECT_ID_INTERNAL_DAC1: |
1381 | drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_DAC); | 1680 | drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_DAC); |
1681 | radeon_encoder->enc_priv = radeon_atombios_set_dac_info(radeon_encoder); | ||
1382 | drm_encoder_helper_add(encoder, &radeon_atom_dac_helper_funcs); | 1682 | drm_encoder_helper_add(encoder, &radeon_atom_dac_helper_funcs); |
1383 | break; | 1683 | break; |
1384 | case ENCODER_OBJECT_ID_INTERNAL_DAC2: | 1684 | case ENCODER_OBJECT_ID_INTERNAL_DAC2: |