drm/radeon/kms: get HPD info for connectors
Alex Deucher [Fri, 4 Dec 2009 19:45:27 +0000 (14:45 -0500)]
This populates the connectors with HPD (Hot Plug Detect)
information.  This will be used in subsequent patches
for automatic digital monitor connect/disconnect handling.

Signed-off-by: Alex Deucher <alexdeucher@gmail.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>

drivers/gpu/drm/radeon/atombios.h
drivers/gpu/drm/radeon/r500_reg.h
drivers/gpu/drm/radeon/radeon_atombios.c
drivers/gpu/drm/radeon/radeon_combios.c
drivers/gpu/drm/radeon/radeon_connectors.c
drivers/gpu/drm/radeon/radeon_display.c
drivers/gpu/drm/radeon/radeon_mode.h

index c11dddd..e839276 100644 (file)
@@ -2680,7 +2680,7 @@ typedef struct _ATOM_I2C_RECORD {
 typedef struct _ATOM_HPD_INT_RECORD {
        ATOM_COMMON_RECORD_HEADER sheader;
        UCHAR ucHPDIntGPIOID;   /* Corresponding block in GPIO_PIN_INFO table gives the pin info */
-       UCHAR ucPluggged_PinState;
+       UCHAR ucPlugged_PinState;
 } ATOM_HPD_INT_RECORD;
 
 typedef struct _ATOM_OUTPUT_PROTECTION_RECORD {
index 7baa739..74ad89b 100644 (file)
 
 #define AVIVO_DVOA_BIT_DEPTH_CONTROL                   0x7988
 
+#define AVIVO_DC_GPIO_HPD_A                 0x7e94
+
 #define AVIVO_GPIO_0                        0x7e30
 #define AVIVO_GPIO_1                        0x7e40
 #define AVIVO_GPIO_2                        0x7e50
index 87bf6b9..d7b0feb 100644 (file)
@@ -47,7 +47,8 @@ radeon_add_atom_connector(struct drm_device *dev,
                          int connector_type,
                          struct radeon_i2c_bus_rec *i2c_bus,
                          bool linkb, uint32_t igp_lane_info,
-                         uint16_t connector_object_id);
+                         uint16_t connector_object_id,
+                         struct radeon_hpd *hpd);
 
 /* from radeon_legacy_encoder.c */
 extern void
@@ -60,10 +61,9 @@ union atom_supported_devices {
        struct _ATOM_SUPPORTED_DEVICES_INFO_2d1 info_2d1;
 };
 
-static inline struct radeon_i2c_bus_rec radeon_lookup_gpio(struct drm_device *dev,
-                                                          uint8_t id)
+static inline struct radeon_i2c_bus_rec radeon_lookup_i2c_gpio(struct radeon_device *rdev,
+                                                              uint8_t id)
 {
-       struct radeon_device *rdev = dev->dev_private;
        struct atom_context *ctx = rdev->mode_info.atom_context;
        ATOM_GPIO_I2C_ASSIGMENT *gpio;
        struct radeon_i2c_bus_rec i2c;
@@ -114,11 +114,80 @@ static inline struct radeon_i2c_bus_rec radeon_lookup_gpio(struct drm_device *de
        return i2c;
 }
 
+static inline struct radeon_gpio_rec radeon_lookup_gpio(struct radeon_device *rdev,
+                                                       u8 id)
+{
+       struct atom_context *ctx = rdev->mode_info.atom_context;
+       struct radeon_gpio_rec gpio;
+       int index = GetIndexIntoMasterTable(DATA, GPIO_Pin_LUT);
+       struct _ATOM_GPIO_PIN_LUT *gpio_info;
+       ATOM_GPIO_PIN_ASSIGNMENT *pin;
+       u16 data_offset, size;
+       int i, num_indices;
+
+       memset(&gpio, 0, sizeof(struct radeon_gpio_rec));
+       gpio.valid = false;
+
+       atom_parse_data_header(ctx, index, &size, NULL, NULL, &data_offset);
+
+       gpio_info = (struct _ATOM_GPIO_PIN_LUT *)(ctx->bios + data_offset);
+
+       num_indices = (size - sizeof(ATOM_COMMON_TABLE_HEADER)) / sizeof(ATOM_GPIO_PIN_ASSIGNMENT);
+
+       for (i = 0; i < num_indices; i++) {
+               pin = &gpio_info->asGPIO_Pin[i];
+               if (id == pin->ucGPIO_ID) {
+                       gpio.id = pin->ucGPIO_ID;
+                       gpio.reg = pin->usGpioPin_AIndex * 4;
+                       gpio.mask = (1 << pin->ucGpioPinBitShift);
+                       gpio.valid = true;
+                       break;
+               }
+       }
+
+       return gpio;
+}
+
+static struct radeon_hpd radeon_atom_get_hpd_info_from_gpio(struct radeon_device *rdev,
+                                                           struct radeon_gpio_rec *gpio)
+{
+       struct radeon_hpd hpd;
+       hpd.gpio = *gpio;
+       if (gpio->reg == AVIVO_DC_GPIO_HPD_A) {
+               switch(gpio->mask) {
+               case (1 << 0):
+                       hpd.hpd = RADEON_HPD_1;
+                       break;
+               case (1 << 8):
+                       hpd.hpd = RADEON_HPD_2;
+                       break;
+               case (1 << 16):
+                       hpd.hpd = RADEON_HPD_3;
+                       break;
+               case (1 << 24):
+                       hpd.hpd = RADEON_HPD_4;
+                       break;
+               case (1 << 26):
+                       hpd.hpd = RADEON_HPD_5;
+                       break;
+               case (1 << 28):
+                       hpd.hpd = RADEON_HPD_6;
+                       break;
+               default:
+                       hpd.hpd = RADEON_HPD_NONE;
+                       break;
+               }
+       } else
+               hpd.hpd = RADEON_HPD_NONE;
+       return hpd;
+}
+
 static bool radeon_atom_apply_quirks(struct drm_device *dev,
                                     uint32_t supported_device,
                                     int *connector_type,
                                     struct radeon_i2c_bus_rec *i2c_bus,
-                                    uint16_t *line_mux)
+                                    uint16_t *line_mux,
+                                    struct radeon_hpd *hpd)
 {
 
        /* Asus M2A-VM HDMI board lists the DVI port as HDMI */
@@ -279,16 +348,19 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev)
        struct radeon_mode_info *mode_info = &rdev->mode_info;
        struct atom_context *ctx = mode_info->atom_context;
        int index = GetIndexIntoMasterTable(DATA, Object_Header);
-       uint16_t size, data_offset;
-       uint8_t frev, crev, line_mux = 0;
+       u16 size, data_offset;
+       u8 frev, crev;
        ATOM_CONNECTOR_OBJECT_TABLE *con_obj;
        ATOM_DISPLAY_OBJECT_PATH_TABLE *path_obj;
        ATOM_OBJECT_HEADER *obj_header;
        int i, j, path_size, device_support;
        int connector_type;
-       uint16_t igp_lane_info, conn_id, connector_object_id;
+       u16 igp_lane_info, conn_id, connector_object_id;
        bool linkb;
        struct radeon_i2c_bus_rec ddc_bus;
+       struct radeon_gpio_rec gpio;
+       struct radeon_hpd hpd;
+
        atom_parse_data_header(ctx, index, &size, &frev, &crev, &data_offset);
 
        if (data_offset == 0)
@@ -414,10 +486,9 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev)
                                }
                        }
 
