aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu
diff options
context:
space:
mode:
authorAlex Deucher <alexdeucher@gmail.com>2010-11-08 11:08:29 -0500
committerDave Airlie <airlied@redhat.com>2010-11-08 22:43:32 -0500
commitfb939dfcf2a3a70357000617799925b6a11f9348 (patch)
tree7b307b6edbd6e6c6f7b8a93a9fc95e1d87abcc8f /drivers/gpu
parentdccb2a952b1f0b51978fcb3f9899c7f46ffd4b28 (diff)
drm/radeon/kms: add support for clock/data path routers
This is a follow on to: 26b5bc986423cf3887e09188cb662ed651c5374d (drm/radeon/kms: add support for router objects) That patch added support for systems that use a mux to control the ddc line routing between the connectors. This patch adds support for systems that use a mux to control the encoder clock and data path routing to the connectors. Should fix: https://bugs.freedesktop.org/show_bug.cgi?id=31339 Signed-off-by: Alex Deucher <alexdeucher@gmail.com> Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/drm/radeon/radeon_atombios.c26
-rw-r--r--drivers/gpu/drm/radeon/radeon_connectors.c4
-rw-r--r--drivers/gpu/drm/radeon/radeon_display.c18
-rw-r--r--drivers/gpu/drm/radeon/radeon_encoders.c8
-rw-r--r--drivers/gpu/drm/radeon/radeon_i2c.c41
-rw-r--r--drivers/gpu/drm/radeon/radeon_mode.h17
6 files changed, 85 insertions, 29 deletions
diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c
index 04cac7ec9039..a1de975eec30 100644
--- a/drivers/gpu/drm/radeon/radeon_atombios.c
+++ b/drivers/gpu/drm/radeon/radeon_atombios.c
@@ -526,7 +526,8 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev)
526 if (crev < 2) 526 if (crev < 2)
527 return false; 527 return false;
528 528
529 router.valid = false; 529 router.ddc_valid = false;
530 router.cd_valid = false;
530 531
531 obj_header = (ATOM_OBJECT_HEADER *) (ctx->bios + data_offset); 532 obj_header = (ATOM_OBJECT_HEADER *) (ctx->bios + data_offset);
532 path_obj = (ATOM_DISPLAY_OBJECT_PATH_TABLE *) 533 path_obj = (ATOM_DISPLAY_OBJECT_PATH_TABLE *)
@@ -647,7 +648,8 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev)
647 usDeviceTag)); 648 usDeviceTag));
648 649
649 } else if (grph_obj_type == GRAPH_OBJECT_TYPE_ROUTER) { 650 } else if (grph_obj_type == GRAPH_OBJECT_TYPE_ROUTER) {
650 router.valid = false; 651 router.ddc_valid = false;
652 router.cd_valid = false;
651 for (k = 0; k < router_obj->ucNumberOfObjects; k++) { 653 for (k = 0; k < router_obj->ucNumberOfObjects; k++) {
652 u16 router_obj_id = le16_to_cpu(router_obj->asObjects[j].usObjectID); 654 u16 router_obj_id = le16_to_cpu(router_obj->asObjects[j].usObjectID);
653 if (le16_to_cpu(path->usGraphicObjIds[j]) == router_obj_id) { 655 if (le16_to_cpu(path->usGraphicObjIds[j]) == router_obj_id) {
@@ -657,6 +659,7 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev)
657 ATOM_I2C_RECORD *i2c_record; 659 ATOM_I2C_RECORD *i2c_record;
658 ATOM_I2C_ID_CONFIG_ACCESS *i2c_config; 660 ATOM_I2C_ID_CONFIG_ACCESS *i2c_config;
659 ATOM_ROUTER_DDC_PATH_SELECT_RECORD *ddc_path; 661 ATOM_ROUTER_DDC_PATH_SELECT_RECORD *ddc_path;
662 ATOM_ROUTER_DATA_CLOCK_PATH_SELECT_RECORD *cd_path;
660 ATOM_SRC_DST_TABLE_FOR_ONE_OBJECT *router_src_dst_table = 663 ATOM_SRC_DST_TABLE_FOR_ONE_OBJECT *router_src_dst_table =
661 (ATOM_SRC_DST_TABLE_FOR_ONE_OBJECT *) 664 (ATOM_SRC_DST_TABLE_FOR_ONE_OBJECT *)
662 (ctx->bios + data_offset + 665 (ctx->bios + data_offset +
@@ -690,10 +693,18 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev)
690 case ATOM_ROUTER_DDC_PATH_SELECT_RECORD_TYPE: 693 case ATOM_ROUTER_DDC_PATH_SELECT_RECORD_TYPE:
691 ddc_path = (ATOM_ROUTER_DDC_PATH_SELECT_RECORD *) 694 ddc_path = (ATOM_ROUTER_DDC_PATH_SELECT_RECORD *)
692 record; 695 record;
693 router.valid = true; 696 router.ddc_valid = true;
694 router.mux_type = ddc_path->ucMuxType; 697 router.ddc_mux_type = ddc_path->ucMuxType;
695 router.mux_control_pin = ddc_path->ucMuxControlPin; 698 router.ddc_mux_control_pin = ddc_path->ucMuxControlPin;
696 router.mux_state = ddc_path->ucMuxState[enum_id]; 699 router.ddc_mux_state = ddc_path->ucMuxState[enum_id];
700 break;
701 case ATOM_ROUTER_DATA_CLOCK_PATH_SELECT_RECORD_TYPE:
702 cd_path = (ATOM_ROUTER_DATA_CLOCK_PATH_SELECT_RECORD *)
703 record;
704 router.cd_valid = true;
705 router.cd_mux_type = cd_path->ucMuxType;
706 router.cd_mux_control_pin = cd_path->ucMuxControlPin;
707 router.cd_mux_state = cd_path->ucMuxState[enum_id];
697 break; 708 break;
698 } 709 }
699 record = (ATOM_COMMON_RECORD_HEADER *) 710 record = (ATOM_COMMON_RECORD_HEADER *)
@@ -860,7 +871,8 @@ bool radeon_get_atom_connector_info_from_supported_devices_table(struct
860 size_t bc_size = sizeof(*bios_connectors) * ATOM_MAX_SUPPORTED_DEVICE; 871 size_t bc_size = sizeof(*bios_connectors) * ATOM_MAX_SUPPORTED_DEVICE;
861 struct radeon_router router; 872 struct radeon_router router;
862 873
863 router.valid = false; 874 router.ddc_valid = false;
875 router.cd_valid = false;
864 876
865 bios_connectors = kzalloc(bc_size, GFP_KERNEL); 877 bios_connectors = kzalloc(bc_size, GFP_KERNEL);
866 if (!bios_connectors) 878 if (!bios_connectors)
diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c
index a9d541534796..fe6c74780f18 100644
--- a/drivers/gpu/drm/radeon/radeon_connectors.c
+++ b/drivers/gpu/drm/radeon/radeon_connectors.c
@@ -1116,7 +1116,7 @@ radeon_add_atom_connector(struct drm_device *dev,
1116 radeon_connector->shared_ddc = true; 1116 radeon_connector->shared_ddc = true;
1117 shared_ddc = true; 1117 shared_ddc = true;
1118 } 1118 }
1119 if (radeon_connector->router_bus && router->valid && 1119 if (radeon_connector->router_bus && router->ddc_valid &&
1120 (radeon_connector->router.router_id == router->router_id)) { 1120 (radeon_connector->router.router_id == router->router_id)) {
1121 radeon_connector->shared_ddc = false; 1121 radeon_connector->shared_ddc = false;
1122 shared_ddc = false; 1122 shared_ddc = false;
@@ -1136,7 +1136,7 @@ radeon_add_atom_connector(struct drm_device *dev,
1136 radeon_connector->connector_object_id = connector_object_id; 1136 radeon_connector->connector_object_id = connector_object_id;
1137 radeon_connector->hpd = *hpd; 1137 radeon_connector->hpd = *hpd;
1138 radeon_connector->router = *router; 1138 radeon_connector->router = *router;
1139 if (router->valid) { 1139 if (router->ddc_valid || router->cd_valid) {
1140 radeon_connector->router_bus = radeon_i2c_lookup(rdev, &router->i2c_info); 1140 radeon_connector->router_bus = radeon_i2c_lookup(rdev, &router->i2c_info);
1141 if (!radeon_connector->router_bus) 1141 if (!radeon_connector->router_bus)
1142 goto failed; 1142 goto failed;
diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c
index 0383631da69c..1df4dc6c063c 100644
--- a/drivers/gpu/drm/radeon/radeon_display.c
+++ b/drivers/gpu/drm/radeon/radeon_display.c
@@ -315,10 +315,14 @@ static void radeon_print_display_setup(struct drm_device *dev)
315 radeon_connector->ddc_bus->rec.en_data_reg, 315 radeon_connector->ddc_bus->rec.en_data_reg,
316 radeon_connector->ddc_bus->rec.y_clk_reg, 316 radeon_connector->ddc_bus->rec.y_clk_reg,
317 radeon_connector->ddc_bus->rec.y_data_reg); 317 radeon_connector->ddc_bus->rec.y_data_reg);
318 if (radeon_connector->router_bus) 318 if (radeon_connector->router.ddc_valid)
319 DRM_INFO(" DDC Router 0x%x/0x%x\n", 319 DRM_INFO(" DDC Router 0x%x/0x%x\n",
320 radeon_connector->router.mux_control_pin, 320 radeon_connector->router.ddc_mux_control_pin,
321 radeon_connector->router.mux_state); 321 radeon_connector->router.ddc_mux_state);
322 if (radeon_connector->router.cd_valid)
323 DRM_INFO(" Clock/Data Router 0x%x/0x%x\n",
324 radeon_connector->router.cd_mux_control_pin,
325 radeon_connector->router.cd_mux_state);
322 } else { 326 } else {
323 if (connector->connector_type == DRM_MODE_CONNECTOR_VGA || 327 if (connector->connector_type == DRM_MODE_CONNECTOR_VGA ||
324 connector->connector_type == DRM_MODE_CONNECTOR_DVII || 328 connector->connector_type == DRM_MODE_CONNECTOR_DVII ||
@@ -398,8 +402,8 @@ int radeon_ddc_get_modes(struct radeon_connector *radeon_connector)
398 int ret = 0; 402 int ret = 0;
399 403
400 /* on hw with routers, select right port */ 404 /* on hw with routers, select right port */
401 if (radeon_connector->router.valid) 405 if (radeon_connector->router.ddc_valid)
402 radeon_router_select_port(radeon_connector); 406 radeon_router_select_ddc_port(radeon_connector);
403 407
404 if ((radeon_connector->base.connector_type == DRM_MODE_CONNECTOR_DisplayPort) || 408 if ((radeon_connector->base.connector_type == DRM_MODE_CONNECTOR_DisplayPort) ||
405 (radeon_connector->base.connector_type == DRM_MODE_CONNECTOR_eDP)) { 409 (radeon_connector->base.connector_type == DRM_MODE_CONNECTOR_eDP)) {
@@ -432,8 +436,8 @@ static int radeon_ddc_dump(struct drm_connector *connector)
432 int ret = 0; 436 int ret = 0;
433 437
434 /* on hw with routers, select right port */ 438 /* on hw with routers, select right port */
435 if (radeon_connector->router.valid) 439 if (radeon_connector->router.ddc_valid)
436 radeon_router_select_port(radeon_connector); 440 radeon_router_select_ddc_port(radeon_connector);
437 441
438 if (!radeon_connector->ddc_bus) 442 if (!radeon_connector->ddc_bus)
439 return -1; 443 return -1;
diff --git a/drivers/gpu/drm/radeon/radeon_encoders.c b/drivers/gpu/drm/radeon/radeon_encoders.c
index b862be61c398..f678257c42e6 100644
--- a/drivers/gpu/drm/radeon/radeon_encoders.c
+++ b/drivers/gpu/drm/radeon/radeon_encoders.c
@@ -1520,6 +1520,7 @@ radeon_atom_dac_detect(struct drm_encoder *encoder, struct drm_connector *connec
1520static void radeon_atom_encoder_prepare(struct drm_encoder *encoder) 1520static void radeon_atom_encoder_prepare(struct drm_encoder *encoder)
1521{ 1521{
1522 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); 1522 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
1523 struct drm_connector *connector = radeon_get_connector_for_encoder(encoder);
1523 1524
1524 if (radeon_encoder->active_device & 1525 if (radeon_encoder->active_device &
1525 (ATOM_DEVICE_DFP_SUPPORT | ATOM_DEVICE_LCD_SUPPORT)) { 1526 (ATOM_DEVICE_DFP_SUPPORT | ATOM_DEVICE_LCD_SUPPORT)) {
@@ -1531,6 +1532,13 @@ static void radeon_atom_encoder_prepare(struct drm_encoder *encoder)
1531 radeon_atom_output_lock(encoder, true); 1532 radeon_atom_output_lock(encoder, true);
1532 radeon_atom_encoder_dpms(encoder, DRM_MODE_DPMS_OFF); 1533 radeon_atom_encoder_dpms(encoder, DRM_MODE_DPMS_OFF);
1533 1534
1535 /* select the clock/data port if it uses a router */
1536 if (connector) {
1537 struct radeon_connector *radeon_connector = to_radeon_connector(connector);
1538 if (radeon_connector->router.cd_valid)
1539 radeon_router_select_cd_port(radeon_connector);
1540 }
1541
1534 /* this is needed for the pll/ss setup to work correctly in some cases */ 1542 /* this is needed for the pll/ss setup to work correctly in some cases */
1535 atombios_set_encoder_crtc_source(encoder); 1543 atombios_set_encoder_crtc_source(encoder);
1536} 1544}
diff --git a/drivers/gpu/drm/radeon/radeon_i2c.c b/drivers/gpu/drm/radeon/radeon_i2c.c
index 6a13ee38a5b9..24b8a8be2cd4 100644
--- a/drivers/gpu/drm/radeon/radeon_i2c.c
+++ b/drivers/gpu/drm/radeon/radeon_i2c.c
@@ -53,8 +53,8 @@ bool radeon_ddc_probe(struct radeon_connector *radeon_connector)
53 }; 53 };
54 54
55 /* on hw with routers, select right port */ 55 /* on hw with routers, select right port */
56 if (radeon_connector->router.valid) 56 if (radeon_connector->router.ddc_valid)
57 radeon_router_select_port(radeon_connector); 57 radeon_router_select_ddc_port(radeon_connector);
58 58
59 ret = i2c_transfer(&radeon_connector->ddc_bus->adapter, msgs, 2); 59 ret = i2c_transfer(&radeon_connector->ddc_bus->adapter, msgs, 2);
60 if (ret == 2) 60 if (ret == 2)
@@ -1084,26 +1084,51 @@ void radeon_i2c_put_byte(struct radeon_i2c_chan *i2c_bus,
1084 addr, val); 1084 addr, val);
1085} 1085}
1086 1086
1087/* router switching */ 1087/* ddc router switching */
1088void radeon_router_select_port(struct radeon_connector *radeon_connector) 1088void radeon_router_select_ddc_port(struct radeon_connector *radeon_connector)
1089{ 1089{
1090 u8 val; 1090 u8 val;
1091 1091
1092 if (!radeon_connector->router.valid) 1092 if (!radeon_connector->router.ddc_valid)
1093 return; 1093 return;
1094 1094
1095 radeon_i2c_get_byte(radeon_connector->router_bus, 1095 radeon_i2c_get_byte(radeon_connector->router_bus,
1096 radeon_connector->router.i2c_addr, 1096 radeon_connector->router.i2c_addr,
1097 0x3, &val); 1097 0x3, &val);
1098 val &= radeon_connector->router.mux_control_pin; 1098 val &= radeon_connector->router.ddc_mux_control_pin;
1099 radeon_i2c_put_byte(radeon_connector->router_bus, 1099 radeon_i2c_put_byte(radeon_connector->router_bus,
1100 radeon_connector->router.i2c_addr, 1100 radeon_connector->router.i2c_addr,
1101 0x3, val); 1101 0x3, val);
1102 radeon_i2c_get_byte(radeon_connector->router_bus, 1102 radeon_i2c_get_byte(radeon_connector->router_bus,
1103 radeon_connector->router.i2c_addr, 1103 radeon_connector->router.i2c_addr,
1104 0x1, &val); 1104 0x1, &val);
1105 val &= radeon_connector->router.mux_control_pin; 1105 val &= radeon_connector->router.ddc_mux_control_pin;
1106 val |= radeon_connector->router.mux_state; 1106 val |= radeon_connector->router.ddc_mux_state;
1107 radeon_i2c_put_byte(radeon_connector->router_bus,
1108 radeon_connector->router.i2c_addr,
1109 0x1, val);
1110}
1111
1112/* clock/data router switching */
1113void radeon_router_select_cd_port(struct radeon_connector *radeon_connector)
1114{
1115 u8 val;
1116
1117 if (!radeon_connector->router.cd_valid)
1118 return;
1119
1120 radeon_i2c_get_byte(radeon_connector->router_bus,
1121 radeon_connector->router.i2c_addr,
1122 0x3, &val);
1123 val &= radeon_connector->router.cd_mux_control_pin;
1124 radeon_i2c_put_byte(radeon_connector->router_bus,
1125 radeon_connector->router.i2c_addr,
1126 0x3, val);
1127 radeon_i2c_get_byte(radeon_connector->router_bus,
1128 radeon_connector->router.i2c_addr,
1129 0x1, &val);
1130 val &= radeon_connector->router.cd_mux_control_pin;
1131 val |= radeon_connector->router.cd_mux_state;
1107 radeon_i2c_put_byte(radeon_connector->router_bus, 1132 radeon_i2c_put_byte(radeon_connector->router_bus,
1108 radeon_connector->router.i2c_addr, 1133 radeon_connector->router.i2c_addr,
1109 0x1, val); 1134 0x1, val);
diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h
index 92457163d070..680f57644e86 100644
--- a/drivers/gpu/drm/radeon/radeon_mode.h
+++ b/drivers/gpu/drm/radeon/radeon_mode.h
@@ -401,13 +401,19 @@ struct radeon_hpd {
401}; 401};
402 402
403struct radeon_router { 403struct radeon_router {
404 bool valid;
405 u32 router_id; 404 u32 router_id;
406 struct radeon_i2c_bus_rec i2c_info; 405 struct radeon_i2c_bus_rec i2c_info;
407 u8 i2c_addr; 406 u8 i2c_addr;
408 u8 mux_type; 407 /* i2c mux */
409 u8 mux_control_pin; 408 bool ddc_valid;
410 u8 mux_state; 409 u8 ddc_mux_type;
410 u8 ddc_mux_control_pin;
411 u8 ddc_mux_state;
412 /* clock/data mux */
413 bool cd_valid;
414 u8 cd_mux_type;
415 u8 cd_mux_control_pin;
416 u8 cd_mux_state;
411}; 417};
412 418
413struct radeon_connector { 419struct radeon_connector {
@@ -488,7 +494,8 @@ extern void radeon_i2c_put_byte(struct radeon_i2c_chan *i2c,
488 u8 slave_addr, 494 u8 slave_addr,
489 u8 addr, 495 u8 addr,
490 u8 val); 496 u8 val);
491extern void radeon_router_select_port(struct radeon_connector *radeon_connector); 497extern void radeon_router_select_ddc_port(struct radeon_connector *radeon_connector);
498extern void radeon_router_select_cd_port(struct radeon_connector *radeon_connector);
492extern bool radeon_ddc_probe(struct radeon_connector *radeon_connector); 499extern bool radeon_ddc_probe(struct radeon_connector *radeon_connector);
493extern int radeon_ddc_get_modes(struct radeon_connector *radeon_connector); 500extern int radeon_ddc_get_modes(struct radeon_connector *radeon_connector);
494 501