From ee59f2b462b0a7d2eb57ae59340d016589fa8e42 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Thu, 5 Nov 2009 13:11:46 -0500 Subject: drm/radeon/kms/r600: fix rs880 support v2 Lots of cases were wrong or missing. v2: rebased against drm-next Signed-off-by: Alex Deucher Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/r600.c | 18 ++++++++++++------ drivers/gpu/drm/radeon/r600_blit_kms.c | 2 +- drivers/gpu/drm/radeon/radeon_atombios.c | 3 ++- 3 files changed, 15 insertions(+), 8 deletions(-) (limited to 'drivers/gpu/drm/radeon') diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index 3e5703f324b..35360b09df3 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c @@ -858,7 +858,8 @@ void r600_gpu_init(struct radeon_device *rdev) ((rdev->family) == CHIP_RV630) || ((rdev->family) == CHIP_RV610) || ((rdev->family) == CHIP_RV620) || - ((rdev->family) == CHIP_RS780)) { + ((rdev->family) == CHIP_RS780) || + ((rdev->family) == CHIP_RS880)) { WREG32(DB_DEBUG, PREZ_MUST_WAIT_FOR_POSTZ_DONE); } else { WREG32(DB_DEBUG, 0); @@ -875,7 +876,8 @@ void r600_gpu_init(struct radeon_device *rdev) tmp = RREG32(SQ_MS_FIFO_SIZES); if (((rdev->family) == CHIP_RV610) || ((rdev->family) == CHIP_RV620) || - ((rdev->family) == CHIP_RS780)) { + ((rdev->family) == CHIP_RS780) || + ((rdev->family) == CHIP_RS880)) { tmp = (CACHE_FIFO_SIZE(0xa) | FETCH_FIFO_HIWATER(0xa) | DONE_FIFO_HIWATER(0xe0) | @@ -918,7 +920,8 @@ void r600_gpu_init(struct radeon_device *rdev) NUM_ES_STACK_ENTRIES(0)); } else if (((rdev->family) == CHIP_RV610) || ((rdev->family) == CHIP_RV620) || - ((rdev->family) == CHIP_RS780)) { + ((rdev->family) == CHIP_RS780) || + ((rdev->family) == CHIP_RS880)) { /* no vertex cache */ sq_config &= ~VC_ENABLE; @@ -975,7 +978,8 @@ void r600_gpu_init(struct radeon_device *rdev) if (((rdev->family) == CHIP_RV610) || ((rdev->family) == CHIP_RV620) || - ((rdev->family) == CHIP_RS780)) { + ((rdev->family) == CHIP_RS780) || + ((rdev->family) == CHIP_RS880)) { WREG32(VGT_CACHE_INVALIDATION, CACHE_INVALIDATION(TC_ONLY)); } else { WREG32(VGT_CACHE_INVALIDATION, CACHE_INVALIDATION(VC_AND_TC)); @@ -1001,8 +1005,9 @@ void r600_gpu_init(struct radeon_device *rdev) tmp = rdev->config.r600.max_pipes * 16; switch (rdev->family) { case CHIP_RV610: - case CHIP_RS780: case CHIP_RV620: + case CHIP_RS780: + case CHIP_RS880: tmp += 32; break; case CHIP_RV670: @@ -1043,8 +1048,9 @@ void r600_gpu_init(struct radeon_device *rdev) switch (rdev->family) { case CHIP_RV610: - case CHIP_RS780: case CHIP_RV620: + case CHIP_RS780: + case CHIP_RS880: tmp = TC_L2_SIZE(8); break; case CHIP_RV630: diff --git a/drivers/gpu/drm/radeon/r600_blit_kms.c b/drivers/gpu/drm/radeon/r600_blit_kms.c index acae33e2ad5..dbf716e1fbf 100644 --- a/drivers/gpu/drm/radeon/r600_blit_kms.c +++ b/drivers/gpu/drm/radeon/r600_blit_kms.c @@ -368,7 +368,7 @@ set_default_state(struct radeon_device *rdev) if ((rdev->family == CHIP_RV610) || (rdev->family == CHIP_RV620) || (rdev->family == CHIP_RS780) || - (rdev->family == CHIP_RS780) || + (rdev->family == CHIP_RS880) || (rdev->family == CHIP_RV710)) sq_config = 0; else diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c index 1c9a9c46176..050722492b4 100644 --- a/drivers/gpu/drm/radeon/radeon_atombios.c +++ b/drivers/gpu/drm/radeon/radeon_atombios.c @@ -277,7 +277,8 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev) ATOM_DEVICE_CV_SUPPORT) continue; - if ((rdev->family == CHIP_RS780) && + /* IGP chips */ + if ((rdev->flags & RADEON_IS_IGP) && (con_obj_id == CONNECTOR_OBJECT_ID_PCIE_CONNECTOR)) { uint16_t igp_offset = 0; -- cgit v1.2.3 From 4170a6c1bc106d7fcf94f5842224ac4dac61006b Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Thu, 5 Nov 2009 01:16:23 -0500 Subject: drm/radeon/kms/atom/dce3: fix up usPixelClock calculation for Transmitter tables Signed-off-by: Alex Deucher Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/radeon_encoders.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'drivers/gpu/drm/radeon') diff --git a/drivers/gpu/drm/radeon/radeon_encoders.c b/drivers/gpu/drm/radeon/radeon_encoders.c index 2aa5994a29d..355b0fbed92 100644 --- a/drivers/gpu/drm/radeon/radeon_encoders.c +++ b/drivers/gpu/drm/radeon/radeon_encoders.c @@ -725,10 +725,10 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action) if (ASIC_IS_DCE32(rdev)) { if (radeon_encoder->pixel_clock > 165000) { - args.v2.usPixelClock = cpu_to_le16((radeon_encoder->pixel_clock * 10 * 2) / 100); + args.v2.usPixelClock = cpu_to_le16((radeon_encoder->pixel_clock / 2) / 10); args.v2.acConfig.fDualLinkConnector = 1; } else { - args.v2.usPixelClock = cpu_to_le16((radeon_encoder->pixel_clock * 10 * 4) / 100); + args.v2.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); } if (dig->dig_block) args.v2.acConfig.ucEncoderSel = 1; @@ -754,7 +754,10 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action) } } else { args.v1.ucConfig = ATOM_TRANSMITTER_CONFIG_CLKSRC_PPLL; - args.v1.usPixelClock = cpu_to_le16((radeon_encoder->pixel_clock) / 10); + if (radeon_encoder->pixel_clock > 165000) + args.v1.usPixelClock = cpu_to_le16((radeon_encoder->pixel_clock / 2) / 10); + else + args.v1.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); switch (radeon_encoder->encoder_id) { case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: -- cgit v1.2.3 From b75fad0682caacb16012582deecbd7d19bc2f68e Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Thu, 5 Nov 2009 13:16:01 -0500 Subject: drm/radeon/kms: store detailed connector info This will be useful for mode validation and certain atom tables. Signed-off-by: Alex Deucher Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/radeon_atombios.c | 76 +++++++++++++- drivers/gpu/drm/radeon/radeon_combios.c | 162 +++++++++++++++++++++-------- drivers/gpu/drm/radeon/radeon_connectors.c | 8 +- drivers/gpu/drm/radeon/radeon_mode.h | 1 + 4 files changed, 199 insertions(+), 48 deletions(-) (limited to 'drivers/gpu/drm/radeon') diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c index 050722492b4..80aacded85a 100644 --- a/drivers/gpu/drm/radeon/radeon_atombios.c +++ b/drivers/gpu/drm/radeon/radeon_atombios.c @@ -46,7 +46,8 @@ radeon_add_atom_connector(struct drm_device *dev, uint32_t supported_device, int connector_type, struct radeon_i2c_bus_rec *i2c_bus, - bool linkb, uint32_t igp_lane_info); + bool linkb, uint32_t igp_lane_info, + uint16_t connector_object_id); /* from radeon_legacy_encoder.c */ extern void @@ -193,6 +194,23 @@ const int supported_devices_connector_convert[] = { DRM_MODE_CONNECTOR_DisplayPort }; +const uint16_t supported_devices_connector_object_id_convert[] = { + CONNECTOR_OBJECT_ID_NONE, + CONNECTOR_OBJECT_ID_VGA, + CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_I, /* not all boards support DL */ + CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_D, /* not all boards support DL */ + CONNECTOR_OBJECT_ID_VGA, /* technically DVI-A */ + CONNECTOR_OBJECT_ID_COMPOSITE, + CONNECTOR_OBJECT_ID_SVIDEO, + CONNECTOR_OBJECT_ID_LVDS, + CONNECTOR_OBJECT_ID_9PIN_DIN, + CONNECTOR_OBJECT_ID_9PIN_DIN, + CONNECTOR_OBJECT_ID_DISPLAYPORT, + CONNECTOR_OBJECT_ID_HDMI_TYPE_A, + CONNECTOR_OBJECT_ID_HDMI_TYPE_B, + CONNECTOR_OBJECT_ID_SVIDEO +}; + const int object_connector_convert[] = { DRM_MODE_CONNECTOR_Unknown, DRM_MODE_CONNECTOR_DVII, @@ -229,7 +247,7 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev) ATOM_OBJECT_HEADER *obj_header; int i, j, path_size, device_support; int connector_type; - uint16_t igp_lane_info, conn_id; + uint16_t igp_lane_info, conn_id, connector_object_id; bool linkb; struct radeon_i2c_bus_rec ddc_bus; @@ -312,6 +330,7 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev) connector_type = object_connector_convert [ct]; + connector_object_id = ct; igp_lane_info = slot_config & 0xffff; } else @@ -322,6 +341,7 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev) igp_lane_info = 0; connector_type = object_connector_convert[con_obj_id]; + connector_object_id = con_obj_id; } if (connector_type == DRM_MODE_CONNECTOR_Unknown) @@ -426,7 +446,8 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev) le16_to_cpu(path-> usDeviceTag), connector_type, &ddc_bus, - linkb, igp_lane_info); + linkb, igp_lane_info, + connector_object_id); } } @@ -436,6 +457,45 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev) return true; } +static uint16_t atombios_get_connector_object_id(struct drm_device *dev, + int connector_type, + uint16_t devices) +{ + struct radeon_device *rdev = dev->dev_private; + + if (rdev->flags & RADEON_IS_IGP) { + return supported_devices_connector_object_id_convert + [connector_type]; + } else if (((connector_type == DRM_MODE_CONNECTOR_DVII) || + (connector_type == DRM_MODE_CONNECTOR_DVID)) && + (devices & ATOM_DEVICE_DFP2_SUPPORT)) { + struct radeon_mode_info *mode_info = &rdev->mode_info; + struct atom_context *ctx = mode_info->atom_context; + int index = GetIndexIntoMasterTable(DATA, XTMDS_Info); + uint16_t size, data_offset; + uint8_t frev, crev; + ATOM_XTMDS_INFO *xtmds; + + atom_parse_data_header(ctx, index, &size, &frev, &crev, &data_offset); + xtmds = (ATOM_XTMDS_INFO *)(ctx->bios + data_offset); + + if (xtmds->ucSupportedLink & ATOM_XTMDS_SUPPORTED_DUALLINK) { + if (connector_type == DRM_MODE_CONNECTOR_DVII) + return CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_I; + else + return CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_D; + } else { + if (connector_type == DRM_MODE_CONNECTOR_DVII) + return CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I; + else + return CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D; + } + } else { + return supported_devices_connector_object_id_convert + [connector_type]; + } +} + struct bios_connector { bool valid; uint16_t line_mux; @@ -594,14 +654,20 @@ bool radeon_get_atom_connector_info_from_supported_devices_table(struct /* add the connectors */ for (i = 0; i < ATOM_MAX_SUPPORTED_DEVICE; i++) { - if (bios_connectors[i].valid) + if (bios_connectors[i].valid) { + uint16_t connector_object_id = + atombios_get_connector_object_id(dev, + bios_connectors[i].connector_type, + bios_connectors[i].devices); radeon_add_atom_connector(dev, bios_connectors[i].line_mux, bios_connectors[i].devices, bios_connectors[i]. connector_type, &bios_connectors[i].ddc_bus, - false, 0); + false, 0, + connector_object_id); + } } radeon_link_encoder_connector(dev); diff --git a/drivers/gpu/drm/radeon/radeon_combios.c b/drivers/gpu/drm/radeon/radeon_combios.c index a36ede002ee..5253cbf6db1 100644 --- a/drivers/gpu/drm/radeon/radeon_combios.c +++ b/drivers/gpu/drm/radeon/radeon_combios.c @@ -49,7 +49,8 @@ radeon_add_legacy_connector(struct drm_device *dev, uint32_t connector_id, uint32_t supported_device, int connector_type, - struct radeon_i2c_bus_rec *i2c_bus); + struct radeon_i2c_bus_rec *i2c_bus, + uint16_t connector_object_id); /* from radeon_legacy_encoder.c */ extern void @@ -1176,7 +1177,8 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) radeon_add_legacy_connector(dev, 0, ATOM_DEVICE_CRT1_SUPPORT, DRM_MODE_CONNECTOR_VGA, - &ddc_i2c); + &ddc_i2c, + CONNECTOR_OBJECT_ID_VGA); } else if (rdev->flags & RADEON_IS_MOBILITY) { /* LVDS */ ddc_i2c = combios_setup_i2c_bus(RADEON_LCD_GPIO_MASK); @@ -1188,7 +1190,8 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) radeon_add_legacy_connector(dev, 0, ATOM_DEVICE_LCD1_SUPPORT, DRM_MODE_CONNECTOR_LVDS, - &ddc_i2c); + &ddc_i2c, + CONNECTOR_OBJECT_ID_LVDS); /* VGA - primary dac */ ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_VGA_DDC); @@ -1200,7 +1203,8 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) radeon_add_legacy_connector(dev, 1, ATOM_DEVICE_CRT1_SUPPORT, DRM_MODE_CONNECTOR_VGA, - &ddc_i2c); + &ddc_i2c, + CONNECTOR_OBJECT_ID_VGA); } else { /* DVI-I - tv dac, int tmds */ ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_DVI_DDC); @@ -1218,7 +1222,8 @@ 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); + &ddc_i2c, + CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I); /* VGA - primary dac */ ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_VGA_DDC); @@ -1230,7 +1235,8 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) radeon_add_legacy_connector(dev, 1, ATOM_DEVICE_CRT1_SUPPORT, DRM_MODE_CONNECTOR_VGA, - &ddc_i2c); + &ddc_i2c, + CONNECTOR_OBJECT_ID_VGA); } if (rdev->family != CHIP_R100 && rdev->family != CHIP_R200) { @@ -1243,7 +1249,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); + &ddc_i2c, + CONNECTOR_OBJECT_ID_SVIDEO); } break; case CT_IBOOK: @@ -1257,7 +1264,8 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) 0), ATOM_DEVICE_LCD1_SUPPORT); radeon_add_legacy_connector(dev, 0, ATOM_DEVICE_LCD1_SUPPORT, - DRM_MODE_CONNECTOR_LVDS, &ddc_i2c); + DRM_MODE_CONNECTOR_LVDS, &ddc_i2c, + CONNECTOR_OBJECT_ID_LVDS); /* VGA - TV DAC */ ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_VGA_DDC); radeon_add_legacy_encoder(dev, @@ -1266,7 +1274,8 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) 2), ATOM_DEVICE_CRT2_SUPPORT); radeon_add_legacy_connector(dev, 1, ATOM_DEVICE_CRT2_SUPPORT, - DRM_MODE_CONNECTOR_VGA, &ddc_i2c); + DRM_MODE_CONNECTOR_VGA, &ddc_i2c, + CONNECTOR_OBJECT_ID_VGA); /* TV - TV DAC */ radeon_add_legacy_encoder(dev, radeon_get_encoder_id(dev, @@ -1275,7 +1284,8 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) ATOM_DEVICE_TV1_SUPPORT); radeon_add_legacy_connector(dev, 2, ATOM_DEVICE_TV1_SUPPORT, DRM_MODE_CONNECTOR_SVIDEO, - &ddc_i2c); + &ddc_i2c, + CONNECTOR_OBJECT_ID_SVIDEO); break; case CT_POWERBOOK_EXTERNAL: DRM_INFO("Connector Table: %d (powerbook external tmds)\n", @@ -1288,7 +1298,8 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) 0), ATOM_DEVICE_LCD1_SUPPORT); radeon_add_legacy_connector(dev, 0, ATOM_DEVICE_LCD1_SUPPORT, - DRM_MODE_CONNECTOR_LVDS, &ddc_i2c); + 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); radeon_add_legacy_encoder(dev, @@ -1301,10 +1312,12 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) ATOM_DEVICE_CRT1_SUPPORT, 1), ATOM_DEVICE_CRT1_SUPPORT); + /* XXX some are SL */ radeon_add_legacy_connector(dev, 1, ATOM_DEVICE_DFP2_SUPPORT | ATOM_DEVICE_CRT1_SUPPORT, - DRM_MODE_CONNECTOR_DVII, &ddc_i2c); + DRM_MODE_CONNECTOR_DVII, &ddc_i2c, + CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_I); /* TV - TV DAC */ radeon_add_legacy_encoder(dev, radeon_get_encoder_id(dev, @@ -1313,7 +1326,8 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) ATOM_DEVICE_TV1_SUPPORT); radeon_add_legacy_connector(dev, 2, ATOM_DEVICE_TV1_SUPPORT, DRM_MODE_CONNECTOR_SVIDEO, - &ddc_i2c); + &ddc_i2c, + CONNECTOR_OBJECT_ID_SVIDEO); break; case CT_POWERBOOK_INTERNAL: DRM_INFO("Connector Table: %d (powerbook internal tmds)\n", @@ -1326,7 +1340,8 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) 0), ATOM_DEVICE_LCD1_SUPPORT); radeon_add_legacy_connector(dev, 0, ATOM_DEVICE_LCD1_SUPPORT, - DRM_MODE_CONNECTOR_LVDS, &ddc_i2c); + 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); radeon_add_legacy_encoder(dev, @@ -1342,7 +1357,8 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) radeon_add_legacy_connector(dev, 1, ATOM_DEVICE_DFP1_SUPPORT | ATOM_DEVICE_CRT1_SUPPORT, - DRM_MODE_CONNECTOR_DVII, &ddc_i2c); + DRM_MODE_CONNECTOR_DVII, &ddc_i2c, + CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I); /* TV - TV DAC */ radeon_add_legacy_encoder(dev, radeon_get_encoder_id(dev, @@ -1351,7 +1367,8 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) ATOM_DEVICE_TV1_SUPPORT); radeon_add_legacy_connector(dev, 2, ATOM_DEVICE_TV1_SUPPORT, DRM_MODE_CONNECTOR_SVIDEO, - &ddc_i2c); + &ddc_i2c, + CONNECTOR_OBJECT_ID_SVIDEO); break; case CT_POWERBOOK_VGA: DRM_INFO("Connector Table: %d (powerbook vga)\n", @@ -1364,7 +1381,8 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) 0), ATOM_DEVICE_LCD1_SUPPORT); radeon_add_legacy_connector(dev, 0, ATOM_DEVICE_LCD1_SUPPORT, - DRM_MODE_CONNECTOR_LVDS, &ddc_i2c); + DRM_MODE_CONNECTOR_LVDS, &ddc_i2c, + CONNECTOR_OBJECT_ID_LVDS); /* VGA - primary dac */ ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_VGA_DDC); radeon_add_legacy_encoder(dev, @@ -1373,7 +1391,8 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) 1), ATOM_DEVICE_CRT1_SUPPORT); radeon_add_legacy_connector(dev, 1, ATOM_DEVICE_CRT1_SUPPORT, - DRM_MODE_CONNECTOR_VGA, &ddc_i2c); + DRM_MODE_CONNECTOR_VGA, &ddc_i2c, + CONNECTOR_OBJECT_ID_VGA); /* TV - TV DAC */ radeon_add_legacy_encoder(dev, radeon_get_encoder_id(dev, @@ -1382,7 +1401,8 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) ATOM_DEVICE_TV1_SUPPORT); radeon_add_legacy_connector(dev, 2, ATOM_DEVICE_TV1_SUPPORT, DRM_MODE_CONNECTOR_SVIDEO, - &ddc_i2c); + &ddc_i2c, + CONNECTOR_OBJECT_ID_SVIDEO); break; case CT_MINI_EXTERNAL: DRM_INFO("Connector Table: %d (mini external tmds)\n", @@ -1399,10 +1419,12 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) ATOM_DEVICE_CRT2_SUPPORT, 2), ATOM_DEVICE_CRT2_SUPPORT); + /* XXX are any DL? */ radeon_add_legacy_connector(dev, 0, ATOM_DEVICE_DFP2_SUPPORT | ATOM_DEVICE_CRT2_SUPPORT, - DRM_MODE_CONNECTOR_DVII, &ddc_i2c); + DRM_MODE_CONNECTOR_DVII, &ddc_i2c, + CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I); /* TV - TV DAC */ radeon_add_legacy_encoder(dev, radeon_get_encoder_id(dev, @@ -1411,7 +1433,8 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) ATOM_DEVICE_TV1_SUPPORT); radeon_add_legacy_connector(dev, 1, ATOM_DEVICE_TV1_SUPPORT, DRM_MODE_CONNECTOR_SVIDEO, - &ddc_i2c); + &ddc_i2c, + CONNECTOR_OBJECT_ID_SVIDEO); break; case CT_MINI_INTERNAL: DRM_INFO("Connector Table: %d (mini internal tmds)\n", @@ -1431,7 +1454,8 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) radeon_add_legacy_connector(dev, 0, ATOM_DEVICE_DFP1_SUPPORT | ATOM_DEVICE_CRT2_SUPPORT, - DRM_MODE_CONNECTOR_DVII, &ddc_i2c); + DRM_MODE_CONNECTOR_DVII, &ddc_i2c, + CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I); /* TV - TV DAC */ radeon_add_legacy_encoder(dev, radeon_get_encoder_id(dev, @@ -1440,7 +1464,8 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) ATOM_DEVICE_TV1_SUPPORT); radeon_add_legacy_connector(dev, 1, ATOM_DEVICE_TV1_SUPPORT, DRM_MODE_CONNECTOR_SVIDEO, - &ddc_i2c); + &ddc_i2c, + CONNECTOR_OBJECT_ID_SVIDEO); break; case CT_IMAC_G5_ISIGHT: DRM_INFO("Connector Table: %d (imac g5 isight)\n", @@ -1453,7 +1478,8 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) 0), ATOM_DEVICE_DFP1_SUPPORT); radeon_add_legacy_connector(dev, 0, ATOM_DEVICE_DFP1_SUPPORT, - DRM_MODE_CONNECTOR_DVID, &ddc_i2c); + 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); radeon_add_legacy_encoder(dev, @@ -1462,7 +1488,8 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) 2), ATOM_DEVICE_CRT2_SUPPORT); radeon_add_legacy_connector(dev, 1, ATOM_DEVICE_CRT2_SUPPORT, - DRM_MODE_CONNECTOR_VGA, &ddc_i2c); + DRM_MODE_CONNECTOR_VGA, &ddc_i2c, + CONNECTOR_OBJECT_ID_VGA); /* TV - TV DAC */ radeon_add_legacy_encoder(dev, radeon_get_encoder_id(dev, @@ -1471,7 +1498,8 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) ATOM_DEVICE_TV1_SUPPORT); radeon_add_legacy_connector(dev, 2, ATOM_DEVICE_TV1_SUPPORT, DRM_MODE_CONNECTOR_SVIDEO, - &ddc_i2c); + &ddc_i2c, + CONNECTOR_OBJECT_ID_SVIDEO); break; case CT_EMAC: DRM_INFO("Connector Table: %d (emac)\n", @@ -1484,7 +1512,8 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) 1), ATOM_DEVICE_CRT1_SUPPORT); radeon_add_legacy_connector(dev, 0, ATOM_DEVICE_CRT1_SUPPORT, - DRM_MODE_CONNECTOR_VGA, &ddc_i2c); + DRM_MODE_CONNECTOR_VGA, &ddc_i2c, + CONNECTOR_OBJECT_ID_VGA); /* VGA - tv dac */ ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_CRT2_DDC); radeon_add_legacy_encoder(dev, @@ -1493,7 +1522,8 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) 2), ATOM_DEVICE_CRT2_SUPPORT); radeon_add_legacy_connector(dev, 1, ATOM_DEVICE_CRT2_SUPPORT, - DRM_MODE_CONNECTOR_VGA, &ddc_i2c); + DRM_MODE_CONNECTOR_VGA, &ddc_i2c, + CONNECTOR_OBJECT_ID_VGA); /* TV - TV DAC */ radeon_add_legacy_encoder(dev, radeon_get_encoder_id(dev, @@ -1502,7 +1532,8 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) ATOM_DEVICE_TV1_SUPPORT); radeon_add_legacy_connector(dev, 2, ATOM_DEVICE_TV1_SUPPORT, DRM_MODE_CONNECTOR_SVIDEO, - &ddc_i2c); + &ddc_i2c, + CONNECTOR_OBJECT_ID_SVIDEO); break; default: DRM_INFO("Connector table: %d (invalid)\n", @@ -1596,11 +1627,46 @@ static bool radeon_apply_legacy_tv_quirks(struct drm_device *dev) return true; } +static uint16_t combios_check_dl_dvi(struct drm_device *dev, int is_dvi_d) +{ + struct radeon_device *rdev = dev->dev_private; + uint32_t ext_tmds_info; + + if (rdev->flags & RADEON_IS_IGP) { + if (is_dvi_d) + return CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D; + else + return CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I; + } + ext_tmds_info = combios_get_table_offset(dev, COMBIOS_EXT_TMDS_INFO_TABLE); + if (ext_tmds_info) { + uint8_t rev = RBIOS8(ext_tmds_info); + uint8_t flags = RBIOS8(ext_tmds_info + 4 + 5); + if (rev >= 3) { + if (is_dvi_d) + return CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_D; + else + return CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_I; + } else { + if (flags & 1) { + if (is_dvi_d) + return CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_D; + else + return CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_I; + } + } + } + if (is_dvi_d) + return CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D; + else + return CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I; +} + bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev) { struct radeon_device *rdev = dev->dev_private; uint32_t conn_info, entry, devices; - uint16_t tmp; + uint16_t tmp, connector_object_id; enum radeon_combios_ddc ddc_type; enum radeon_combios_connector connector; int i = 0; @@ -1660,7 +1726,8 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev) radeon_add_legacy_connector(dev, i, devices, legacy_connector_convert [connector], - &ddc_i2c); + &ddc_i2c, + CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D); break; case CONNECTOR_CRT_LEGACY: if (tmp & 0x1) { @@ -1685,7 +1752,8 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev) devices, legacy_connector_convert [connector], - &ddc_i2c); + &ddc_i2c, + CONNECTOR_OBJECT_ID_VGA); break; case CONNECTOR_DVI_I_LEGACY: devices = 0; @@ -1714,6 +1782,7 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev) ATOM_DEVICE_DFP2_SUPPORT, 0), ATOM_DEVICE_DFP2_SUPPORT); + connector_object_id = combios_check_dl_dvi(dev, 0); } else { devices |= ATOM_DEVICE_DFP1_SUPPORT; radeon_add_legacy_encoder(dev, @@ -1722,19 +1791,24 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev) ATOM_DEVICE_DFP1_SUPPORT, 0), ATOM_DEVICE_DFP1_SUPPORT); + connector_object_id = CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I; } radeon_add_legacy_connector(dev, i, devices, legacy_connector_convert [connector], - &ddc_i2c); + &ddc_i2c, + connector_object_id); break; case CONNECTOR_DVI_D_LEGACY: - if ((tmp >> 4) & 0x1) + if ((tmp >> 4) & 0x1) { devices = ATOM_DEVICE_DFP2_SUPPORT; - else + connector_object_id = combios_check_dl_dvi(dev, 1); + } else { devices = ATOM_DEVICE_DFP1_SUPPORT; + connector_object_id = CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I; + } radeon_add_legacy_encoder(dev, radeon_get_encoder_id (dev, devices, 0), @@ -1742,7 +1816,8 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev) radeon_add_legacy_connector(dev, i, devices, legacy_connector_convert [connector], - &ddc_i2c); + &ddc_i2c, + connector_object_id); break; case CONNECTOR_CTV_LEGACY: case CONNECTOR_STV_LEGACY: @@ -1756,7 +1831,8 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev) ATOM_DEVICE_TV1_SUPPORT, legacy_connector_convert [connector], - &ddc_i2c); + &ddc_i2c, + CONNECTOR_OBJECT_ID_SVIDEO); break; default: DRM_ERROR("Unknown connector type: %d\n", @@ -1788,7 +1864,8 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev) ATOM_DEVICE_CRT1_SUPPORT | ATOM_DEVICE_DFP1_SUPPORT, DRM_MODE_CONNECTOR_DVII, - &ddc_i2c); + &ddc_i2c, + CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I); } else { uint16_t crt_info = combios_get_table_offset(dev, COMBIOS_CRT_INFO_TABLE); @@ -1804,7 +1881,8 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev) 0, ATOM_DEVICE_CRT1_SUPPORT, DRM_MODE_CONNECTOR_VGA, - &ddc_i2c); + &ddc_i2c, + CONNECTOR_OBJECT_ID_VGA); } else { DRM_DEBUG("No connector info found\n"); return false; @@ -1903,7 +1981,8 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev) 5, ATOM_DEVICE_LCD1_SUPPORT, DRM_MODE_CONNECTOR_LVDS, - &ddc_i2c); + &ddc_i2c, + CONNECTOR_OBJECT_ID_LVDS); } } @@ -1923,7 +2002,8 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev) radeon_add_legacy_connector(dev, 6, ATOM_DEVICE_TV1_SUPPORT, DRM_MODE_CONNECTOR_SVIDEO, - &ddc_i2c); + &ddc_i2c, + CONNECTOR_OBJECT_ID_SVIDEO); } } } diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c index ce3a785a633..fb4d9184704 100644 --- a/drivers/gpu/drm/radeon/radeon_connectors.c +++ b/drivers/gpu/drm/radeon/radeon_connectors.c @@ -823,7 +823,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) + uint32_t igp_lane_info, + uint16_t connector_object_id) { struct radeon_device *rdev = dev->dev_private; struct drm_connector *connector; @@ -862,6 +863,7 @@ radeon_add_atom_connector(struct drm_device *dev, radeon_connector->connector_id = connector_id; radeon_connector->devices = supported_device; radeon_connector->shared_ddc = shared_ddc; + radeon_connector->connector_object_id = connector_object_id; switch (connector_type) { case DRM_MODE_CONNECTOR_VGA: drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type); @@ -1013,7 +1015,8 @@ radeon_add_legacy_connector(struct drm_device *dev, uint32_t connector_id, uint32_t supported_device, int connector_type, - struct radeon_i2c_bus_rec *i2c_bus) + struct radeon_i2c_bus_rec *i2c_bus, + uint16_t connector_object_id) { struct radeon_device *rdev = dev->dev_private; struct drm_connector *connector; @@ -1042,6 +1045,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; switch (connector_type) { case DRM_MODE_CONNECTOR_VGA: drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type); diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h index ccb783868ad..ace726aa0d7 100644 --- a/drivers/gpu/drm/radeon/radeon_mode.h +++ b/drivers/gpu/drm/radeon/radeon_mode.h @@ -317,6 +317,7 @@ struct radeon_connector { struct edid *edid; void *con_priv; bool dac_load_detect; + uint16_t connector_object_id; }; struct radeon_framebuffer { -- cgit v1.2.3 From f95a9f0b05d22cffc46fbd2d065b260f8405e43f Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Thu, 5 Nov 2009 02:21:06 -0500 Subject: drm/radeon/kms/atom/dce3: call transmitter init on mode set Generally this is done at post, but might not always be done with softboot or for connectors on docking stations. Could probably be done once when the driver loads/resumes rather than on each mode set. Signed-off-by: Alex Deucher Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/radeon_encoders.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'drivers/gpu/drm/radeon') diff --git a/drivers/gpu/drm/radeon/radeon_encoders.c b/drivers/gpu/drm/radeon/radeon_encoders.c index 355b0fbed92..d42bc512d75 100644 --- a/drivers/gpu/drm/radeon/radeon_encoders.c +++ b/drivers/gpu/drm/radeon/radeon_encoders.c @@ -722,14 +722,17 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action) atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev); args.v1.ucAction = action; - + if (action == ATOM_TRANSMITTER_ACTION_INIT) { + args.v1.usInitInfo = radeon_connector->connector_object_id; + } else { + if (radeon_encoder->pixel_clock > 165000) + args.v1.usPixelClock = cpu_to_le16((radeon_encoder->pixel_clock / 2) / 10); + else + args.v1.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); + } if (ASIC_IS_DCE32(rdev)) { - if (radeon_encoder->pixel_clock > 165000) { + if (radeon_encoder->pixel_clock > 165000) args.v2.usPixelClock = cpu_to_le16((radeon_encoder->pixel_clock / 2) / 10); - args.v2.acConfig.fDualLinkConnector = 1; - } else { - args.v2.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); - } if (dig->dig_block) args.v2.acConfig.ucEncoderSel = 1; @@ -754,10 +757,6 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action) } } else { args.v1.ucConfig = ATOM_TRANSMITTER_CONFIG_CLKSRC_PPLL; - if (radeon_encoder->pixel_clock > 165000) - args.v1.usPixelClock = cpu_to_le16((radeon_encoder->pixel_clock / 2) / 10); - else - args.v1.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); switch (radeon_encoder->encoder_id) { case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: @@ -1140,6 +1139,7 @@ radeon_atom_encoder_mode_set(struct drm_encoder *encoder, /* setup and enable the encoder and transmitter */ atombios_dig_encoder_setup(encoder, ATOM_ENABLE); + atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_INIT); atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_SETUP); atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE); break; -- cgit v1.2.3 From a3fa6320ce964f799388b152a1b0f6e2c3b32a7f Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Thu, 5 Nov 2009 11:57:07 -0500 Subject: drm/radeon/kms: initial mode validation support Signed-off-by: Alex Deucher Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/radeon_connectors.c | 48 +++++++++++++++++++++++++++++- 1 file changed, 47 insertions(+), 1 deletion(-) (limited to 'drivers/gpu/drm/radeon') diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c index fb4d9184704..fce4c4087fd 100644 --- a/drivers/gpu/drm/radeon/radeon_connectors.c +++ b/drivers/gpu/drm/radeon/radeon_connectors.c @@ -397,6 +397,30 @@ static int radeon_lvds_get_modes(struct drm_connector *connector) static int radeon_lvds_mode_valid(struct drm_connector *connector, struct drm_display_mode *mode) { + struct drm_encoder *encoder = radeon_best_single_encoder(connector); + + if ((mode->hdisplay < 320) || (mode->vdisplay < 240)) + return MODE_PANEL; + + if (encoder) { + struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); + struct drm_display_mode *native_mode = &radeon_encoder->native_mode; + + /* AVIVO hardware supports downscaling modes larger than the panel + * to the panel size, but I'm not sure this is desirable. + */ + if ((mode->hdisplay > native_mode->hdisplay) || + (mode->vdisplay > native_mode->vdisplay)) + return MODE_PANEL; + + /* if scaling is disabled, block non-native modes */ + if (radeon_encoder->rmx_type == RMX_OFF) { + if ((mode->hdisplay != native_mode->hdisplay) || + (mode->vdisplay != native_mode->vdisplay)) + return MODE_PANEL; + } + } + return MODE_OK; } @@ -512,6 +536,8 @@ static int radeon_vga_get_modes(struct drm_connector *connector) static int radeon_vga_mode_valid(struct drm_connector *connector, struct drm_display_mode *mode) { + /* XXX check mode bandwidth */ + /* XXX verify against max DAC output frequency */ return MODE_OK; } @@ -609,6 +635,8 @@ static int radeon_tv_get_modes(struct drm_connector *connector) static int radeon_tv_mode_valid(struct drm_connector *connector, struct drm_display_mode *mode) { + if ((mode->hdisplay > 1024) || (mode->vdisplay > 768)) + return MODE_CLOCK_RANGE; return MODE_OK; } @@ -801,9 +829,27 @@ static void radeon_dvi_force(struct drm_connector *connector) radeon_connector->use_digital = true; } +static int radeon_dvi_mode_valid(struct drm_connector *connector, + struct drm_display_mode *mode) +{ + struct radeon_connector *radeon_connector = to_radeon_connector(connector); + + /* XXX check mode bandwidth */ + + if (radeon_connector->use_digital && (mode->clock > 165000)) { + if ((radeon_connector->connector_object_id == CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_I) || + (radeon_connector->connector_object_id == CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_D) || + (radeon_connector->connector_object_id == CONNECTOR_OBJECT_ID_HDMI_TYPE_B)) + return MODE_OK; + else + return MODE_CLOCK_HIGH; + } + return MODE_OK; +} + struct drm_connector_helper_funcs radeon_dvi_connector_helper_funcs = { .get_modes = radeon_dvi_get_modes, - .mode_valid = radeon_vga_mode_valid, + .mode_valid = radeon_dvi_mode_valid, .best_encoder = radeon_dvi_encoder, }; -- cgit v1.2.3