From: Dave Airlie <airl...@redhat.com> The RN50 really needs this since its a single crtc card, however other gpus may benefit from it as well.
Changes since v1: add the clones after initialising all the encoders. Userspace DDX changes are required as it reports connector clones over randr not encoder clones so it needs some impedance matching in radeon_encoders.c Signed-off-by: Dave Airlie <airl...@redhat.com> --- drivers/gpu/drm/radeon/radeon_atombios.c | 2 + drivers/gpu/drm/radeon/radeon_combios.c | 2 + drivers/gpu/drm/radeon/radeon_encoders.c | 41 ++++++++++++++++++++++- drivers/gpu/drm/radeon/radeon_legacy_encoders.c | 1 - drivers/gpu/drm/radeon/radeon_mode.h | 1 + 5 files changed, 45 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c index 79d4b77..e2c7f26 100644 --- a/drivers/gpu/drm/radeon/radeon_atombios.c +++ b/drivers/gpu/drm/radeon/radeon_atombios.c @@ -430,6 +430,7 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev) } } + radeon_encoder_setup_cloning(dev); radeon_link_encoder_connector(dev); return true; @@ -603,6 +604,7 @@ bool radeon_get_atom_connector_info_from_supported_devices_table(struct false, 0); } + radeon_encoder_setup_cloning(dev); radeon_link_encoder_connector(dev); return true; diff --git a/drivers/gpu/drm/radeon/radeon_combios.c b/drivers/gpu/drm/radeon/radeon_combios.c index e91aba8..d10fbda 100644 --- a/drivers/gpu/drm/radeon/radeon_combios.c +++ b/drivers/gpu/drm/radeon/radeon_combios.c @@ -1510,6 +1510,7 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) return false; } + radeon_encoder_setup_cloning(dev); radeon_link_encoder_connector(dev); return true; @@ -1892,6 +1893,7 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev) } } + radeon_encoder_setup_cloning(dev); radeon_link_encoder_connector(dev); return true; diff --git a/drivers/gpu/drm/radeon/radeon_encoders.c b/drivers/gpu/drm/radeon/radeon_encoders.c index 10845f3..698a4d1 100644 --- a/drivers/gpu/drm/radeon/radeon_encoders.c +++ b/drivers/gpu/drm/radeon/radeon_encoders.c @@ -35,6 +35,45 @@ extern int atom_debug; bool radeon_atom_get_tv_timings(struct radeon_device *rdev, int index, struct drm_display_mode *mode); +void radeon_encoder_setup_cloning(struct drm_device *dev) +{ + struct radeon_device *rdev = dev->dev_private; + struct drm_encoder *encoder, *clone_encoder; + uint32_t index_mask = 0; + int count; + + list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { + struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); + index_mask = 0; + + encoder->possible_clones = 0; + /* DIG routing gets problematic */ + if (ASIC_IS_DCE32(rdev)) + continue; + /* LVDS/TV are too wacky */ + if (radeon_encoder->devices & ATOM_DEVICE_LCD_SUPPORT) + continue; + if (radeon_encoder->devices & ATOM_DEVICE_TV_SUPPORT) + continue; + + + count = -1; + list_for_each_entry(clone_encoder, &dev->mode_config.encoder_list, head) { + struct radeon_encoder *radeon_clone = to_radeon_encoder(clone_encoder); + count++; + if (clone_encoder == encoder) + continue; + if (radeon_clone->devices & (ATOM_DEVICE_LCD_SUPPORT)) + continue; + if (radeon_clone->devices & (ATOM_DEVICE_TV_SUPPORT)) + continue; + else + index_mask |= (1 << count); + } + encoder->possible_clones = index_mask; + } +} + uint32_t radeon_get_encoder_id(struct drm_device *dev, uint32_t supported_device, uint8_t dac) { @@ -1356,7 +1395,6 @@ radeon_add_atom_encoder(struct drm_device *dev, uint32_t encoder_id, uint32_t su else encoder->possible_crtcs = 0x3; encoder->possible_clones = 0; - radeon_encoder->enc_priv = NULL; radeon_encoder->encoder_id = encoder_id; @@ -1407,4 +1445,5 @@ radeon_add_atom_encoder(struct drm_device *dev, uint32_t encoder_id, uint32_t su drm_encoder_helper_add(encoder, &radeon_atom_dig_helper_funcs); break; } + } diff --git a/drivers/gpu/drm/radeon/radeon_legacy_encoders.c b/drivers/gpu/drm/radeon/radeon_legacy_encoders.c index 6ceb958..aaf6962 100644 --- a/drivers/gpu/drm/radeon/radeon_legacy_encoders.c +++ b/drivers/gpu/drm/radeon/radeon_legacy_encoders.c @@ -1323,7 +1323,6 @@ radeon_add_legacy_encoder(struct drm_device *dev, uint32_t encoder_id, uint32_t else encoder->possible_crtcs = 0x3; encoder->possible_clones = 0; - radeon_encoder->enc_priv = NULL; radeon_encoder->encoder_id = encoder_id; diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h index 3d2631b..157ee1a 100644 --- a/drivers/gpu/drm/radeon/radeon_mode.h +++ b/drivers/gpu/drm/radeon/radeon_mode.h @@ -328,6 +328,7 @@ extern void radeon_compute_pll(struct radeon_pll *pll, uint32_t *post_div_p, int flags); +extern void radeon_encoder_setup_cloning(struct drm_device *dev); struct drm_encoder *radeon_encoder_legacy_lvds_add(struct drm_device *dev, int bios_index); struct drm_encoder *radeon_encoder_legacy_primary_dac_add(struct drm_device *dev, int bios_index, int with_tv); struct drm_encoder *radeon_encoder_legacy_tv_dac_add(struct drm_device *dev, int bios_index, int with_tv); -- 1.6.5.rc2 ------------------------------------------------------------------------------ Come build with us! The BlackBerry(R) Developer Conference in SF, CA is the only developer event you need to attend this year. Jumpstart your developing skills, take BlackBerry mobile applications to market and stay ahead of the curve. Join us from November 9 - 12, 2009. Register now! http://p.sf.net/sfu/devconference -- _______________________________________________ Dri-devel mailing list Dri-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/dri-devel