drm/radeon/kms: i2c reorg
authorAlex Deucher <alexdeucher@gmail.com>
Mon, 23 Nov 2009 22:39:28 +0000 (17:39 -0500)
committerDave Airlie <airlied@redhat.com>
Tue, 8 Dec 2009 00:22:41 +0000 (10:22 +1000)
- keep the atom i2c id in the i2c rec
- fix gpio regs for GPIO and MDGPIO on pre-avivo chips
- track whether the i2c line is hw capable
- track whether the i2c line uses the multimedia i2c block

Signed-off-by: Alex Deucher <alexdeucher@gmail.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
drivers/gpu/drm/radeon/atombios_dp.c
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_i2c.c
drivers/gpu/drm/radeon/radeon_mode.h
drivers/gpu/drm/radeon/radeon_reg.h

index d1c144b..fc5a2df 100644 (file)
@@ -52,7 +52,7 @@ bool radeon_process_aux_ch(struct radeon_i2c_chan *chan, u8 *req_bytes,
        args.lpAuxRequest = 0;
        args.lpDataOut = 16;
        args.ucDataOutLen = 0;
-       args.ucChannelID = chan->i2c_id;
+       args.ucChannelID = chan->rec.i2c_id;
        args.ucDelay = delay / 10;
 
        atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
@@ -60,7 +60,7 @@ bool radeon_process_aux_ch(struct radeon_i2c_chan *chan, u8 *req_bytes,
        if (args.ucReplyStatus) {
                DRM_ERROR("failed to get auxch %02x%02x %02x %02x 0x%02x %02x\n",
                          req_bytes[1], req_bytes[0], req_bytes[2], req_bytes[3],
-                         chan->i2c_id, args.ucReplyStatus);
+                         chan->rec.i2c_id, args.ucReplyStatus);
                return false;
        }
 
@@ -102,7 +102,7 @@ int radeon_dp_getsinktype(struct radeon_connector *radeon_connector)
        struct radeon_device *rdev = dev->dev_private;
 
        return radeon_dp_encoder_service(rdev, ATOM_DP_ACTION_GET_SINK_TYPE, 0,
-                                        radeon_dig_connector->uc_i2c_id, 0);
+                                        radeon_dig_connector->dp_i2c_bus->rec.i2c_id, 0);
 }
 
 union dig_transmitter_control {
index de05ac9..87bf6b9 100644 (file)
@@ -47,7 +47,7 @@ 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, uint8_t uc_i2c_id);
+                         uint16_t connector_object_id);
 
 /* from radeon_legacy_encoder.c */
 extern void