-                       /* look up gpio for ddc */
+                       /* look up gpio for ddc, hpd */
                        if ((le16_to_cpu(path->usDeviceTag) &
-                            (ATOM_DEVICE_TV_SUPPORT | ATOM_DEVICE_CV_SUPPORT))
-                           == 0) {
+                            (ATOM_DEVICE_TV_SUPPORT | ATOM_DEVICE_CV_SUPPORT)) == 0) {
                                for (j = 0; j < con_obj->ucNumberOfObjects; j++) {
                                        if (le16_to_cpu(path->usConnObjectId) ==
                                            le16_to_cpu(con_obj->asObjects[j].
@@ -431,21 +502,31 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev)
                                                                 asObjects[j].
                                                                 usRecordOffset));
                                                ATOM_I2C_RECORD *i2c_record;
+                                               ATOM_HPD_INT_RECORD *hpd_record;
+                                               hpd.hpd = RADEON_HPD_NONE;
 
                                                while (record->ucRecordType > 0
                                                       && record->
                                                       ucRecordType <=
                                                       ATOM_MAX_OBJECT_RECORD_NUMBER) {
-                                                       switch (record->
-                                                               ucRecordType) {
+                                                       switch (record->ucRecordType) {
                                                        case ATOM_I2C_RECORD_TYPE:
                                                                i2c_record =
-                                                                   (ATOM_I2C_RECORD
-                                                                    *) record;
-                                                               line_mux =
-                                                                   i2c_record->
-                                                                   sucI2cId.
-                                                                   bfI2C_LineMux;
+                                                                   (ATOM_I2C_RECORD *)
+                                                                       record;
+                                                               ddc_bus = radeon_lookup_i2c_gpio(rdev,
+                                                                                                i2c_record->
+                                                                                                sucI2cId.
+                                                                                                bfI2C_LineMux);
+                                                               break;
+                                                       case ATOM_HPD_INT_RECORD_TYPE:
+                                                               hpd_record =
+                                                                       (ATOM_HPD_INT_RECORD *)
+                                                                       record;
+                                                               gpio = radeon_lookup_gpio(rdev,
+                                                                                         hpd_record->ucHPDIntGPIOID);
+                                                               hpd = radeon_atom_get_hpd_info_from_gpio(rdev, &gpio);
+                                                               hpd.plugged_state = hpd_record->ucPlugged_PinState;
                                                                break;
                                                        }
                                                        record =
@@ -458,24 +539,16 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev)
                                                break;
                                        }
                                }
-                       } else
-                               line_mux = 0;
-
-                       if ((le16_to_cpu(path->usDeviceTag) ==
-                            ATOM_DEVICE_TV1_SUPPORT)
-                           || (le16_to_cpu(path->usDeviceTag) ==
-                               ATOM_DEVICE_TV2_SUPPORT)
-                           || (le16_to_cpu(path->usDeviceTag) ==
-                               ATOM_DEVICE_CV_SUPPORT))
+                       } else {
+                               hpd.hpd = RADEON_HPD_NONE;
                                ddc_bus.valid = false;
-                       else
-                               ddc_bus = radeon_lookup_gpio(dev, line_mux);
+                       }
 
                        conn_id = le16_to_cpu(path->usConnObjectId);
 
                        if (!radeon_atom_apply_quirks
                            (dev, le16_to_cpu(path->usDeviceTag), &connector_type,
-                            &ddc_bus, &conn_id))
+                            &ddc_bus, &conn_id, &hpd))
                                continue;
 
                        radeon_add_atom_connector(dev,
@@ -484,7 +557,8 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev)
                                                              usDeviceTag),
                                                  connector_type, &ddc_bus,
                                                  linkb, igp_lane_info,
-                                                 connector_object_id);
+                                                 connector_object_id,
+                                                 &hpd);
 
                }
        }
