aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/drm_fb_helper.c
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2010-03-30 01:34:15 -0400
committerDave Airlie <airlied@redhat.com>2010-04-06 20:28:01 -0400
commit0b4c0f3f0eceacb691e2b5570d9b16d751ce1b48 (patch)
tree708eecc3e3b86f4328df588400e2b7a3f6f2b32d /drivers/gpu/drm/drm_fb_helper.c
parent8be48d924c307e72e3797ab5bde81b07a1ccc52d (diff)
drm/kms/fb: separate fbdev connector list from core drm connectors
This breaks the connection between the core drm connector list and the fbdev connector usage, and allows them to become disjoint in the future. It also removes the untype void* that was in the connector struct to support this. All connectors are added to the fbdev now but this could be changed in the future. Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/drm_fb_helper.c')
-rw-r--r--drivers/gpu/drm/drm_fb_helper.c196
1 files changed, 103 insertions, 93 deletions
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c
index 2515563063ce..9808f6e37a9d 100644
--- a/drivers/gpu/drm/drm_fb_helper.c
+++ b/drivers/gpu/drm/drm_fb_helper.c
@@ -41,15 +41,33 @@ MODULE_LICENSE("GPL and additional rights");
41 41
42static LIST_HEAD(kernel_fb_helper_list); 42static LIST_HEAD(kernel_fb_helper_list);
43 43
44int drm_fb_helper_add_connector(struct drm_connector *connector) 44/* simple single crtc case helper function */
45int drm_fb_helper_single_add_all_connectors(struct drm_fb_helper *fb_helper)
45{ 46{
46 connector->fb_helper_private = kzalloc(sizeof(struct drm_fb_helper_connector), GFP_KERNEL); 47 struct drm_device *dev = fb_helper->dev;
47 if (!connector->fb_helper_private) 48 struct drm_connector *connector;
48 return -ENOMEM; 49 int i;
50
51 list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
52 struct drm_fb_helper_connector *fb_helper_connector;
53
54 fb_helper_connector = kzalloc(sizeof(struct drm_fb_helper_connector), GFP_KERNEL);
55 if (!fb_helper_connector)
56 goto fail;
49 57
58 fb_helper_connector->connector = connector;
59 fb_helper->connector_info[fb_helper->connector_count++] = fb_helper_connector;
60 }
50 return 0; 61 return 0;
62fail:
63 for (i = 0; i < fb_helper->connector_count; i++) {
64 kfree(fb_helper->connector_info[i]);
65 fb_helper->connector_info[i] = NULL;
66 }
67 fb_helper->connector_count = 0;
68 return -ENOMEM;
51} 69}
52EXPORT_SYMBOL(drm_fb_helper_add_connector); 70EXPORT_SYMBOL(drm_fb_helper_single_add_all_connectors);
53 71
54/** 72/**
55 * drm_fb_helper_connector_parse_command_line - parse command line for connector 73 * drm_fb_helper_connector_parse_command_line - parse command line for connector
@@ -64,7 +82,7 @@ EXPORT_SYMBOL(drm_fb_helper_add_connector);
64 * 82 *
65 * enable/enable Digital/disable bit at the end 83 * enable/enable Digital/disable bit at the end
66 */ 84 */
67static bool drm_fb_helper_connector_parse_command_line(struct drm_connector *connector, 85static bool drm_fb_helper_connector_parse_command_line(struct drm_fb_helper_connector *fb_helper_conn,
68 const char *mode_option) 86 const char *mode_option)
69{ 87{
70 const char *name; 88 const char *name;
@@ -74,13 +92,13 @@ static bool drm_fb_helper_connector_parse_command_line(struct drm_connector *con
74 int yres_specified = 0, cvt = 0, rb = 0, interlace = 0, margins = 0; 92 int yres_specified = 0, cvt = 0, rb = 0, interlace = 0, margins = 0;
75 int i; 93 int i;
76 enum drm_connector_force force = DRM_FORCE_UNSPECIFIED; 94 enum drm_connector_force force = DRM_FORCE_UNSPECIFIED;
77 struct drm_fb_helper_connector *fb_help_conn = connector->fb_helper_private;
78 struct drm_fb_helper_cmdline_mode *cmdline_mode; 95 struct drm_fb_helper_cmdline_mode *cmdline_mode;
96 struct drm_connector *connector = fb_helper_conn->connector;
79 97
80 if (!fb_help_conn) 98 if (!fb_helper_conn)
81 return false; 99 return false;
82 100
83 cmdline_mode = &fb_help_conn->cmdline_mode; 101 cmdline_mode = &fb_helper_conn->cmdline_mode;
84 if (!mode_option) 102 if (!mode_option)
85 mode_option = fb_mode_option; 103 mode_option = fb_mode_option;
86 104
@@ -203,18 +221,21 @@ done:
203 return true; 221 return true;
204} 222}
205 223
206int drm_fb_helper_parse_command_line(struct drm_device *dev) 224static int drm_fb_helper_parse_command_line(struct drm_fb_helper *fb_helper)
207{ 225{
208 struct drm_connector *connector; 226 struct drm_fb_helper_connector *fb_helper_conn;
227 int i;
209 228
210 list_for_each_entry(connector, &dev->mode_config.connector_list, head) { 229 for (i = 0; i < fb_helper->connector_count; i++) {
211 char *option = NULL; 230 char *option = NULL;
212 231
232 fb_helper_conn = fb_helper->connector_info[i];
233
213 /* do something on return - turn off connector maybe */ 234 /* do something on return - turn off connector maybe */
214 if (fb_get_options(drm_get_connector_name(connector), &option)) 235 if (fb_get_options(drm_get_connector_name(fb_helper_conn->connector), &option))
215 continue; 236 continue;
216 237
217 drm_fb_helper_connector_parse_command_line(connector, option); 238 drm_fb_helper_connector_parse_command_line(fb_helper_conn, option);
218 } 239 }
219 return 0; 240 return 0;
220} 241}
@@ -391,6 +412,9 @@ static void drm_fb_helper_crtc_free(struct drm_fb_helper *helper)
391{ 412{
392 int i; 413 int i;
393 414
415 for (i = 0; i < helper->connector_count; i++)
416 kfree(helper->connector_info[i]);
417 kfree(helper->connector_info);
394 for (i = 0; i < helper->crtc_count; i++) 418 for (i = 0; i < helper->crtc_count; i++)
395 kfree(helper->crtc_info[i].mode_set.connectors); 419 kfree(helper->crtc_info[i].mode_set.connectors);
396 kfree(helper->crtc_info); 420 kfree(helper->crtc_info);
@@ -411,6 +435,13 @@ int drm_fb_helper_init_crtc_count(struct drm_device *dev,
411 return -ENOMEM; 435 return -ENOMEM;
412 helper->crtc_count = crtc_count; 436 helper->crtc_count = crtc_count;
413 437
438 helper->connector_info = kcalloc(dev->mode_config.num_connector, sizeof(struct drm_fb_helper_connector *), GFP_KERNEL);
439 if (!helper->connector_info) {
440 kfree(helper->crtc_info);
441 return -ENOMEM;
442 }
443 helper->connector_count = 0;
444
414 for (i = 0; i < crtc_count; i++) { 445 for (i = 0; i < crtc_count; i++) {
415 helper->crtc_info[i].mode_set.connectors = 446 helper->crtc_info[i].mode_set.connectors =
416 kcalloc(max_conn_count, 447 kcalloc(max_conn_count,
@@ -672,14 +703,10 @@ int drm_fb_helper_set_par(struct fb_info *info)
672 mutex_lock(&dev->mode_config.mutex); 703 mutex_lock(&dev->mode_config.mutex);
673 for (i = 0; i < fb_helper->crtc_count; i++) { 704 for (i = 0; i < fb_helper->crtc_count; i++) {
674 crtc = fb_helper->crtc_info[i].mode_set.crtc; 705 crtc = fb_helper->crtc_info[i].mode_set.crtc;
675 706 ret = crtc->funcs->set_config(&fb_helper->crtc_info[i].mode_set);
676 if (crtc->fb != fb_helper->crtc_info[i].mode_set.fb) { 707 if (ret) {
677 ret = crtc->funcs->set_config(&fb_helper->crtc_info[i].mode_set); 708 mutex_unlock(&dev->mode_config.mutex);
678 709 return ret;
679 if (ret) {
680 mutex_unlock(&dev->mode_config.mutex);
681 return ret;
682 }
683 } 710 }
684 } 711 }
685 mutex_unlock(&dev->mode_config.mutex); 712 mutex_unlock(&dev->mode_config.mutex);
@@ -722,8 +749,6 @@ EXPORT_SYMBOL(drm_fb_helper_pan_display);
722int drm_fb_helper_single_fb_probe(struct drm_fb_helper *fb_helper, 749int drm_fb_helper_single_fb_probe(struct drm_fb_helper *fb_helper,
723 int preferred_bpp) 750 int preferred_bpp)
724{ 751{
725 struct drm_device *dev = fb_helper->dev;
726 struct drm_connector *connector;
727 int new_fb = 0; 752 int new_fb = 0;
728 int crtc_count = 0; 753 int crtc_count = 0;
729 int ret, i; 754 int ret, i;
@@ -743,14 +768,11 @@ int drm_fb_helper_single_fb_probe(struct drm_fb_helper *fb_helper,
743 sizes.surface_depth = sizes.surface_bpp = preferred_bpp; 768 sizes.surface_depth = sizes.surface_bpp = preferred_bpp;
744 } 769 }
745 /* first up get a count of crtcs now in use and new min/maxes width/heights */ 770 /* first up get a count of crtcs now in use and new min/maxes width/heights */
746 list_for_each_entry(connector, &dev->mode_config.connector_list, head) { 771 for (i = 0; i < fb_helper->connector_count; i++) {
747 struct drm_fb_helper_connector *fb_help_conn = connector->fb_helper_private; 772 struct drm_fb_helper_connector *fb_helper_conn = fb_helper->connector_info[i];
748 struct drm_fb_helper_cmdline_mode *cmdline_mode; 773 struct drm_fb_helper_cmdline_mode *cmdline_mode;
749 774
750 if (!fb_help_conn) 775 cmdline_mode = &fb_helper_conn->cmdline_mode;
751 continue;
752
753 cmdline_mode = &fb_help_conn->cmdline_mode;
754 776
755 if (cmdline_mode->bpp_specified) { 777 if (cmdline_mode->bpp_specified) {
756 switch (cmdline_mode->bpp) { 778 switch (cmdline_mode->bpp) {
@@ -954,24 +976,27 @@ void drm_fb_helper_fill_var(struct fb_info *info, struct drm_fb_helper *fb_helpe
954} 976}
955EXPORT_SYMBOL(drm_fb_helper_fill_var); 977EXPORT_SYMBOL(drm_fb_helper_fill_var);
956 978
957static int drm_helper_probe_connector_modes(struct drm_device *dev, uint32_t maxX, 979static int drm_fb_helper_probe_connector_modes(struct drm_fb_helper *fb_helper,
958 uint32_t maxY) 980 uint32_t maxX,
981 uint32_t maxY)
959{ 982{
960 struct drm_connector *connector; 983 struct drm_connector *connector;
961 int count = 0; 984 int count = 0;
985 int i;
962 986
963 list_for_each_entry(connector, &dev->mode_config.connector_list, head) { 987 for (i = 0; i < fb_helper->connector_count; i++) {
988 connector = fb_helper->connector_info[i]->connector;
964 count += connector->funcs->fill_modes(connector, maxX, maxY); 989 count += connector->funcs->fill_modes(connector, maxX, maxY);
965 } 990 }
966 991
967 return count; 992 return count;
968} 993}
969 994
970static struct drm_display_mode *drm_has_preferred_mode(struct drm_connector *connector, int width, int height) 995static struct drm_display_mode *drm_has_preferred_mode(struct drm_fb_helper_connector *fb_connector, int width, int height)
971{ 996{
972 struct drm_display_mode *mode; 997 struct drm_display_mode *mode;
973 998
974 list_for_each_entry(mode, &connector->modes, head) { 999 list_for_each_entry(mode, &fb_connector->connector->modes, head) {
975 if (drm_mode_width(mode) > width || 1000 if (drm_mode_width(mode) > width ||
976 drm_mode_height(mode) > height) 1001 drm_mode_height(mode) > height)
977 continue; 1002 continue;
@@ -981,28 +1006,20 @@ static struct drm_display_mode *drm_has_preferred_mode(struct drm_connector *con
981 return NULL; 1006 return NULL;
982} 1007}
983 1008
984static bool drm_has_cmdline_mode(struct drm_connector *connector) 1009static bool drm_has_cmdline_mode(struct drm_fb_helper_connector *fb_connector)
985{ 1010{
986 struct drm_fb_helper_connector *fb_help_conn = connector->fb_helper_private;
987 struct drm_fb_helper_cmdline_mode *cmdline_mode; 1011 struct drm_fb_helper_cmdline_mode *cmdline_mode;
988 1012 cmdline_mode = &fb_connector->cmdline_mode;
989 if (!fb_help_conn)
990 return false;
991
992 cmdline_mode = &fb_help_conn->cmdline_mode;
993 return cmdline_mode->specified; 1013 return cmdline_mode->specified;
994} 1014}
995 1015
996static struct drm_display_mode *drm_pick_cmdline_mode(struct drm_connector *connector, int width, int height) 1016static struct drm_display_mode *drm_pick_cmdline_mode(struct drm_fb_helper_connector *fb_helper_conn,
1017 int width, int height)
997{ 1018{
998 struct drm_fb_helper_connector *fb_help_conn = connector->fb_helper_private;
999 struct drm_fb_helper_cmdline_mode *cmdline_mode; 1019 struct drm_fb_helper_cmdline_mode *cmdline_mode;
1000 struct drm_display_mode *mode = NULL; 1020 struct drm_display_mode *mode = NULL;
1001 1021
1002 if (!fb_help_conn) 1022 cmdline_mode = &fb_helper_conn->cmdline_mode;
1003 return mode;
1004
1005 cmdline_mode = &fb_help_conn->cmdline_mode;
1006 if (cmdline_mode->specified == false) 1023 if (cmdline_mode->specified == false)
1007 return mode; 1024 return mode;
1008 1025
@@ -1012,7 +1029,7 @@ static struct drm_display_mode *drm_pick_cmdline_mode(struct drm_connector *conn
1012 if (cmdline_mode->rb || cmdline_mode->margins) 1029 if (cmdline_mode->rb || cmdline_mode->margins)
1013 goto create_mode; 1030 goto create_mode;
1014 1031
1015 list_for_each_entry(mode, &connector->modes, head) { 1032 list_for_each_entry(mode, &fb_helper_conn->connector->modes, head) {
1016 /* check width/height */ 1033 /* check width/height */
1017 if (mode->hdisplay != cmdline_mode->xres || 1034 if (mode->hdisplay != cmdline_mode->xres ||
1018 mode->vdisplay != cmdline_mode->yres) 1035 mode->vdisplay != cmdline_mode->yres)
@@ -1031,13 +1048,13 @@ static struct drm_display_mode *drm_pick_cmdline_mode(struct drm_connector *conn
1031 } 1048 }
1032 1049
1033create_mode: 1050create_mode:
1034 mode = drm_cvt_mode(connector->dev, cmdline_mode->xres, 1051 mode = drm_cvt_mode(fb_helper_conn->connector->dev, cmdline_mode->xres,
1035 cmdline_mode->yres, 1052 cmdline_mode->yres,
1036 cmdline_mode->refresh_specified ? cmdline_mode->refresh : 60, 1053 cmdline_mode->refresh_specified ? cmdline_mode->refresh : 60,
1037 cmdline_mode->rb, cmdline_mode->interlace, 1054 cmdline_mode->rb, cmdline_mode->interlace,
1038 cmdline_mode->margins); 1055 cmdline_mode->margins);
1039 drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V); 1056 drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V);
1040 list_add(&mode->head, &connector->modes); 1057 list_add(&mode->head, &fb_helper_conn->connector->modes);
1041 return mode; 1058 return mode;
1042} 1059}
1043 1060
@@ -1053,62 +1070,60 @@ static bool drm_connector_enabled(struct drm_connector *connector, bool strict)
1053 return enable; 1070 return enable;
1054} 1071}
1055 1072
1056static void drm_enable_connectors(struct drm_device *dev, bool *enabled) 1073static void drm_enable_connectors(struct drm_fb_helper *fb_helper,
1074 bool *enabled)
1057{ 1075{
1058 bool any_enabled = false; 1076 bool any_enabled = false;
1059 struct drm_connector *connector; 1077 struct drm_connector *connector;
1060 int i = 0; 1078 int i = 0;
1061 1079
1062 list_for_each_entry(connector, &dev->mode_config.connector_list, head) { 1080 for (i = 0; i < fb_helper->connector_count; i++) {
1081 connector = fb_helper->connector_info[i]->connector;
1063 enabled[i] = drm_connector_enabled(connector, true); 1082 enabled[i] = drm_connector_enabled(connector, true);
1064 DRM_DEBUG_KMS("connector %d enabled? %s\n", connector->base.id, 1083 DRM_DEBUG_KMS("connector %d enabled? %s\n", connector->base.id,
1065 enabled[i] ? "yes" : "no"); 1084 enabled[i] ? "yes" : "no");
1066 any_enabled |= enabled[i]; 1085 any_enabled |= enabled[i];
1067 i++;
1068 } 1086 }
1069 1087
1070 if (any_enabled) 1088 if (any_enabled)
1071 return; 1089 return;
1072 1090
1073 i = 0; 1091 for (i = 0; i < fb_helper->connector_count; i++) {
1074 list_for_each_entry(connector, &dev->mode_config.connector_list, head) { 1092 connector = fb_helper->connector_info[i]->connector;
1075 enabled[i] = drm_connector_enabled(connector, false); 1093 enabled[i] = drm_connector_enabled(connector, false);
1076 i++;
1077 } 1094 }
1078} 1095}
1079 1096
1080static bool drm_target_preferred(struct drm_device *dev, 1097static bool drm_target_preferred(struct drm_fb_helper *fb_helper,
1081 struct drm_display_mode **modes, 1098 struct drm_display_mode **modes,
1082 bool *enabled, int width, int height) 1099 bool *enabled, int width, int height)
1083{ 1100{
1084 struct drm_connector *connector; 1101 struct drm_fb_helper_connector *fb_helper_conn;
1085 int i = 0; 1102 int i;
1086 1103
1087 list_for_each_entry(connector, &dev->mode_config.connector_list, head) { 1104 for (i = 0; i < fb_helper->connector_count; i++) {
1105 fb_helper_conn = fb_helper->connector_info[i];
1088 1106
1089 if (enabled[i] == false) { 1107 if (enabled[i] == false)
1090 i++;
1091 continue; 1108 continue;
1092 }
1093 1109
1094 DRM_DEBUG_KMS("looking for cmdline mode on connector %d\n", 1110 DRM_DEBUG_KMS("looking for cmdline mode on connector %d\n",
1095 connector->base.id); 1111 fb_helper_conn->connector->base.id);
1096 1112
1097 /* got for command line mode first */ 1113 /* got for command line mode first */
1098 modes[i] = drm_pick_cmdline_mode(connector, width, height); 1114 modes[i] = drm_pick_cmdline_mode(fb_helper_conn, width, height);
1099 if (!modes[i]) { 1115 if (!modes[i]) {
1100 DRM_DEBUG_KMS("looking for preferred mode on connector %d\n", 1116 DRM_DEBUG_KMS("looking for preferred mode on connector %d\n",
1101 connector->base.id); 1117 fb_helper_conn->connector->base.id);
1102 modes[i] = drm_has_preferred_mode(connector, width, height); 1118 modes[i] = drm_has_preferred_mode(fb_helper_conn, width, height);
1103 } 1119 }
1104 /* No preferred modes, pick one off the list */ 1120 /* No preferred modes, pick one off the list */
1105 if (!modes[i] && !list_empty(&connector->modes)) { 1121 if (!modes[i] && !list_empty(&fb_helper_conn->connector->modes)) {
1106 list_for_each_entry(modes[i], &connector->modes, head) 1122 list_for_each_entry(modes[i], &fb_helper_conn->connector->modes, head)
1107 break; 1123 break;
1108 } 1124 }
1109 DRM_DEBUG_KMS("found mode %s\n", modes[i] ? modes[i]->name : 1125 DRM_DEBUG_KMS("found mode %s\n", modes[i] ? modes[i]->name :
1110 "none"); 1126 "none");
1111 i++;
1112 } 1127 }
1113 return true; 1128 return true;
1114} 1129}
@@ -1126,15 +1141,13 @@ static int drm_pick_crtcs(struct drm_fb_helper *fb_helper,
1126 struct drm_fb_helper_crtc *best_crtc; 1141 struct drm_fb_helper_crtc *best_crtc;
1127 int my_score, best_score, score; 1142 int my_score, best_score, score;
1128 struct drm_fb_helper_crtc **crtcs, *crtc; 1143 struct drm_fb_helper_crtc **crtcs, *crtc;
1144 struct drm_fb_helper_connector *fb_helper_conn;
1129 1145
1130 if (n == fb_helper->dev->mode_config.num_connector) 1146 if (n == fb_helper->connector_count)
1131 return 0; 1147 return 0;
1132 c = 0; 1148
1133 list_for_each_entry(connector, &dev->mode_config.connector_list, head) { 1149 fb_helper_conn = fb_helper->connector_info[n];
1134 if (c == n) 1150 connector = fb_helper_conn->connector;
1135 break;
1136 c++;
1137 }
1138 1151
1139 best_crtcs[n] = NULL; 1152 best_crtcs[n] = NULL;
1140 best_crtc = NULL; 1153 best_crtc = NULL;
@@ -1150,9 +1163,9 @@ static int drm_pick_crtcs(struct drm_fb_helper *fb_helper,
1150 my_score = 1; 1163 my_score = 1;
1151 if (connector->status == connector_status_connected) 1164 if (connector->status == connector_status_connected)
1152 my_score++; 1165 my_score++;
1153 if (drm_has_cmdline_mode(connector)) 1166 if (drm_has_cmdline_mode(fb_helper_conn))
1154 my_score++; 1167 my_score++;
1155 if (drm_has_preferred_mode(connector, width, height)) 1168 if (drm_has_preferred_mode(fb_helper_conn, width, height))
1156 my_score++; 1169 my_score++;
1157 1170
1158 connector_funcs = connector->helper_private; 1171 connector_funcs = connector->helper_private;
@@ -1201,7 +1214,6 @@ static void drm_setup_crtcs(struct drm_fb_helper *fb_helper)
1201 struct drm_fb_helper_crtc **crtcs; 1214 struct drm_fb_helper_crtc **crtcs;
1202 struct drm_display_mode **modes; 1215 struct drm_display_mode **modes;
1203 struct drm_encoder *encoder; 1216 struct drm_encoder *encoder;
1204 struct drm_connector *connector;
1205 struct drm_mode_set *modeset; 1217 struct drm_mode_set *modeset;
1206 bool *enabled; 1218 bool *enabled;
1207 int width, height; 1219 int width, height;
@@ -1224,9 +1236,9 @@ static void drm_setup_crtcs(struct drm_fb_helper *fb_helper)
1224 enabled = kcalloc(dev->mode_config.num_connector, 1236 enabled = kcalloc(dev->mode_config.num_connector,
1225 sizeof(bool), GFP_KERNEL); 1237 sizeof(bool), GFP_KERNEL);
1226 1238
1227 drm_enable_connectors(dev, enabled); 1239 drm_enable_connectors(fb_helper, enabled);
1228 1240
1229 ret = drm_target_preferred(dev, modes, enabled, width, height); 1241 ret = drm_target_preferred(fb_helper, modes, enabled, width, height);
1230 if (!ret) 1242 if (!ret)
1231 DRM_ERROR("Unable to find initial modes\n"); 1243 DRM_ERROR("Unable to find initial modes\n");
1232 1244
@@ -1241,8 +1253,7 @@ static void drm_setup_crtcs(struct drm_fb_helper *fb_helper)
1241 modeset->num_connectors = 0; 1253 modeset->num_connectors = 0;
1242 } 1254 }
1243 1255
1244 i = 0; 1256 for (i = 0; i < fb_helper->connector_count; i++) {
1245 list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
1246 struct drm_display_mode *mode = modes[i]; 1257 struct drm_display_mode *mode = modes[i];
1247 struct drm_fb_helper_crtc *fb_crtc = crtcs[i]; 1258 struct drm_fb_helper_crtc *fb_crtc = crtcs[i];
1248 modeset = &fb_crtc->mode_set; 1259 modeset = &fb_crtc->mode_set;
@@ -1255,9 +1266,8 @@ static void drm_setup_crtcs(struct drm_fb_helper *fb_helper)
1255 drm_mode_destroy(dev, modeset->mode); 1266 drm_mode_destroy(dev, modeset->mode);
1256 modeset->mode = drm_mode_duplicate(dev, 1267 modeset->mode = drm_mode_duplicate(dev,
1257 fb_crtc->desired_mode); 1268 fb_crtc->desired_mode);
1258 modeset->connectors[modeset->num_connectors++] = connector; 1269 modeset->connectors[modeset->num_connectors++] = fb_helper->connector_info[i]->connector;
1259 } 1270 }
1260 i++;
1261 } 1271 }
1262 1272
1263 kfree(crtcs); 1273 kfree(crtcs);
@@ -1287,11 +1297,11 @@ bool drm_fb_helper_initial_config(struct drm_fb_helper *fb_helper)
1287 /* disable all the possible outputs/crtcs before entering KMS mode */ 1297 /* disable all the possible outputs/crtcs before entering KMS mode */
1288 drm_helper_disable_unused_functions(fb_helper->dev); 1298 drm_helper_disable_unused_functions(fb_helper->dev);
1289 1299
1290 drm_fb_helper_parse_command_line(fb_helper->dev); 1300 drm_fb_helper_parse_command_line(fb_helper);
1291 1301
1292 count = drm_helper_probe_connector_modes(dev, 1302 count = drm_fb_helper_probe_connector_modes(fb_helper,
1293 dev->mode_config.max_width, 1303 dev->mode_config.max_width,
1294 dev->mode_config.max_height); 1304 dev->mode_config.max_height);
1295 1305
1296 /* 1306 /*
1297 * we shouldn't end up with no modes here. 1307 * we shouldn't end up with no modes here.
@@ -1310,8 +1320,8 @@ bool drm_helper_fb_hotplug_event(struct drm_fb_helper *fb_helper,
1310{ 1320{
1311 DRM_DEBUG_KMS("\n"); 1321 DRM_DEBUG_KMS("\n");
1312 1322
1313 drm_helper_probe_connector_modes(fb_helper->dev, max_width, 1323 drm_fb_helper_probe_connector_modes(fb_helper, max_width,
1314 max_height); 1324 max_height);
1315 1325
1316 drm_setup_crtcs(fb_helper); 1326 drm_setup_crtcs(fb_helper);
1317 1327