@@ -65,7 +65,7 @@ static inline struct radeon_i2c_bus_rec radeon_lookup_gpio(struct drm_device *de
 {
        struct radeon_device *rdev = dev->dev_private;
        struct atom_context *ctx = rdev->mode_info.atom_context;
-       ATOM_GPIO_I2C_ASSIGMENT gpio;
+       ATOM_GPIO_I2C_ASSIGMENT *gpio;
        struct radeon_i2c_bus_rec i2c;
        int index = GetIndexIntoMasterTable(DATA, GPIO_I2C_Info);
        struct _ATOM_GPIO_I2C_INFO *i2c_info;
@@ -78,24 +78,37 @@ static inline struct radeon_i2c_bus_rec radeon_lookup_gpio(struct drm_device *de
 
        i2c_info = (struct _ATOM_GPIO_I2C_INFO *)(ctx->bios + data_offset);
 
-       gpio = i2c_info->asGPIO_Info[id];
-
-       i2c.mask_clk_reg = le16_to_cpu(gpio.usClkMaskRegisterIndex) * 4;
-       i2c.mask_data_reg = le16_to_cpu(gpio.usDataMaskRegisterIndex) * 4;
-       i2c.en_clk_reg = le16_to_cpu(gpio.usClkEnRegisterIndex) * 4;
-       i2c.en_data_reg = le16_to_cpu(gpio.usDataEnRegisterIndex) * 4;
-       i2c.y_clk_reg = le16_to_cpu(gpio.usClkY_RegisterIndex) * 4;
-       i2c.y_data_reg = le16_to_cpu(gpio.usDataY_RegisterIndex) * 4;
-       i2c.a_clk_reg = le16_to_cpu(gpio.usClkA_RegisterIndex) * 4;
-       i2c.a_data_reg = le16_to_cpu(gpio.usDataA_RegisterIndex) * 4;
-       i2c.mask_clk_mask = (1 << gpio.ucClkMaskShift);
-       i2c.mask_data_mask = (1 << gpio.ucDataMaskShift);
-       i2c.en_clk_mask = (1 << gpio.ucClkEnShift);
-       i2c.en_data_mask = (1 << gpio.ucDataEnShift);
-       i2c.y_clk_mask = (1 << gpio.ucClkY_Shift);
-       i2c.y_data_mask = (1 << gpio.ucDataY_Shift);
-       i2c.a_clk_mask = (1 << gpio.ucClkA_Shift);
-       i2c.a_data_mask = (1 << gpio.ucDataA_Shift);
+       gpio = &i2c_info->asGPIO_Info[id];
+
+       i2c.mask_clk_reg = le16_to_cpu(gpio->usClkMaskRegisterIndex) * 4;
+       i2c.mask_data_reg = le16_to_cpu(gpio->usDataMaskRegisterIndex) * 4;
+       i2c.en_clk_reg = le16_to_cpu(gpio->usClkEnRegisterIndex) * 4;
+       i2c.en_data_reg = le16_to_cpu(gpio->usDataEnRegisterIndex) * 4;
+       i2c.y_clk_reg = le16_to_cpu(gpio->usClkY_RegisterIndex) * 4;
+       i2c.y_data_reg = le16_to_cpu(gpio->usDataY_RegisterIndex) * 4;
+       i2c.a_clk_reg = le16_to_cpu(gpio->usClkA_RegisterIndex) * 4;
+       i2c.a_data_reg = le16_to_cpu(gpio->usDataA_RegisterIndex) * 4;
+       i2c.mask_clk_mask = (1 << gpio->ucClkMaskShift);
+       i2c.mask_data_mask = (1 << gpio->ucDataMaskShift);
+       i2c.en_clk_mask = (1 << gpio->ucClkEnShift);
+       i2c.en_data_mask = (1 << gpio->ucDataEnShift);
+       i2c.y_clk_mask = (1 << gpio->ucClkY_Shift);
+       i2c.y_data_mask = (1 << gpio->ucDataY_Shift);
+       i2c.a_clk_mask = (1 << gpio->ucClkA_Shift);
+       i2c.a_data_mask = (1 << gpio->ucDataA_Shift);
+
+       if (gpio->sucI2cId.sbfAccess.bfHW_Capable)
+               i2c.hw_capable = true;
+       else
+               i2c.hw_capable = false;
+
+       if (gpio->sucI2cId.ucAccess == 0xa0)
+               i2c.mm_i2c = true;
+       else
+               i2c.mm_i2c = false;
+
+       i2c.i2c_id = gpio->sucI2cId.ucAccess;
+
        i2c.valid = true;
 
        return i2c;
@@ -276,7 +289,6 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev)
        uint16_t igp_lane_info, conn_id, connector_object_id;
        bool linkb;
        struct radeon_i2c_bus_rec ddc_bus;
-       ATOM_I2C_ID_CONFIG_ACCESS i2c_id;
        atom_parse_data_header(ctx, index, &size, &frev, &crev, &data_offset);
 
        if (data_offset == 0)
@@ -302,7 +314,6 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev)
                path = (ATOM_DISPLAY_OBJECT_PATH *) addr;
                path_size += le16_to_cpu(path->usSize);
                linkb = false;
-               i2c_id.ucAccess = 0;
                if (device_support & le16_to_cpu(path->usDeviceTag)) {
                        uint8_t con_obj_id, con_obj_num, con_obj_type;
 
@@ -420,7 +431,7 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev)
                                                                 asObjects[j].
                                                                 usRecordOffset));
                                                ATOM_I2C_RECORD *i2c_record;
-                                               
+
                                                while (record->ucRecordType > 0
                                                       && record->
                                                       ucRecordType <=
@@ -431,7 +442,6 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev)
                                                                i2c_record =
                                                                    (ATOM_I2C_RECORD
                                                                     *) record;
-                                                               i2c_id.sbfAccess = i2c_record->sucI2cId;
                                                                line_mux =
                                                                    i2c_record->
                                                                    sucI2cId.
@@ -474,7 +484,7 @@ 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, i2c_id.ucAccess);
+                                                 connector_object_id);
 
                }
        }
@@ -693,7 +703,7 @@ bool radeon_get_atom_connector_info_from_supported_devices_table(struct
                                                  connector_type,
                                                  &bios_connectors[i].ddc_bus,
                                                  false, 0,
-                                                 connector_object_id, 0);
+                                                 connector_object_id);
                }
        }
 
index 14d3555..b6761cd 100644 (file)
@@ -442,29 +442,39 @@ static uint16_t combios_get_table_offset(struct drm_device *dev,
 
 }
 