@@ -539,6 +613,7 @@ struct bios_connector {
        uint16_t devices;
        int connector_type;
        struct radeon_i2c_bus_rec ddc_bus;
+       struct radeon_hpd hpd;
 };
 
 bool radeon_get_atom_connector_info_from_supported_devices_table(struct
@@ -554,7 +629,7 @@ bool radeon_get_atom_connector_info_from_supported_devices_table(struct
        uint16_t device_support;
        uint8_t dac;
        union atom_supported_devices *supported_devices;
-       int i, j;
+       int i, j, max_device;
        struct bios_connector bios_connectors[ATOM_MAX_SUPPORTED_DEVICE];
 
        atom_parse_data_header(ctx, index, &size, &frev, &crev, &data_offset);
@@ -564,7 +639,12 @@ bool radeon_get_atom_connector_info_from_supported_devices_table(struct
 
        device_support = le16_to_cpu(supported_devices->info.usDeviceSupport);
 
-       for (i = 0; i < ATOM_MAX_SUPPORTED_DEVICE; i++) {
+       if (frev > 1)
+               max_device = ATOM_MAX_SUPPORTED_DEVICE;
+       else
+               max_device = ATOM_MAX_SUPPORTED_DEVICE_INFO;
+
+       for (i = 0; i < max_device; i++) {
                ATOM_CONNECTOR_INFO_I2C ci =
                    supported_devices->info.asConnInfo[i];
 
@@ -619,8 +699,30 @@ bool radeon_get_atom_connector_info_from_supported_devices_table(struct
                        bios_connectors[i].line_mux = 52;
                } else
                        bios_connectors[i].ddc_bus =
-                           radeon_lookup_gpio(dev,
-                                              bios_connectors[i].line_mux);
+                           radeon_lookup_i2c_gpio(rdev,
+                                                  bios_connectors[i].line_mux);
+
+               if ((crev > 1) && (frev > 1)) {
+                       u8 isb = supported_devices->info_2d1.asIntSrcInfo[i].ucIntSrcBitmap;
+                       switch (isb) {
+                       case 0x4:
+                               bios_connectors[i].hpd.hpd = RADEON_HPD_1;
+                               break;
+                       case 0xa:
+                               bios_connectors[i].hpd.hpd = RADEON_HPD_2;
+                               break;
+                       default:
+                               bios_connectors[i].hpd.hpd = RADEON_HPD_NONE;
+                               break;
+                       }
+               } else {
+                       if (i == ATOM_DEVICE_DFP1_INDEX)
+                               bios_connectors[i].hpd.hpd = RADEON_HPD_1;
+                       else if (i == ATOM_DEVICE_DFP2_INDEX)
+                               bios_connectors[i].hpd.hpd = RADEON_HPD_2;
+                       else
+                               bios_connectors[i].hpd.hpd = RADEON_HPD_NONE;
+               }
 
                /* Always set the connector type to VGA for CRT1/CRT2. if they are
                 * shared with a DVI port, we'll pick up the DVI connector when we
@@ -632,7 +734,8 @@ bool radeon_get_atom_connector_info_from_supported_devices_table(struct
 
                if (!radeon_atom_apply_quirks
                    (dev, (1 << i), &bios_connectors[i].connector_type,
-                    &bios_connectors[i].ddc_bus, &bios_connectors[i].line_mux))
+                    &bios_connectors[i].ddc_bus, &bios_connectors[i].line_mux,
+                    &bios_connectors[i].hpd))
                        continue;
 
                bios_connectors[i].valid = true;
@@ -654,9 +757,9 @@ bool radeon_get_atom_connector_info_from_supported_devices_table(struct
        }
 
        /* combine shared connectors */
-       for (i = 0; i < ATOM_MAX_SUPPORTED_DEVICE; i++) {
+       for (i = 0; i < max_device; i++) {
                if (bios_connectors[i].valid) {
-                       for (j = 0; j < ATOM_MAX_SUPPORTED_DEVICE; j++) {
+                       for (j = 0; j < max_device; j++) {
                                if (bios_connectors[j].valid && (i != j)) {
                                        if (bios_connectors[i].line_mux ==
                                            bios_connectors[j].line_mux) {
@@ -680,6 +783,10 @@ bool radeon_get_atom_connector_info_from_supported_devices_table(struct
                                                        bios_connectors[i].
                                                            connector_type =
                                                            DRM_MODE_CONNECTOR_DVII;
+                                                       if (bios_connectors[j].devices &
+                                                           (ATOM_DEVICE_DFP_SUPPORT))
+                                                               bios_connectors[i].hpd =
+                                                                       bios_connectors[j].hpd;
                                                        bios_connectors[j].
                                                            valid = false;
                                                }
@@ -690,7 +797,7 @@ bool radeon_get_atom_connector_info_from_supported_devices_table(struct
        }
 
        /* add the connectors */
-       for (i = 0; i < ATOM_MAX_SUPPORTED_DEVICE; i++) {
+       for (i = 0; i < max_device; i++) {
                if (bios_connectors[i].valid) {
                        uint16_t connector_object_id =
                                atombios_get_connector_object_id(dev,
@@ -703,7 +810,8 @@ bool radeon_get_atom_connector_info_from_supported_devices_table(struct
                                                  connector_type,
                                                  &bios_connectors[i].ddc_bus,
                                                  false, 0,
-                                                 connector_object_id);
+                                                 connector_object_id,
+                                                 &bios_connectors[i].hpd);
                }
        }
 
index b6761cd..c5021a3 100644 (file)
@@ -50,7 +50,8 @@ radeon_add_legacy_connector(struct drm_device *dev,
                            uint32_t supported_device,
                            int connector_type,
                            struct radeon_i2c_bus_rec *i2c_bus,
-                           uint16_t connector_object_id);
+                           uint16_t connector_object_id,
+                           struct radeon_hpd *hpd);
 
 /* from radeon_legacy_encoder.c */
 extern void
@@ -1226,6 +1227,7 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
 {
        struct radeon_device *rdev = dev->dev_private;
        struct radeon_i2c_bus_rec ddc_i2c;
+       struct radeon_hpd hpd;
 
        rdev->mode_info.connector_table = radeon_connector_table;
        if (rdev->mode_info.connector_table == CT_NONE) {
@@ -1287,6 +1289,7 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
                if (rdev->flags & RADEON_SINGLE_CRTC) {
                        /* VGA - primary dac */
                        ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_VGA_DDC);
+                       hpd.hpd = RADEON_HPD_NONE;
                        radeon_add_legacy_encoder(dev,
                                                  radeon_get_encoder_id(dev,
                                                                        ATOM_DEVICE_CRT1_SUPPORT,
@@ -1296,10 +1299,12 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
                                                    ATOM_DEVICE_CRT1_SUPPORT,
                                                    DRM_MODE_CONNECTOR_VGA,
                                                    &ddc_i2c,
-                                                   CONNECTOR_OBJECT_ID_VGA);
+                                                   CONNECTOR_OBJECT_ID_VGA,
+                                                   &hpd);
                } else if (rdev->flags & RADEON_IS_MOBILITY) {
                        /* LVDS */
                        ddc_i2c = combios_setup_i2c_bus(rdev, 0);
+                       hpd.hpd = RADEON_HPD_NONE;
                        radeon_add_legacy_encoder(dev,
                                                  radeon_get_encoder_id(dev,
                                                                        ATOM_DEVICE_LCD1_SUPPORT,
@@ -1309,10 +1314,12 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
                                                    ATOM_DEVICE_LCD1_SUPPORT,
                                                    DRM_MODE_CONNECTOR_LVDS,
                                                    &ddc_i2c,
-                                                   CONNECTOR_OBJECT_ID_LVDS);
+                                                   CONNECTOR_OBJECT_ID_LVDS,
+                                                   &hpd);
 
                        /* VGA - primary dac */
                        ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_VGA_DDC);
+                       hpd.hpd = RADEON_HPD_NONE;
                        radeon_add_legacy_encoder(dev,
                                                  radeon_get_encoder_id(dev,
                                                                        ATOM_DEVICE_CRT1_SUPPORT,
@@ -1322,10 +1329,12 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
                                                    ATOM_DEVICE_CRT1_SUPPORT,
                                                    DRM_MODE_CONNECTOR_VGA,
                                                    &ddc_i2c,
-                                                   CONNECTOR_OBJECT_ID_VGA);
+                                                   CONNECTOR_OBJECT_ID_VGA,
+                                                   &hpd);
                } else {
                        /* DVI-I - tv dac, int tmds */
                        ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_DVI_DDC);
+                       hpd.hpd = RADEON_HPD_1;
                        radeon_add_legacy_encoder(dev,
                                                  radeon_get_encoder_id(dev,
                                                                        ATOM_DEVICE_DFP1_SUPPORT,
@@ -1341,10 +1350,12 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
                                                    ATOM_DEVICE_CRT2_SUPPORT,
                                                    DRM_MODE_CONNECTOR_DVII,
                                                    &ddc_i2c,
-                                                   CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I);
+                                                   CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I,
+                                                   &hpd);
 
                        /* VGA - primary dac */
                        ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_VGA_DDC);
+                       hpd.hpd = RADEON_HPD_NONE;
                        radeon_add_legacy_encoder(dev,
                                                  radeon_get_encoder_id(dev,
                                                                        ATOM_DEVICE_CRT1_SUPPORT,
@@ -1354,11 +1365,14 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
                                                    ATOM_DEVICE_CRT1_SUPPORT,
                                                    DRM_MODE_CONNECTOR_VGA,
                                                    &ddc_i2c,
-                                                   CONNECTOR_OBJECT_ID_VGA);
+                                                   CONNECTOR_OBJECT_ID_VGA,
+                                                   &hpd);
                }
 
                if (rdev->family != CHIP_R100 && rdev->family != CHIP_R200) {
                        /* TV - tv dac */
+                       ddc_i2c.valid = false;
+                       hpd.hpd = RADEON_HPD_NONE;
                        radeon_add_legacy_encoder(dev,
                                                  radeon_get_encoder_id(dev,
                                                                        ATOM_DEVICE_TV1_SUPPORT,
@@ -1368,7 +1382,8 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
                                                    ATOM_DEVICE_TV1_SUPPORT,
                                                    DRM_MODE_CONNECTOR_SVIDEO,
                                                    &ddc_i2c,
-                                                   CONNECTOR_OBJECT_ID_SVIDEO);
+                                                   CONNECTOR_OBJECT_ID_SVIDEO,
+                                                   &hpd);
                }
                break;
        case CT_IBOOK:
@@ -1376,6 +1391,7 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
                         rdev->mode_info.connector_table);
                /* LVDS */
                ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_DVI_DDC);
+               hpd.hpd = RADEON_HPD_NONE;
                radeon_add_legacy_encoder(dev,
                                          radeon_get_encoder_id(dev,
                                                                ATOM_DEVICE_LCD1_SUPPORT,
@@ -1383,9 +1399,11 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
                                          ATOM_DEVICE_LCD1_SUPPORT);
                radeon_add_legacy_connector(dev, 0, ATOM_DEVICE_LCD1_SUPPORT,
                                            DRM_MODE_CONNECTOR_LVDS, &ddc_i2c,
-                                           CONNECTOR_OBJECT_ID_LVDS);
+                                           CONNECTOR_OBJECT_ID_LVDS,
+                                           &hpd);
                /* VGA - TV DAC */
                ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_VGA_DDC);
+               hpd.hpd = RADEON_HPD_NONE;
                radeon_add_legacy_encoder(dev,
                                          radeon_get_encoder_id(dev,
                                                                ATOM_DEVICE_CRT2_SUPPORT,
@@ -1393,8 +1411,11 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
                                          ATOM_DEVICE_CRT2_SUPPORT);
                radeon_add_legacy_connector(dev, 1, ATOM_DEVICE_CRT2_SUPPORT,
                                            DRM_MODE_CONNECTOR_VGA, &ddc_i2c,
-                                           CONNECTOR_OBJECT_ID_VGA);
+                                           CONNECTOR_OBJECT_ID_VGA,
+                                           &hpd);
                /* TV - TV DAC */
+               ddc_i2c.valid = false;
+               hpd.hpd = RADEON_HPD_NONE;
                radeon_add_legacy_encoder(dev,
                                          radeon_get_encoder_id(dev,
                                                                ATOM_DEVICE_TV1_SUPPORT,
@@ -1403,13 +1424,15 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
                radeon_add_legacy_connector(dev, 2, ATOM_DEVICE_TV1_SUPPORT,
                                            DRM_MODE_CONNECTOR_SVIDEO,
                                            &ddc_i2c,
-                                           CONNECTOR_OBJECT_ID_SVIDEO);
+                                           CONNECTOR_OBJECT_ID_SVIDEO,
+                                           &hpd);
                break;
        case CT_POWERBOOK_EXTERNAL:
                DRM_INFO("Connector Table: %d (powerbook external tmds)\n",
                         rdev->mode_info.connector_table);
                /* LVDS */
                ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_DVI_DDC);
+               hpd.hpd = RADEON_HPD_NONE;
                radeon_add_legacy_encoder(dev,
                                          radeon_get_encoder_id(dev,
                                                                ATOM_DEVICE_LCD1_SUPPORT,
@@ -1417,9 +1440,11 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
                                          ATOM_DEVICE_LCD1_SUPPORT);
                radeon_add_legacy_connector(dev, 0, ATOM_DEVICE_LCD1_SUPPORT,
                                            DRM_MODE_CONNECTOR_LVDS, &ddc_i2c,
-                                           CONNECTOR_OBJECT_ID_LVDS);
+                                           CONNECTOR_OBJECT_ID_LVDS,
+                                           &hpd);
                /* DVI-I - primary dac, ext tmds */
                ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_VGA_DDC);
+               hpd.hpd = RADEON_HPD_2; /* ??? */
                radeon_add_legacy_encoder(dev,
                                          radeon_get_encoder_id(dev,
                                                                ATOM_DEVICE_DFP2_SUPPORT,
@@ -1435,8 +1460,11 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
                                            ATOM_DEVICE_DFP2_SUPPORT |
                                            ATOM_DEVICE_CRT1_SUPPORT,
                                            DRM_MODE_CONNECTOR_DVII, &ddc_i2c,
-                                           CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_I);
+                                           CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_I,
+                                           &hpd);
                /* TV - TV DAC */
+               ddc_i2c.valid = false;
+               hpd.hpd = RADEON_HPD_NONE;
                radeon_add_legacy_encoder(dev,
                                          radeon_get_encoder_id(dev,
                                                                ATOM_DEVICE_TV1_SUPPORT,
@@ -1445,13 +1473,15 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
                radeon_add_legacy_connector(dev, 2, ATOM_DEVICE_TV1_SUPPORT,
                                            DRM_MODE_CONNECTOR_SVIDEO,
                                            &ddc_i2c,
-                                           CONNECTOR_OBJECT_ID_SVIDEO);
+                                           CONNECTOR_OBJECT_ID_SVIDEO,
+                                           &hpd);
                break;
        case CT_POWERBOOK_INTERNAL:
                DRM_INFO("Connector Table: %d (powerbook internal tmds)\n",
                         rdev->mode_info.connector_table);
                /* LVDS */
                ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_DVI_DDC);
+               hpd.hpd = RADEON_HPD_NONE;
                radeon_add_legacy_encoder(dev,
                                          radeon_get_encoder_id(dev,
                                                                ATOM_DEVICE_LCD1_SUPPORT,
@@ -1459,9 +1489,11 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
                                          ATOM_DEVICE_LCD1_SUPPORT);
                radeon_add_legacy_connector(dev, 0, ATOM_DEVICE_LCD1_SUPPORT,
                                            DRM_MODE_CONNECTOR_LVDS, &ddc_i2c,
-                                           CONNECTOR_OBJECT_ID_LVDS);
+                                           CONNECTOR_OBJECT_ID_LVDS,
+                                           &hpd);
                /* DVI-I - primary dac, int tmds */
                ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_VGA_DDC);
+               hpd.hpd = RADEON_HPD_1; /* ??? */
                radeon_add_legacy_encoder(dev,
                                          radeon_get_encoder_id(dev,
                                                                ATOM_DEVICE_DFP1_SUPPORT,
@@ -1476,8 +1508,11 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
                                            ATOM_DEVICE_DFP1_SUPPORT |
                                            ATOM_DEVICE_CRT1_SUPPORT,
                                            DRM_MODE_CONNECTOR_DVII, &ddc_i2c,
-                                           CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I);
+                                           CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I,
+                                           &hpd);
                /* TV - TV DAC */
+               ddc_i2c.valid = false;
+               hpd.hpd = RADEON_HPD_NONE;
                radeon_add_legacy_encoder(dev,
                                          radeon_get_encoder_id(dev,
                                                                ATOM_DEVICE_TV1_SUPPORT,
@@ -1486,13 +1521,15 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
                radeon_add_legacy_connector(dev, 2, ATOM_DEVICE_TV1_SUPPORT,
                                            DRM_MODE_CONNECTOR_SVIDEO,
                                            &ddc_i2c,
-                                           CONNECTOR_OBJECT_ID_SVIDEO);
+                                           CONNECTOR_OBJECT_ID_SVIDEO,
+                                           &hpd);
                break;
        case CT_POWERBOOK_VGA:
                DRM_INFO("Connector Table: %d (powerbook vga)\n",
                         rdev->mode_info.connector_table);
                /* LVDS */
                ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_DVI_DDC);
+               hpd.hpd = RADEON_HPD_NONE;
                radeon_add_legacy_encoder(dev,
                                          radeon_get_encoder_id(dev,
                                                                ATOM_DEVICE_LCD1_SUPPORT,
@@ -1500,9 +1537,11 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
                                          ATOM_DEVICE_LCD1_SUPPORT);
                radeon_add_legacy_connector(dev, 0, ATOM_DEVICE_LCD1_SUPPORT,
                                            DRM_MODE_CONNECTOR_LVDS, &ddc_i2c,
-                                           CONNECTOR_OBJECT_ID_LVDS);
+                                           CONNECTOR_OBJECT_ID_LVDS,
+                                           &hpd);
                /* VGA - primary dac */
                ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_VGA_DDC);
+               hpd.hpd = RADEON_HPD_NONE;
                radeon_add_legacy_encoder(dev,
                                          radeon_get_encoder_id(dev,
                                                                ATOM_DEVICE_CRT1_SUPPORT,
@@ -1510,8 +1549,11 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
                                          ATOM_DEVICE_CRT1_SUPPORT);
                radeon_add_legacy_connector(dev, 1, ATOM_DEVICE_CRT1_SUPPORT,
                                            DRM_MODE_CONNECTOR_VGA, &ddc_i2c,
-                                           CONNECTOR_OBJECT_ID_VGA);
+                                           CONNECTOR_OBJECT_ID_VGA,
+                                           &hpd);
                /* TV - TV DAC */
+               ddc_i2c.valid = false;
+               hpd.hpd = RADEON_HPD_NONE;
                radeon_add_legacy_encoder(dev,
                                          radeon_get_encoder_id(dev,
                                                                ATOM_DEVICE_TV1_SUPPORT,
@@ -1520,13 +1562,15 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
                radeon_add_legacy_connector(dev, 2, ATOM_DEVICE_TV1_SUPPORT,
                                            DRM_MODE_CONNECTOR_SVIDEO,
                                            &ddc_i2c,
-                                           CONNECTOR_OBJECT_ID_SVIDEO);
+                                           CONNECTOR_OBJECT_ID_SVIDEO,
+                                           &hpd);
                break;
        case CT_MINI_EXTERNAL:
                DRM_INFO("Connector Table: %d (mini external tmds)\n",
                         rdev->mode_info.connector_table);
                /* DVI-I - tv dac, ext tmds */
                ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_CRT2_DDC);
+               hpd.hpd = RADEON_HPD_2; /* ??? */
                radeon_add_legacy_encoder(dev,
                                          radeon_get_encoder_id(dev,
                                                                ATOM_DEVICE_DFP2_SUPPORT,
@@ -1542,8 +1586,11 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
                                            ATOM_DEVICE_DFP2_SUPPORT |
                                            ATOM_DEVICE_CRT2_SUPPORT,
                                            DRM_MODE_CONNECTOR_DVII, &ddc_i2c,
-                                           CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I);
+                                           CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I,
+                                           &hpd);
                /* TV - TV DAC */
+               ddc_i2c.valid = false;
+               hpd.hpd = RADEON_HPD_NONE;
                radeon_add_legacy_encoder(dev,
                                          radeon_get_encoder_id(dev,
                                                                ATOM_DEVICE_TV1_SUPPORT,
@@ -1552,13 +1599,15 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
                radeon_add_legacy_connector(dev, 1, ATOM_DEVICE_TV1_SUPPORT,
                                            DRM_MODE_CONNECTOR_SVIDEO,
                                            &ddc_i2c,
-                                           CONNECTOR_OBJECT_ID_SVIDEO);
+                                           CONNECTOR_OBJECT_ID_SVIDEO,
+                                           &hpd);
                break;
        case CT_MINI_INTERNAL:
                DRM_INFO("Connector Table: %d (mini internal tmds)\n",
                         rdev->mode_info.connector_table);
                /* DVI-I - tv dac, int tmds */
                ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_CRT2_DDC);
+               hpd.hpd = RADEON_HPD_1; /* ??? */
                radeon_add_legacy_encoder(dev,
                                          radeon_get_encoder_id(dev,
                                                                ATOM_DEVICE_DFP1_SUPPORT,
@@ -1573,8 +1622,11 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
                                            ATOM_DEVICE_DFP1_SUPPORT |
                                            ATOM_DEVICE_CRT2_SUPPORT,
                                            DRM_MODE_CONNECTOR_DVII, &ddc_i2c,
-                                           CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I);
+                                           CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I,
+                                           &hpd);
                /* TV - TV DAC */
+               ddc_i2c.valid = false;
+               hpd.hpd = RADEON_HPD_NONE;
                radeon_add_legacy_encoder(dev,
                                          radeon_get_encoder_id(dev,
                                                                ATOM_DEVICE_TV1_SUPPORT,
@@ -1583,13 +1635,15 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
                radeon_add_legacy_connector(dev, 1, ATOM_DEVICE_TV1_SUPPORT,
                                            DRM_MODE_CONNECTOR_SVIDEO,
                                            &ddc_i2c,
-                                           CONNECTOR_OBJECT_ID_SVIDEO);
+                                           CONNECTOR_OBJECT_ID_SVIDEO,
+                                           &hpd);
                break;
        case CT_IMAC_G5_ISIGHT:
                DRM_INFO("Connector Table: %d (imac g5 isight)\n",
                         rdev->mode_info.connector_table);
                /* DVI-D - int tmds */
                ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_MONID);
+               hpd.hpd = RADEON_HPD_1; /* ??? */
                radeon_add_legacy_encoder(dev,
                                          radeon_get_encoder_id(dev,
                                                                ATOM_DEVICE_DFP1_SUPPORT,
@@ -1597,9 +1651,11 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
                                          ATOM_DEVICE_DFP1_SUPPORT);
                radeon_add_legacy_connector(dev, 0, ATOM_DEVICE_DFP1_SUPPORT,
                                            DRM_MODE_CONNECTOR_DVID, &ddc_i2c,
-                                           CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D);
+                                           CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D,
+                                           &hpd);
                /* VGA - tv dac */
                ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_DVI_DDC);
+               hpd.hpd = RADEON_HPD_NONE;
                radeon_add_legacy_encoder(dev,
                                          radeon_get_encoder_id(dev,
                                                                ATOM_DEVICE_CRT2_SUPPORT,
@@ -1607,8 +1663,11 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
                                          ATOM_DEVICE_CRT2_SUPPORT);
                radeon_add_legacy_connector(dev, 1, ATOM_DEVICE_CRT2_SUPPORT,
                                            DRM_MODE_CONNECTOR_VGA, &ddc_i2c,
-                                           CONNECTOR_OBJECT_ID_VGA);
+                                           CONNECTOR_OBJECT_ID_VGA,
+                                           &hpd);
                /* TV - TV DAC */
+               ddc_i2c.valid = false;
+               hpd.hpd = RADEON_HPD_NONE;
                radeon_add_legacy_encoder(dev,
                                          radeon_get_encoder_id(dev,
                                                                ATOM_DEVICE_TV1_SUPPORT,
@@ -1617,13 +1676,15 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
                radeon_add_legacy_connector(dev, 2, ATOM_DEVICE_TV1_SUPPORT,
                                            DRM_MODE_CONNECTOR_SVIDEO,
                                            &ddc_i2c,
-                                           CONNECTOR_OBJECT_ID_SVIDEO);
+                                           CONNECTOR_OBJECT_ID_SVIDEO,
+                                           &hpd);
                break;
        case CT_EMAC:
                DRM_INFO("Connector Table: %d (emac)\n",
                         rdev->mode_info.connector_table);
                /* VGA - primary dac */
                ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_VGA_DDC);
+               hpd.hpd = RADEON_HPD_NONE;
                radeon_add_legacy_encoder(dev,
                                          radeon_get_encoder_id(dev,
                                                                ATOM_DEVICE_CRT1_SUPPORT,
@@ -1631,9 +1692,11 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
                                          ATOM_DEVICE_CRT1_SUPPORT);
                radeon_add_legacy_connector(dev, 0, ATOM_DEVICE_CRT1_SUPPORT,
                                            DRM_MODE_CONNECTOR_VGA, &ddc_i2c,
-                                           CONNECTOR_OBJECT_ID_VGA);
+                                           CONNECTOR_OBJECT_ID_VGA,
+                                           &hpd);
                /* VGA - tv dac */
                ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_CRT2_DDC);
+               hpd.hpd = RADEON_HPD_NONE;
                radeon_add_legacy_encoder(dev,
                                          radeon_get_encoder_id(dev,
                                                                ATOM_DEVICE_CRT2_SUPPORT,
@@ -1641,8 +1704,11 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
                                          ATOM_DEVICE_CRT2_SUPPORT);
                radeon_add_legacy_connector(dev, 1, ATOM_DEVICE_CRT2_SUPPORT,
                                            DRM_MODE_CONNECTOR_VGA, &ddc_i2c,
-                                           CONNECTOR_OBJECT_ID_VGA);
+                                           CONNECTOR_OBJECT_ID_VGA,
+                                           &hpd);
                /* TV - TV DAC */
+               ddc_i2c.valid = false;
+               hpd.hpd = RADEON_HPD_NONE;
                radeon_add_legacy_encoder(dev,
                                          radeon_get_encoder_id(dev,
                                                                ATOM_DEVICE_TV1_SUPPORT,
@@ -1651,7 +1717,8 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
                radeon_add_legacy_connector(dev, 2, ATOM_DEVICE_TV1_SUPPORT,
                                            DRM_MODE_CONNECTOR_SVIDEO,
                                            &ddc_i2c,
-                                           CONNECTOR_OBJECT_ID_SVIDEO);
+                                           CONNECTOR_OBJECT_ID_SVIDEO,
+                                           &hpd);
                break;
        default:
                DRM_INFO("Connector table: %d (invalid)\n",
@@ -1668,7 +1735,8 @@ static bool radeon_apply_legacy_quirks(struct drm_device *dev,
                                       int bios_index,
                                       enum radeon_combios_connector
                                       *legacy_connector,
-                                      struct radeon_i2c_bus_rec *ddc_i2c)
+                                      struct radeon_i2c_bus_rec *ddc_i2c,
+                                      struct radeon_hpd *hpd)
 {
        struct radeon_device *rdev = dev->dev_private;
 
@@ -1792,6 +1860,7 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev)
        enum radeon_combios_connector connector;
        int i = 0;
        struct radeon_i2c_bus_rec ddc_i2c;
+       struct radeon_hpd hpd;
 
        if (rdev->bios == NULL)
                return false;
@@ -1830,8 +1899,22 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev)
                                break;
                        }
 
+                       switch (connector) {
+                       case CONNECTOR_PROPRIETARY_LEGACY:
+                       case CONNECTOR_DVI_I_LEGACY:
+                       case CONNECTOR_DVI_D_LEGACY:
+                               if ((tmp >> 4) & 0x1)
+                                       hpd.hpd = RADEON_HPD_2;
+                               else
+                                       hpd.hpd = RADEON_HPD_1;
+                               break;
+                       default:
+                               hpd.hpd = RADEON_HPD_NONE;
+                               break;
+                       }
+
                        if (!radeon_apply_legacy_quirks(dev, i, &connector,
-                                                      &ddc_i2c))
+                                                       &ddc_i2c, &hpd))
                                continue;
 
                        switch (connector) {
@@ -1848,7 +1931,8 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev)
                                                            legacy_connector_convert
                                                            [connector],
                                                            &ddc_i2c,
