drm/radeon/kms: add support for encoder cloning.
authorDave Airlie <airlied@redhat.com>
Tue, 13 Oct 2009 04:10:37 +0000 (14:10 +1000)
committerDave Airlie <airlied@redhat.com>
Wed, 2 Dec 2009 01:37:09 +0000 (11:37 +1000)
The RN50 really needs this since its a single crtc card,
however other gpus may benefit from it as well.

Signed-off-by: Dave Airlie <airlied@redhat.com>
drivers/gpu/drm/radeon/radeon_display.c
drivers/gpu/drm/radeon/radeon_encoders.c
drivers/gpu/drm/radeon/radeon_legacy_encoders.c
drivers/gpu/drm/radeon/radeon_mode.h

index 5859109f924ddf77697b5a2faf137bc2ab926057..62b02372cb097c64179c9fe2b993c5f6a0ff805c 100644 (file)
@@ -324,6 +324,7 @@ static bool radeon_setup_enc_conn(struct drm_device *dev)
                        ret = radeon_get_legacy_connector_info_from_table(dev);
        }
        if (ret) {
+               radeon_setup_encoder_clones(dev);
                radeon_print_display_setup(dev);
                list_for_each_entry(drm_connector, &dev->mode_config.connector_list, head)
                        radeon_ddc_dump(drm_connector);
index 57a29f36115eb3859774bcdfaea4cd3343859ed8..52e484fc75ffdbc9e3d0e1bc89349d1ce305f36a 100644 (file)
@@ -35,6 +35,51 @@ extern int atom_debug;
 bool radeon_atom_get_tv_timings(struct radeon_device *rdev, int index,
                                struct drm_display_mode *mode);
 
+static uint32_t radeon_encoder_clones(struct drm_encoder *encoder)
+{
+       struct drm_device *dev = encoder->dev;
+       struct radeon_device *rdev = dev->dev_private;
+       struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+       struct drm_encoder *clone_encoder;
+       uint32_t index_mask = 0;
+       int count;
+
+       /* DIG routing gets problematic */
+       if (rdev->family >= CHIP_R600)
+               return index_mask;
+       /* LVDS/TV are too wacky */
+       if (radeon_encoder->devices & ATOM_DEVICE_LCD_SUPPORT)
+               return index_mask;
+       /* DVO requires 2x ppll clocks depending on tmds chip */
+       if (radeon_encoder->devices & ATOM_DEVICE_DFP2_SUPPORT)
+               return index_mask;
+       
+       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_DFP2_SUPPORT)
+                       continue;
+               else
+                       index_mask |= (1 << count);
+       }
+       return index_mask;
+}
+
+void radeon_setup_encoder_clones(struct drm_device *dev)
+{
+       struct drm_encoder *encoder;
+
+       list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
+               encoder->possible_clones = radeon_encoder_clones(encoder);
+       }
+}
+
 uint32_t
 radeon_get_encoder_id(struct drm_device *dev, uint32_t supported_device, uint8_t dac)
 {
@@ -1341,7 +1386,6 @@ radeon_add_atom_encoder(struct drm_device *dev, uint32_t encoder_id, uint32_t su
                encoder->possible_crtcs = 0x1;
        else
                encoder->possible_crtcs = 0x3;
-       encoder->possible_clones = 0;
 
        radeon_encoder->enc_priv = NULL;
 
index ae554bfa05488249ea9b03d6414b282dac6d5eb6..36ac47672a3c4718f7934e665162f3c4e28af349 100644 (file)
@@ -1331,7 +1331,6 @@ radeon_add_legacy_encoder(struct drm_device *dev, uint32_t encoder_id, uint32_t
                encoder->possible_crtcs = 0x1;
        else
                encoder->possible_crtcs = 0x3;
-       encoder->possible_clones = 0;
 
        radeon_encoder->enc_priv = NULL;
 
index d7a29ce19df894d87ce36a805d9985a0612fda3a..5c25930d9bcf0c75366231812117ccd5d9c9ccf9 100644 (file)
@@ -377,6 +377,8 @@ extern void radeon_compute_pll(struct radeon_pll *pll,
                               uint32_t *post_div_p,
                               int flags);
 
+extern void radeon_setup_encoder_clones(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);