-struct radeon_i2c_bus_rec combios_setup_i2c_bus(int ddc_line)
+static struct radeon_i2c_bus_rec combios_setup_i2c_bus(struct radeon_device *rdev,
+                                                      int ddc_line)
 {
        struct radeon_i2c_bus_rec i2c;
 
-       i2c.mask_clk_mask = RADEON_GPIO_EN_1;
-       i2c.mask_data_mask = RADEON_GPIO_EN_0;
-       i2c.a_clk_mask = RADEON_GPIO_A_1;
-       i2c.a_data_mask = RADEON_GPIO_A_0;
-       i2c.en_clk_mask = RADEON_GPIO_EN_1;
-       i2c.en_data_mask = RADEON_GPIO_EN_0;
-       i2c.y_clk_mask = RADEON_GPIO_Y_1;
-       i2c.y_data_mask = RADEON_GPIO_Y_0;
-       if ((ddc_line == RADEON_LCD_GPIO_MASK) ||
-           (ddc_line == RADEON_MDGPIO_EN_REG)) {
-               i2c.mask_clk_reg = ddc_line;
-               i2c.mask_data_reg = ddc_line;
-               i2c.a_clk_reg = ddc_line;
-               i2c.a_data_reg = ddc_line;
-               i2c.en_clk_reg = ddc_line;
-               i2c.en_data_reg = ddc_line;
-               i2c.y_clk_reg = ddc_line + 4;
-               i2c.y_data_reg = ddc_line + 4;
+       if (ddc_line == RADEON_GPIOPAD_MASK) {
+               i2c.mask_clk_reg = RADEON_GPIOPAD_MASK;
+               i2c.mask_data_reg = RADEON_GPIOPAD_MASK;
+               i2c.a_clk_reg = RADEON_GPIOPAD_A;
+               i2c.a_data_reg = RADEON_GPIOPAD_A;
+               i2c.en_clk_reg = RADEON_GPIOPAD_EN;
+               i2c.en_data_reg = RADEON_GPIOPAD_EN;
+               i2c.y_clk_reg = RADEON_GPIOPAD_Y;
+               i2c.y_data_reg = RADEON_GPIOPAD_Y;
+       } else if (ddc_line == RADEON_MDGPIO_MASK) {
+               i2c.mask_clk_reg = RADEON_MDGPIO_MASK;
+               i2c.mask_data_reg = RADEON_MDGPIO_MASK;
+               i2c.a_clk_reg = RADEON_MDGPIO_A;
+               i2c.a_data_reg = RADEON_MDGPIO_A;
+               i2c.en_clk_reg = RADEON_MDGPIO_EN;
+               i2c.en_data_reg = RADEON_MDGPIO_EN;
+               i2c.y_clk_reg = RADEON_MDGPIO_Y;
+               i2c.y_data_reg = RADEON_MDGPIO_Y;
        } else {
+               i2c.mask_clk_mask = RADEON_GPIO_EN_1;
+               i2c.mask_data_mask = RADEON_GPIO_EN_0;
+               i2c.a_clk_mask = RADEON_GPIO_A_1;
+               i2c.a_data_mask = RADEON_GPIO_A_0;
+               i2c.en_clk_mask = RADEON_GPIO_EN_1;
+               i2c.en_data_mask = RADEON_GPIO_EN_0;
+               i2c.y_clk_mask = RADEON_GPIO_Y_1;
+               i2c.y_data_mask = RADEON_GPIO_Y_0;
+
                i2c.mask_clk_reg = ddc_line;
                i2c.mask_data_reg = ddc_line;
                i2c.a_clk_reg = ddc_line;
@@ -475,6 +485,28 @@ struct radeon_i2c_bus_rec combios_setup_i2c_bus(int ddc_line)
                i2c.y_data_reg = ddc_line;
        }
 
+       if (rdev->family < CHIP_R200)
+               i2c.hw_capable = false;
+       else {
+               switch (ddc_line) {
+               case RADEON_GPIO_VGA_DDC:
+               case RADEON_GPIO_DVI_DDC:
+                       i2c.hw_capable = true;
+                       break;
+               case RADEON_GPIO_MONID:
+                       /* hw i2c on RADEON_GPIO_MONID doesn't seem to work
+                        * reliably on some pre-r4xx hardware; not sure why.
+                        */
+                       i2c.hw_capable = false;
+                       break;
+               default:
+                       i2c.hw_capable = false;
+                       break;
+               }
+       }
+       i2c.mm_i2c = false;
+       i2c.i2c_id = 0;
+
        if (ddc_line)
                i2c.valid = true;
        else
@@ -1077,7 +1109,7 @@ bool radeon_legacy_get_ext_tmds_info_from_table(struct radeon_encoder *encoder,
        struct radeon_i2c_bus_rec i2c_bus;
 
        /* default for macs */
-       i2c_bus = combios_setup_i2c_bus(RADEON_GPIO_MONID);
+       i2c_bus = combios_setup_i2c_bus(rdev, RADEON_GPIO_MONID);
        tmds->i2c_bus = radeon_i2c_create(dev, &i2c_bus, "DVO");
 
        /* XXX some macs have duallink chips */
@@ -1153,23 +1185,23 @@ bool radeon_legacy_get_ext_tmds_info_from_combios(struct radeon_encoder *encoder
                        gpio = RBIOS8(offset + 4 + 3);
                        switch (gpio) {
                        case DDC_MONID:
-                               i2c_bus = combios_setup_i2c_bus(RADEON_GPIO_MONID);
+                               i2c_bus = combios_setup_i2c_bus(rdev, RADEON_GPIO_MONID);
                                tmds->i2c_bus = radeon_i2c_create(dev, &i2c_bus, "DVO");
                                break;
                        case DDC_DVI:
-                               i2c_bus = combios_setup_i2c_bus(RADEON_GPIO_DVI_DDC);
+                               i2c_bus = combios_setup_i2c_bus(rdev, RADEON_GPIO_DVI_DDC);
                                tmds->i2c_bus = radeon_i2c_create(dev, &i2c_bus, "DVO");
                                break;
                        case DDC_VGA:
-                               i2c_bus = combios_setup_i2c_bus(RADEON_GPIO_VGA_DDC);
+                               i2c_bus = combios_setup_i2c_bus(rdev, RADEON_GPIO_VGA_DDC);
                                tmds->i2c_bus = radeon_i2c_create(dev, &i2c_bus, "DVO");
                                break;
                        case DDC_CRT2:
                                /* R3xx+ chips don't have GPIO_CRT2_DDC gpio pad */
                                if (rdev->family >= CHIP_R300)
-                                       i2c_bus = combios_setup_i2c_bus(RADEON_GPIO_MONID);
+                                       i2c_bus = combios_setup_i2c_bus(rdev, RADEON_GPIO_MONID);
                                else
-                                       i2c_bus = combios_setup_i2c_bus(RADEON_GPIO_CRT2_DDC);
+                                       i2c_bus = combios_setup_i2c_bus(rdev, RADEON_GPIO_CRT2_DDC);
                                tmds->i2c_bus = radeon_i2c_create(dev, &i2c_bus, "DVO");
                                break;
                        case DDC_LCD: /* MM i2c */
@@ -1254,7 +1286,7 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
                /* these are the most common settings */
                if (rdev->flags & RADEON_SINGLE_CRTC) {
                        /* VGA - primary dac */
-                       ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_VGA_DDC);
+                       ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_VGA_DDC);
                        radeon_add_legacy_encoder(dev,
                                                  radeon_get_encoder_id(dev,
                                                                        ATOM_DEVICE_CRT1_SUPPORT,
@@ -1267,7 +1299,7 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
                                                    CONNECTOR_OBJECT_ID_VGA);
                } else if (rdev->flags & RADEON_IS_MOBILITY) {
                        /* LVDS */
-                       ddc_i2c = combios_setup_i2c_bus(RADEON_LCD_GPIO_MASK);
+                       ddc_i2c = combios_setup_i2c_bus(rdev, 0);
                        radeon_add_legacy_encoder(dev,
                                                  radeon_get_encoder_id(dev,
                                                                        ATOM_DEVICE_LCD1_SUPPORT,
@@ -1280,7 +1312,7 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
                                                    CONNECTOR_OBJECT_ID_LVDS);
 
                        /* VGA - primary dac */
-                       ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_VGA_DDC);
+                       ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_VGA_DDC);
                        radeon_add_legacy_encoder(dev,
                                                  radeon_get_encoder_id(dev,
                                                                        ATOM_DEVICE_CRT1_SUPPORT,
@@ -1293,7 +1325,7 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
                                                    CONNECTOR_OBJECT_ID_VGA);
                } else {
                        /* DVI-I - tv dac, int tmds */
-                       ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_DVI_DDC);
+                       ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_DVI_DDC);
                        radeon_add_legacy_encoder(dev,
                                                  radeon_get_encoder_id(dev,
                                                                        ATOM_DEVICE_DFP1_SUPPORT,
@@ -1312,7 +1344,7 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
                                                    CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I);
 
                        /* VGA - primary dac */
-                       ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_VGA_DDC);
+                       ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_VGA_DDC);
                        radeon_add_legacy_encoder(dev,
                                                  radeon_get_encoder_id(dev,
                                                                        ATOM_DEVICE_CRT1_SUPPORT,
@@ -1343,7 +1375,7 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
                DRM_INFO("Connector Table: %d (ibook)\n",
                         rdev->mode_info.connector_table);
                /* LVDS */
-               ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_DVI_DDC);
+               ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_DVI_DDC);
                radeon_add_legacy_encoder(dev,
                                          radeon_get_encoder_id(dev,
                                                                ATOM_DEVICE_LCD1_SUPPORT,
@@ -1353,7 +1385,7 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
                                            DRM_MODE_CONNECTOR_LVDS, &ddc_i2c,
                                            CONNECTOR_OBJECT_ID_LVDS);
                /* VGA - TV DAC */
-               ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_VGA_DDC);
+               ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_VGA_DDC);
                radeon_add_legacy_encoder(dev,
                                          radeon_get_encoder_id(dev,
                                                                ATOM_DEVICE_CRT2_SUPPORT,
@@ -1377,7 +1409,7 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
                DRM_INFO("Connector Table: %d (powerbook external tmds)\n",
                         rdev->mode_info.connector_table);
                /* LVDS */
-               ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_DVI_DDC);
+               ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_DVI_DDC);
                radeon_add_legacy_encoder(dev,
                                          radeon_get_encoder_id(dev,
                                                                ATOM_DEVICE_LCD1_SUPPORT,
@@ -1387,7 +1419,7 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
                                            DRM_MODE_CONNECTOR_LVDS, &ddc_i2c,
                                            CONNECTOR_OBJECT_ID_LVDS);
                /* DVI-I - primary dac, ext tmds */
-               ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_VGA_DDC);
+               ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_VGA_DDC);
                radeon_add_legacy_encoder(dev,
                                          radeon_get_encoder_id(dev,
                                                                ATOM_DEVICE_DFP2_SUPPORT,
@@ -1419,7 +1451,7 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
                DRM_INFO("Connector Table: %d (powerbook internal tmds)\n",
                         rdev->mode_info.connector_table);
                /* LVDS */
-               ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_DVI_DDC);
+               ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_DVI_DDC);
                radeon_add_legacy_encoder(dev,
                                          radeon_get_encoder_id(dev,
                                                                ATOM_DEVICE_LCD1_SUPPORT,
@@ -1429,7 +1461,7 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
                                            DRM_MODE_CONNECTOR_LVDS, &ddc_i2c,
                                            CONNECTOR_OBJECT_ID_LVDS);
                /* DVI-I - primary dac, int tmds */
-               ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_VGA_DDC);
+               ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_VGA_DDC);
                radeon_add_legacy_encoder(dev,
                                          radeon_get_encoder_id(dev,
                                                                ATOM_DEVICE_DFP1_SUPPORT,
@@ -1460,7 +1492,7 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
                DRM_INFO("Connector Table: %d (powerbook vga)\n",
                         rdev->mode_info.connector_table);
                /* LVDS */
-               ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_DVI_DDC);
+               ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_DVI_DDC);
                radeon_add_legacy_encoder(dev,
                                          radeon_get_encoder_id(dev,
                                                                ATOM_DEVICE_LCD1_SUPPORT,
@@ -1470,7 +1502,7 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
                                            DRM_MODE_CONNECTOR_LVDS, &ddc_i2c,
                                            CONNECTOR_OBJECT_ID_LVDS);
                /* VGA - primary dac */
-               ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_VGA_DDC);
+               ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_VGA_DDC);
                radeon_add_legacy_encoder(dev,
                                          radeon_get_encoder_id(dev,
                                                                ATOM_DEVICE_CRT1_SUPPORT,
@@ -1494,7 +1526,7 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
                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(RADEON_GPIO_CRT2_DDC);
+               ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_CRT2_DDC);
                radeon_add_legacy_encoder(dev,
                                          radeon_get_encoder_id(dev,
                                                                ATOM_DEVICE_DFP2_SUPPORT,
@@ -1526,7 +1558,7 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
                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(RADEON_GPIO_CRT2_DDC);
+               ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_CRT2_DDC);
                radeon_add_legacy_encoder(dev,
                                          radeon_get_encoder_id(dev,
                                                                ATOM_DEVICE_DFP1_SUPPORT,
@@ -1557,7 +1589,7 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
                DRM_INFO("Connector Table: %d (imac g5 isight)\n",
                         rdev->mode_info.connector_table);
                /* DVI-D - int tmds */
-               ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_MONID);
+               ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_MONID);
                radeon_add_legacy_encoder(dev,
                                          radeon_get_encoder_id(dev,
                                                                ATOM_DEVICE_DFP1_SUPPORT,
@@ -1567,7 +1599,7 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
                                            DRM_MODE_CONNECTOR_DVID, &ddc_i2c,
                                            CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D);
                /* VGA - tv dac */
-               ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_DVI_DDC);
+               ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_DVI_DDC);
                radeon_add_legacy_encoder(dev,
                                          radeon_get_encoder_id(dev,
                                                                ATOM_DEVICE_CRT2_SUPPORT,
@@ -1591,7 +1623,7 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
                DRM_INFO("Connector Table: %d (emac)\n",
                         rdev->mode_info.connector_table);
                /* VGA - primary dac */
-               ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_VGA_DDC);
+               ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_VGA_DDC);
                radeon_add_legacy_encoder(dev,
                                          radeon_get_encoder_id(dev,
                                                                ATOM_DEVICE_CRT1_SUPPORT,
@@ -1601,7 +1633,7 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
                                            DRM_MODE_CONNECTOR_VGA, &ddc_i2c,
                                            CONNECTOR_OBJECT_ID_VGA);
                /* VGA - tv dac */
-               ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_CRT2_DDC);
+               ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_CRT2_DDC);
                radeon_add_legacy_encoder(dev,
                                          radeon_get_encoder_id(dev,
                                                                ATOM_DEVICE_CRT2_SUPPORT,
@@ -1644,11 +1676,11 @@ static bool radeon_apply_legacy_quirks(struct drm_device *dev,
        if ((rdev->family == CHIP_RS400 ||
             rdev->family == CHIP_RS480) &&
            ddc_i2c->mask_clk_reg == RADEON_GPIO_CRT2_DDC)
-               *ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_MONID);
+               *ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_MONID);
        else if ((rdev->family == CHIP_RS400 ||
                  rdev->family == CHIP_RS480) &&
                 ddc_i2c->mask_clk_reg == RADEON_GPIO_MONID) {
-               ddc_i2c->valid = true;
+               *ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIOPAD_MASK);
                ddc_i2c->mask_clk_mask = (0x20 << 8);
                ddc_i2c->mask_data_mask = 0x80;
                ddc_i2c->a_clk_mask = (0x20 << 8);
@@ -1657,20 +1689,12 @@ static bool radeon_apply_legacy_quirks(struct drm_device *dev,
                ddc_i2c->en_data_mask = 0x80;
                ddc_i2c->y_clk_mask = (0x20 << 8);
                ddc_i2c->y_data_mask = 0x80;
-               ddc_i2c->mask_clk_reg = RADEON_GPIOPAD_MASK;
-               ddc_i2c->mask_data_reg = RADEON_GPIOPAD_MASK;
-               ddc_i2c->a_clk_reg = RADEON_GPIOPAD_A;
-               ddc_i2c->a_data_reg = RADEON_GPIOPAD_A;
-               ddc_i2c->en_clk_reg = RADEON_GPIOPAD_EN;
-               ddc_i2c->en_data_reg = RADEON_GPIOPAD_EN;
-               ddc_i2c->y_clk_reg = RADEON_GPIOPAD_Y;
-               ddc_i2c->y_data_reg = RADEON_GPIOPAD_Y;
        }
 
        /* R3xx+ chips don't have GPIO_CRT2_DDC gpio pad */
        if ((rdev->family >= CHIP_R300) &&
            ddc_i2c->mask_clk_reg == RADEON_GPIO_CRT2_DDC)
-               *ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_DVI_DDC);
+               *ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_DVI_DDC);
 
        /* Certain IBM chipset RN50s have a BIOS reporting two VGAs,
           one with VGA DDC and one with CRT2 DDC. - kill the CRT2 DDC one */