-                                                           CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D);
+                                                           CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D,
+                                                           &hpd);
                                break;
                        case CONNECTOR_CRT_LEGACY:
                                if (tmp & 0x1) {
@@ -1874,7 +1958,8 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev)
                                                            legacy_connector_convert
                                                            [connector],
                                                            &ddc_i2c,
-                                                           CONNECTOR_OBJECT_ID_VGA);
+                                                           CONNECTOR_OBJECT_ID_VGA,
+                                                           &hpd);
                                break;
                        case CONNECTOR_DVI_I_LEGACY:
                                devices = 0;
@@ -1920,7 +2005,8 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev)
                                                            legacy_connector_convert
                                                            [connector],
                                                            &ddc_i2c,
-                                                           connector_object_id);
+                                                           connector_object_id,
+                                                           &hpd);
                                break;
                        case CONNECTOR_DVI_D_LEGACY:
                                if ((tmp >> 4) & 0x1) {
@@ -1938,7 +2024,8 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev)
                                                            legacy_connector_convert
                                                            [connector],
                                                            &ddc_i2c,
-                                                           connector_object_id);
+                                                           connector_object_id,
+                                                           &hpd);
                                break;
                        case CONNECTOR_CTV_LEGACY:
                        case CONNECTOR_STV_LEGACY:
