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

Reply via email to