@@ -1788,19 +1812,19 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev)
                        switch (ddc_type) {
                        case DDC_MONID:
                                ddc_i2c =
-                                   combios_setup_i2c_bus(RADEON_GPIO_MONID);
+                                       combios_setup_i2c_bus(rdev, RADEON_GPIO_MONID);
                                break;
                        case DDC_DVI:
                                ddc_i2c =
-                                   combios_setup_i2c_bus(RADEON_GPIO_DVI_DDC);
+                                       combios_setup_i2c_bus(rdev, RADEON_GPIO_DVI_DDC);
                                break;
                        case DDC_VGA:
                                ddc_i2c =
-                                   combios_setup_i2c_bus(RADEON_GPIO_VGA_DDC);
+                                       combios_setup_i2c_bus(rdev, RADEON_GPIO_VGA_DDC);
                                break;
                        case DDC_CRT2:
                                ddc_i2c =
-                                   combios_setup_i2c_bus(RADEON_GPIO_CRT2_DDC);
+                                       combios_setup_i2c_bus(rdev, RADEON_GPIO_CRT2_DDC);
                                break;
                        default:
                                break;
@@ -1955,7 +1979,7 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev)
                                                                        0),
                                                  ATOM_DEVICE_DFP1_SUPPORT);
 