@@ -1953,7 +2040,8 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev)
                                                            legacy_connector_convert
                                                            [connector],
                                                            &ddc_i2c,
-                                                           CONNECTOR_OBJECT_ID_SVIDEO);
+                                                           CONNECTOR_OBJECT_ID_SVIDEO,
+                                                           &hpd);
                                break;
                        default:
                                DRM_ERROR("Unknown connector type: %d\n",
@@ -1980,13 +2068,15 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev)
                                                  ATOM_DEVICE_DFP1_SUPPORT);
 
                        ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_DVI_DDC);
+                       hpd.hpd = RADEON_HPD_NONE;
                        radeon_add_legacy_connector(dev,
                                                    0,
                                                    ATOM_DEVICE_CRT1_SUPPORT |
                                                    ATOM_DEVICE_DFP1_SUPPORT,
                                                    DRM_MODE_CONNECTOR_DVII,
                                                    &ddc_i2c,
-                                                   CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I);
+                                                   CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I,
+                                                   &hpd);
                } else {
                        uint16_t crt_info =
                                combios_get_table_offset(dev, COMBIOS_CRT_INFO_TABLE);
@@ -1998,12 +2088,14 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev)
                                                                                1),
                                                          ATOM_DEVICE_CRT1_SUPPORT);
                                ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_VGA_DDC);
+                               hpd.hpd = RADEON_HPD_NONE;
                                radeon_add_legacy_connector(dev,
                                                            0,
                                                            ATOM_DEVICE_CRT1_SUPPORT,
                                                            DRM_MODE_CONNECTOR_VGA,
                                                            &ddc_i2c,
-                                                           CONNECTOR_OBJECT_ID_VGA);
+                                                           CONNECTOR_OBJECT_ID_VGA,
+                                                           &hpd);
                        } else {
                                DRM_DEBUG("No connector info found\n");
                                return false;
@@ -2098,12 +2190,14 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev)
                        } else
                                ddc_i2c.valid = false;
 
+                       hpd.hpd = RADEON_HPD_NONE;
                        radeon_add_legacy_connector(dev,
                                                    5,
                                                    ATOM_DEVICE_LCD1_SUPPORT,
                                                    DRM_MODE_CONNECTOR_LVDS,
                                                    &ddc_i2c,
-                                                   CONNECTOR_OBJECT_ID_LVDS);
+                                                   CONNECTOR_OBJECT_ID_LVDS,
+                                                   &hpd);
                }
        }
 
@@ -2114,6 +2208,7 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev)
                if (tv_info) {
                        if (RBIOS8(tv_info + 6) == 'T') {
                                if (radeon_apply_legacy_tv_quirks(dev)) {
+                                       hpd.hpd = RADEON_HPD_NONE;
                                        radeon_add_legacy_encoder(dev,
                                                                  radeon_get_encoder_id
                                                                  (dev,
@@ -2124,7 +2219,8 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev)
                                                                    ATOM_DEVICE_TV1_SUPPORT,
                                                                    DRM_MODE_CONNECTOR_SVIDEO,
                                                                    &ddc_i2c,
-                                                                   CONNECTOR_OBJECT_ID_SVIDEO);
+                                                                   CONNECTOR_OBJECT_ID_SVIDEO,
+                                                                   &hpd);
                                }
                        }
                }