-                       ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_DVI_DDC);
+                       ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_DVI_DDC);
                        radeon_add_legacy_connector(dev,
                                                    0,
                                                    ATOM_DEVICE_CRT1_SUPPORT |
@@ -1973,7 +1997,7 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev)
                                                                                ATOM_DEVICE_CRT1_SUPPORT,
                                                                                1),
                                                          ATOM_DEVICE_CRT1_SUPPORT);
-                               ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_VGA_DDC);
+                               ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_VGA_DDC);
                                radeon_add_legacy_connector(dev,
                                                            0,
                                                            ATOM_DEVICE_CRT1_SUPPORT,
@@ -2007,27 +2031,27 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev)
                                case DDC_MONID:
                                        ddc_i2c =
                                            combios_setup_i2c_bus
-                                           (RADEON_GPIO_MONID);
+                                               (rdev, RADEON_GPIO_MONID);
                                        break;
                                case DDC_DVI:
                                        ddc_i2c =
                                            combios_setup_i2c_bus
-                                           (RADEON_GPIO_DVI_DDC);
+                                               (rdev, RADEON_GPIO_DVI_DDC);
                                        break;
                                case DDC_VGA:
                                        ddc_i2c =
                                            combios_setup_i2c_bus
-                                           (RADEON_GPIO_VGA_DDC);
+                                               (rdev, RADEON_GPIO_VGA_DDC);
                                        break;
                                case DDC_CRT2:
                                        ddc_i2c =
                                            combios_setup_i2c_bus