index 5638472..7328d15 100644 (file)
@@ -989,7 +989,8 @@ radeon_add_atom_connector(struct drm_device *dev,
                          struct radeon_i2c_bus_rec *i2c_bus,
                          bool linkb,
                          uint32_t igp_lane_info,
-                         uint16_t connector_object_id)
+                         uint16_t connector_object_id,
+                         struct radeon_hpd *hpd)
 {
        struct radeon_device *rdev = dev->dev_private;
        struct drm_connector *connector;
@@ -1029,6 +1030,7 @@ radeon_add_atom_connector(struct drm_device *dev,
        radeon_connector->devices = supported_device;
        radeon_connector->shared_ddc = shared_ddc;
        radeon_connector->connector_object_id = connector_object_id;
+       radeon_connector->hpd = *hpd;
        switch (connector_type) {
        case DRM_MODE_CONNECTOR_VGA:
                drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type);
@@ -1186,7 +1188,8 @@ radeon_add_legacy_connector(struct drm_device *dev,
                            uint32_t supported_device,
                            int connector_type,
                            struct radeon_i2c_bus_rec *i2c_bus,
-                           uint16_t connector_object_id)
+                           uint16_t connector_object_id,
+                           struct radeon_hpd *hpd)
 {
        struct radeon_device *rdev = dev->dev_private;
        struct drm_connector *connector;
@@ -1216,6 +1219,7 @@ radeon_add_legacy_connector(struct drm_device *dev,
        radeon_connector->connector_id = connector_id;
        radeon_connector->devices = supported_device;
        radeon_connector->connector_object_id = connector_object_id;
+       radeon_connector->hpd = *hpd;
        switch (connector_type) {
        case DRM_MODE_CONNECTOR_VGA:
                drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type);
index 62c929e..d4f4fb1 100644 (file)
@@ -250,6 +250,16 @@ static const char *connector_names[13] = {
        "HDMI-B",
 };
 
+static const char *hpd_names[7] = {
+       "NONE",
+       "HPD1",
+       "HPD2",
+       "HPD3",
+       "HPD4",
+       "HPD5",
+       "HPD6",
+};
+
 static void radeon_print_display_setup(struct drm_device *dev)
 {
        struct drm_connector *connector;
@@ -264,6 +274,8 @@ static void radeon_print_display_setup(struct drm_device *dev)
                radeon_connector = to_radeon_connector(connector);
                DRM_INFO("Connector %d:\n", i);
                DRM_INFO("  %s\n", connector_names[connector->connector_type]);
+               if (radeon_connector->hpd.hpd != RADEON_HPD_NONE)
+                       DRM_INFO("  %s\n", hpd_names[radeon_connector->hpd.hpd]);
                if (radeon_connector->ddc_bus)
                        DRM_INFO("  DDC: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n",
                                 radeon_connector->ddc_bus->rec.mask_clk_reg,
index a263362..61b9034 100644 (file)
@@ -347,6 +347,29 @@ struct radeon_connector_atom_dig {
        int dp_lane_count;
 };
 
+struct radeon_gpio_rec {
+       bool valid;
+       u8 id;
+       u32 reg;
+       u32 mask;
+};
+
+enum radeon_hpd_id {
+       RADEON_HPD_NONE = 0,
+       RADEON_HPD_1,
+       RADEON_HPD_2,
+       RADEON_HPD_3,
+       RADEON_HPD_4,
+       RADEON_HPD_5,
+       RADEON_HPD_6,
+};
+
+struct radeon_hpd {
+       enum radeon_hpd_id hpd;
+       u8 plugged_state;
+       struct radeon_gpio_rec gpio;
+};
+
 struct radeon_connector {
        struct drm_connector base;
        uint32_t connector_id;
@@ -361,6 +384,7 @@ struct radeon_connector {
        void *con_priv;
        bool dac_load_detect;
        uint16_t connector_object_id;
+       struct radeon_hpd hpd;
 };
 
 struct radeon_framebuffer {