-                                           (RADEON_GPIO_CRT2_DDC);
+                                               (rdev, RADEON_GPIO_CRT2_DDC);
                                        break;
                                case DDC_LCD:
                                        ddc_i2c =
                                            combios_setup_i2c_bus
-                                           (RADEON_LCD_GPIO_MASK);
+                                               (rdev, RADEON_GPIOPAD_MASK);
                                        ddc_i2c.mask_clk_mask =
                                            RBIOS32(lcd_ddc_info + 3);
                                        ddc_i2c.mask_data_mask =
@@ -2048,7 +2072,7 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev)
                                case DDC_GPIO:
                                        ddc_i2c =
                                            combios_setup_i2c_bus
-                                           (RADEON_MDGPIO_EN_REG);
+                                               (rdev, RADEON_MDGPIO_MASK);
                                        ddc_i2c.mask_clk_mask =
                                            RBIOS32(lcd_ddc_info + 3);
                                        ddc_i2c.mask_data_mask =
index 4d457bc..98634ce 100644 (file)
@@ -952,7 +952,7 @@ 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, uint8_t uc_i2c_id)
+                         uint16_t connector_object_id)
 {
        struct radeon_device *rdev = dev->dev_private;
        struct drm_connector *connector;
@@ -1083,8 +1083,7 @@ radeon_add_atom_connector(struct drm_device *dev,
                if (ret)
                        goto failed;
                /* add DP i2c bus */
-               radeon_dig_connector->uc_i2c_id = uc_i2c_id;
-               radeon_dig_connector->dp_i2c_bus = radeon_i2c_create_dp(dev, "DP-auxch", true, uc_i2c_id);
+               radeon_dig_connector->dp_i2c_bus = radeon_i2c_create_dp(dev, i2c_bus, "DP-auxch");
                if (i2c_bus->valid) {
                        radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "DP");
                        if (!radeon_connector->ddc_bus)
index f200312..da3da1e 100644 (file)
@@ -69,13 +69,15 @@ void radeon_i2c_do_lock(struct radeon_i2c_chan *i2c, int lock_state)
         * holds the i2c port in a bad state - switch hw i2c away before
         * doing DDC - do this for all r200s/r300s/r400s for safety sake
         */
-       if ((rdev->family >= CHIP_R200) && !ASIC_IS_AVIVO(rdev)) {
-               if (rec->a_clk_reg == RADEON_GPIO_MONID) {
-                       WREG32(RADEON_DVI_I2C_CNTL_0, (RADEON_I2C_SOFT_RST |
-                                               R200_DVI_I2C_PIN_SEL(R200_SEL_DDC1)));
-               } else {
-                       WREG32(RADEON_DVI_I2C_CNTL_0, (RADEON_I2C_SOFT_RST |
-                                               R200_DVI_I2C_PIN_SEL(R200_SEL_DDC3)));
+       if (rec->hw_capable) {
+               if ((rdev->family >= CHIP_R200) && !ASIC_IS_AVIVO(rdev)) {
+                       if (rec->a_clk_reg == RADEON_GPIO_MONID) {
+                               WREG32(RADEON_DVI_I2C_CNTL_0, (RADEON_I2C_SOFT_RST |
+                                                              R200_DVI_I2C_PIN_SEL(R200_SEL_DDC1)));
+                       } else {
+                               WREG32(RADEON_DVI_I2C_CNTL_0, (RADEON_I2C_SOFT_RST |
+                                                              R200_DVI_I2C_PIN_SEL(R200_SEL_DDC3)));
+                       }
                }
        }
 
@@ -86,6 +88,12 @@ void radeon_i2c_do_lock(struct radeon_i2c_chan *i2c, int lock_state)
        temp = RREG32(rec->a_data_reg) & ~rec->a_data_mask;
        WREG32(rec->a_data_reg, temp);
 
+       /* set the pins to input */
+       temp = RREG32(rec->en_clk_reg) & ~rec->en_clk_mask;
+       WREG32(rec->en_clk_reg, temp);
+
+       temp = RREG32(rec->en_data_reg) & ~rec->en_data_mask;
+       WREG32(rec->en_data_reg, temp);
 
        /* mask the gpio pins for software use */
        temp = RREG32(rec->mask_clk_reg);
@@ -199,7 +207,8 @@ out_free:
 }
 
 struct radeon_i2c_chan *radeon_i2c_create_dp(struct drm_device *dev,
-                                            const char *name, bool dp, u8 i2c_id)
+                                            struct radeon_i2c_bus_rec *rec,
+                                            const char *name)
 {
        struct radeon_i2c_chan *i2c;
        int ret;
@@ -208,7 +217,7 @@ struct radeon_i2c_chan *radeon_i2c_create_dp(struct drm_device *dev,
        if (i2c == NULL)
                return NULL;
 
-       i2c->i2c_id = i2c_id;
+       i2c->rec = *rec;
        i2c->adapter.owner = THIS_MODULE;
        i2c->dev = dev;
        i2c_set_adapdata(&i2c->adapter, i2c);
index 166f753..1964afb 100644 (file)
@@ -106,6 +106,13 @@ enum radeon_tv_std {
  */
 struct radeon_i2c_bus_rec {
        bool valid;
+       /* id used by atom */
+       uint8_t i2c_id;
+       /* can be used with hw i2c engine */
+       bool hw_capable;
+       /* uses multi-media i2c engine */
+       bool mm_i2c;
+       /* regs and bits */
        uint32_t mask_clk_reg;
        uint32_t mask_data_reg;
        uint32_t a_clk_reg;
@@ -172,7 +179,6 @@ struct radeon_i2c_chan {
                struct i2c_algo_bit_data bit;
        } algo;
        struct radeon_i2c_bus_rec rec;
-       uint8_t i2c_id;
 };
 
 /* mostly for macs, but really any system without connector tables */
@@ -333,7 +339,6 @@ struct radeon_encoder {
 struct radeon_connector_atom_dig {
        uint32_t igp_lane_info;
        bool linkb;
-       uint16_t uc_i2c_id;
        struct radeon_i2c_chan *dp_i2c_bus;
        u8 dpcd[8];
 };
@@ -352,8 +357,6 @@ struct radeon_connector {
        void *con_priv;
        bool dac_load_detect;
        uint16_t connector_object_id;
-       /* need to keep this for display port */
-//     
 };
 
 struct radeon_framebuffer {
@@ -362,12 +365,13 @@ struct radeon_framebuffer {
 };
 
 extern int radeon_dp_getsinktype(struct radeon_connector *radeon_connector);
-extern void radeon_dp_getdpcd(struct radeon_connector *connector);
+extern void radeon_dp_getdpcd(struct radeon_connector *radeon_connector);
 extern int radeon_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode,
                                uint8_t write_byte, uint8_t *read_byte);
 
 extern struct radeon_i2c_chan *radeon_i2c_create_dp(struct drm_device *dev,
-                                                   const char *name, bool dp, u8 i2c_id);
+                                                   struct radeon_i2c_bus_rec *rec,
+                                                   const char *name);
 extern struct radeon_i2c_chan *radeon_i2c_create(struct drm_device *dev,
                                                 struct radeon_i2c_bus_rec *rec,
                                                 const char *name);
index c4c41c8..b811640 100644 (file)
 #       define RADEON_IO_MCLK_MAX_DYN_STOP_LAT (1 << 13)
 #       define RADEON_MC_MCLK_DYN_ENABLE    (1 << 14)
 #       define RADEON_IO_MCLK_DYN_ENABLE    (1 << 15)
+
 #define RADEON_GPIOPAD_MASK                 0x0198
 #define RADEON_GPIOPAD_A                   0x019c
 #define RADEON_GPIOPAD_EN                   0x01a0
 #define RADEON_GPIOPAD_Y                    0x01a4
-#define RADEON_LCD_GPIO_MASK                0x01a0
-#define RADEON_LCD_GPIO_Y_REG               0x01a4
-#define RADEON_MDGPIO_A_REG                 0x01ac
-#define RADEON_MDGPIO_EN_REG                0x01b0
-#define RADEON_MDGPIO_MASK                  0x0198
-#define RADEON_MDGPIO_Y_REG                 0x01b4
+#define RADEON_MDGPIO_MASK                  0x01a8
+#define RADEON_MDGPIO_A                     0x01ac
+#define RADEON_MDGPIO_EN                    0x01b0
+#define RADEON_MDGPIO_Y                     0x01b4
+
 #define RADEON_MEM_ADDR_CONFIG              0x0148
 #define RADEON_MEM_BASE                     0x0f10 /* PCI */
 #define RADEON_MEM_CNTL                     0x0140