aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpu/drm/drm_crtc.c1
-rw-r--r--drivers/gpu/drm/drm_fb_helper.c196
-rw-r--r--drivers/gpu/drm/i915/intel_fb.c1
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_fbcon.c2
-rw-r--r--drivers/gpu/drm/radeon/radeon_connectors.c50
-rw-r--r--drivers/gpu/drm/radeon/radeon_fb.c5
6 files changed, 121 insertions, 134 deletions
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index 6a472d534522..e8cd6832f08e 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -493,7 +493,6 @@ void drm_connector_cleanup(struct drm_connector *connector)
493 list_for_each_entry_safe(mode, t, &connector->user_modes, head) 493 list_for_each_entry_safe(mode, t, &connector->user_modes, head)
494 drm_mode_remove(connector, mode); 494 drm_mode_remove(connector, mode);
495 495
496 kfree(connector->fb_helper_private);
497 mutex_lock(&dev->mode_config.mutex); 496 mutex_lock(&dev->mode_config.mutex);
498 drm_mode_object_put(dev, &connector->base); 497 drm_mode_object_put(dev, &connector->base);
499 list_del(&connector->head); 498 list_del(&connector->head);
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
diff --git a/drivers/gpu/drm/i915/intel_fb.c b/drivers/gpu/drm/i915/intel_fb.c
index ff6912edf0c6..8f7a7c476098 100644
--- a/drivers/gpu/drm/i915/intel_fb.c
+++ b/drivers/gpu/drm/i915/intel_fb.c
@@ -249,6 +249,7 @@ int intel_fbdev_init(struct drm_device *dev)
249 249
250 drm_fb_helper_init_crtc_count(dev, &ifbdev->helper, 2, 250 drm_fb_helper_init_crtc_count(dev, &ifbdev->helper, 2,
251 INTELFB_CONN_LIMIT); 251 INTELFB_CONN_LIMIT);
252 drm_fb_helper_single_add_all_connectors(&ifbdev->helper);
252 ifbdev->helper.fb_probe = intel_fb_find_or_create_single; 253 ifbdev->helper.fb_probe = intel_fb_find_or_create_single;
253 drm_fb_helper_initial_config(&ifbdev->helper); 254 drm_fb_helper_initial_config(&ifbdev->helper);
254 intelfb_probe(ifbdev); 255 intelfb_probe(ifbdev);
diff --git a/drivers/gpu/drm/nouveau/nouveau_fbcon.c b/drivers/gpu/drm/nouveau/nouveau_fbcon.c
index 90843b62d9b1..fd5d3cde0a07 100644
--- a/drivers/gpu/drm/nouveau/nouveau_fbcon.c
+++ b/drivers/gpu/drm/nouveau/nouveau_fbcon.c
@@ -435,6 +435,8 @@ int nouveau_fbcon_init(struct drm_device *dev)
435 drm_fb_helper_init_crtc_count(dev, &nfbdev->helper, 435 drm_fb_helper_init_crtc_count(dev, &nfbdev->helper,
436 2, 4); 436 2, 4);
437 nfbdev->helper.fb_probe = nouveau_fbcon_find_or_create_single; 437 nfbdev->helper.fb_probe = nouveau_fbcon_find_or_create_single;
438 drm_fb_helper_single_add_all_connectors(&nfbdev->helper);
439
438 drm_fb_helper_initial_config(&nfbdev->helper); 440 drm_fb_helper_initial_config(&nfbdev->helper);
439 nouveau_fbcon_probe(nfbdev); 441 nouveau_fbcon_probe(nfbdev);
440 return 0; 442 return 0;
diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c
index 3fba50540f72..47bd98521bec 100644
--- a/drivers/gpu/drm/radeon/radeon_connectors.c
+++ b/drivers/gpu/drm/radeon/radeon_connectors.c
@@ -1032,7 +1032,6 @@ radeon_add_atom_connector(struct drm_device *dev,
1032 struct radeon_connector_atom_dig *radeon_dig_connector; 1032 struct radeon_connector_atom_dig *radeon_dig_connector;
1033 uint32_t subpixel_order = SubPixelNone; 1033 uint32_t subpixel_order = SubPixelNone;
1034 bool shared_ddc = false; 1034 bool shared_ddc = false;
1035 int ret;
1036 1035
1037 /* fixme - tv/cv/din */ 1036 /* fixme - tv/cv/din */
1038 if (connector_type == DRM_MODE_CONNECTOR_Unknown) 1037 if (connector_type == DRM_MODE_CONNECTOR_Unknown)
@@ -1067,9 +1066,7 @@ radeon_add_atom_connector(struct drm_device *dev,
1067 switch (connector_type) { 1066 switch (connector_type) {
1068 case DRM_MODE_CONNECTOR_VGA: 1067 case DRM_MODE_CONNECTOR_VGA:
1069 drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type); 1068 drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type);
1070 ret = drm_connector_helper_add(&radeon_connector->base, &radeon_vga_connector_helper_funcs); 1069 drm_connector_helper_add(&radeon_connector->base, &radeon_vga_connector_helper_funcs);
1071 if (ret)
1072 goto failed;
1073 if (i2c_bus->valid) { 1070 if (i2c_bus->valid) {
1074 radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "VGA"); 1071 radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "VGA");
1075 if (!radeon_connector->ddc_bus) 1072 if (!radeon_connector->ddc_bus)
@@ -1082,9 +1079,7 @@ radeon_add_atom_connector(struct drm_device *dev,
1082 break; 1079 break;
1083 case DRM_MODE_CONNECTOR_DVIA: 1080 case DRM_MODE_CONNECTOR_DVIA:
1084 drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type); 1081 drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type);
1085 ret = drm_connector_helper_add(&radeon_connector->base, &radeon_vga_connector_helper_funcs); 1082 drm_connector_helper_add(&radeon_connector->base, &radeon_vga_connector_helper_funcs);
1086 if (ret)
1087 goto failed;
1088 if (i2c_bus->valid) { 1083 if (i2c_bus->valid) {
1089 radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "DVI"); 1084 radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "DVI");
1090 if (!radeon_connector->ddc_bus) 1085 if (!radeon_connector->ddc_bus)
@@ -1104,9 +1099,7 @@ radeon_add_atom_connector(struct drm_device *dev,
1104 radeon_dig_connector->igp_lane_info = igp_lane_info; 1099 radeon_dig_connector->igp_lane_info = igp_lane_info;
1105 radeon_connector->con_priv = radeon_dig_connector; 1100 radeon_connector->con_priv = radeon_dig_connector;
1106 drm_connector_init(dev, &radeon_connector->base, &radeon_dvi_connector_funcs, connector_type); 1101 drm_connector_init(dev, &radeon_connector->base, &radeon_dvi_connector_funcs, connector_type);
1107 ret = drm_connector_helper_add(&radeon_connector->base, &radeon_dvi_connector_helper_funcs); 1102 drm_connector_helper_add(&radeon_connector->base, &radeon_dvi_connector_helper_funcs);
1108 if (ret)
1109 goto failed;
1110 if (i2c_bus->valid) { 1103 if (i2c_bus->valid) {
1111 radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "DVI"); 1104 radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "DVI");
1112 if (!radeon_connector->ddc_bus) 1105 if (!radeon_connector->ddc_bus)
@@ -1132,9 +1125,7 @@ radeon_add_atom_connector(struct drm_device *dev,
1132 radeon_dig_connector->igp_lane_info = igp_lane_info; 1125 radeon_dig_connector->igp_lane_info = igp_lane_info;
1133 radeon_connector->con_priv = radeon_dig_connector; 1126 radeon_connector->con_priv = radeon_dig_connector;
1134 drm_connector_init(dev, &radeon_connector->base, &radeon_dvi_connector_funcs, connector_type); 1127 drm_connector_init(dev, &radeon_connector->base, &radeon_dvi_connector_funcs, connector_type);
1135 ret = drm_connector_helper_add(&radeon_connector->base, &radeon_dvi_connector_helper_funcs); 1128 drm_connector_helper_add(&radeon_connector->base, &radeon_dvi_connector_helper_funcs);
1136 if (ret)
1137 goto failed;
1138 if (i2c_bus->valid) { 1129 if (i2c_bus->valid) {
1139 radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "HDMI"); 1130 radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "HDMI");
1140 if (!radeon_connector->ddc_bus) 1131 if (!radeon_connector->ddc_bus)
@@ -1154,9 +1145,7 @@ radeon_add_atom_connector(struct drm_device *dev,
1154 radeon_dig_connector->igp_lane_info = igp_lane_info; 1145 radeon_dig_connector->igp_lane_info = igp_lane_info;
1155 radeon_connector->con_priv = radeon_dig_connector; 1146 radeon_connector->con_priv = radeon_dig_connector;
1156 drm_connector_init(dev, &radeon_connector->base, &radeon_dp_connector_funcs, connector_type); 1147 drm_connector_init(dev, &radeon_connector->base, &radeon_dp_connector_funcs, connector_type);
1157 ret = drm_connector_helper_add(&radeon_connector->base, &radeon_dp_connector_helper_funcs); 1148 drm_connector_helper_add(&radeon_connector->base, &radeon_dp_connector_helper_funcs);
1158 if (ret)
1159 goto failed;
1160 if (i2c_bus->valid) { 1149 if (i2c_bus->valid) {
1161 /* add DP i2c bus */ 1150 /* add DP i2c bus */
1162 if (connector_type == DRM_MODE_CONNECTOR_eDP) 1151 if (connector_type == DRM_MODE_CONNECTOR_eDP)
@@ -1182,9 +1171,7 @@ radeon_add_atom_connector(struct drm_device *dev,
1182 case DRM_MODE_CONNECTOR_9PinDIN: 1171 case DRM_MODE_CONNECTOR_9PinDIN:
1183 if (radeon_tv == 1) { 1172 if (radeon_tv == 1) {
1184 drm_connector_init(dev, &radeon_connector->base, &radeon_tv_connector_funcs, connector_type); 1173 drm_connector_init(dev, &radeon_connector->base, &radeon_tv_connector_funcs, connector_type);
1185 ret = drm_connector_helper_add(&radeon_connector->base, &radeon_tv_connector_helper_funcs); 1174 drm_connector_helper_add(&radeon_connector->base, &radeon_tv_connector_helper_funcs);
1186 if (ret)
1187 goto failed;
1188 radeon_connector->dac_load_detect = true; 1175 radeon_connector->dac_load_detect = true;
1189 drm_connector_attach_property(&radeon_connector->base, 1176 drm_connector_attach_property(&radeon_connector->base,
1190 rdev->mode_info.load_detect_property, 1177 rdev->mode_info.load_detect_property,
@@ -1202,9 +1189,7 @@ radeon_add_atom_connector(struct drm_device *dev,
1202 radeon_dig_connector->igp_lane_info = igp_lane_info; 1189 radeon_dig_connector->igp_lane_info = igp_lane_info;
1203 radeon_connector->con_priv = radeon_dig_connector; 1190 radeon_connector->con_priv = radeon_dig_connector;
1204 drm_connector_init(dev, &radeon_connector->base, &radeon_lvds_connector_funcs, connector_type); 1191 drm_connector_init(dev, &radeon_connector->base, &radeon_lvds_connector_funcs, connector_type);
1205 ret = drm_connector_helper_add(&radeon_connector->base, &radeon_lvds_connector_helper_funcs); 1192 drm_connector_helper_add(&radeon_connector->base, &radeon_lvds_connector_helper_funcs);
1206 if (ret)
1207 goto failed;
1208 if (i2c_bus->valid) { 1193 if (i2c_bus->valid) {
1209 radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "LVDS"); 1194 radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "LVDS");
1210 if (!radeon_connector->ddc_bus) 1195 if (!radeon_connector->ddc_bus)
@@ -1241,7 +1226,6 @@ radeon_add_legacy_connector(struct drm_device *dev,
1241 struct drm_connector *connector; 1226 struct drm_connector *connector;
1242 struct radeon_connector *radeon_connector; 1227 struct radeon_connector *radeon_connector;
1243 uint32_t subpixel_order = SubPixelNone; 1228 uint32_t subpixel_order = SubPixelNone;
1244 int ret;
1245 1229
1246 /* fixme - tv/cv/din */ 1230 /* fixme - tv/cv/din */
1247 if (connector_type == DRM_MODE_CONNECTOR_Unknown) 1231 if (connector_type == DRM_MODE_CONNECTOR_Unknown)
@@ -1269,9 +1253,7 @@ radeon_add_legacy_connector(struct drm_device *dev,
1269 switch (connector_type) { 1253 switch (connector_type) {
1270 case DRM_MODE_CONNECTOR_VGA: 1254 case DRM_MODE_CONNECTOR_VGA:
1271 drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type); 1255 drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type);
1272 ret = drm_connector_helper_add(&radeon_connector->base, &radeon_vga_connector_helper_funcs); 1256 drm_connector_helper_add(&radeon_connector->base, &radeon_vga_connector_helper_funcs);
1273 if (ret)
1274 goto failed;
1275 if (i2c_bus->valid) { 1257 if (i2c_bus->valid) {
1276 radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "VGA"); 1258 radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "VGA");
1277 if (!radeon_connector->ddc_bus) 1259 if (!radeon_connector->ddc_bus)
@@ -1284,9 +1266,7 @@ radeon_add_legacy_connector(struct drm_device *dev,
1284 break; 1266 break;
1285 case DRM_MODE_CONNECTOR_DVIA: 1267 case DRM_MODE_CONNECTOR_DVIA:
1286 drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type); 1268 drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type);
1287 ret = drm_connector_helper_add(&radeon_connector->base, &radeon_vga_connector_helper_funcs); 1269 drm_connector_helper_add(&radeon_connector->base, &radeon_vga_connector_helper_funcs);
1288 if (ret)
1289 goto failed;
1290 if (i2c_bus->valid) { 1270 if (i2c_bus->valid) {
1291 radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "DVI"); 1271 radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "DVI");
1292 if (!radeon_connector->ddc_bus) 1272 if (!radeon_connector->ddc_bus)
@@ -1300,9 +1280,7 @@ radeon_add_legacy_connector(struct drm_device *dev,
1300 case DRM_MODE_CONNECTOR_DVII: 1280 case DRM_MODE_CONNECTOR_DVII:
1301 case DRM_MODE_CONNECTOR_DVID: 1281 case DRM_MODE_CONNECTOR_DVID:
1302 drm_connector_init(dev, &radeon_connector->base, &radeon_dvi_connector_funcs, connector_type); 1282 drm_connector_init(dev, &radeon_connector->base, &radeon_dvi_connector_funcs, connector_type);
1303 ret = drm_connector_helper_add(&radeon_connector->base, &radeon_dvi_connector_helper_funcs); 1283 drm_connector_helper_add(&radeon_connector->base, &radeon_dvi_connector_helper_funcs);
1304 if (ret)
1305 goto failed;
1306 if (i2c_bus->valid) { 1284 if (i2c_bus->valid) {
1307 radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "DVI"); 1285 radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "DVI");
1308 if (!radeon_connector->ddc_bus) 1286 if (!radeon_connector->ddc_bus)
@@ -1319,9 +1297,7 @@ radeon_add_legacy_connector(struct drm_device *dev,
1319 case DRM_MODE_CONNECTOR_9PinDIN: 1297 case DRM_MODE_CONNECTOR_9PinDIN:
1320 if (radeon_tv == 1) { 1298 if (radeon_tv == 1) {
1321 drm_connector_init(dev, &radeon_connector->base, &radeon_tv_connector_funcs, connector_type); 1299 drm_connector_init(dev, &radeon_connector->base, &radeon_tv_connector_funcs, connector_type);
1322 ret = drm_connector_helper_add(&radeon_connector->base, &radeon_tv_connector_helper_funcs); 1300 drm_connector_helper_add(&radeon_connector->base, &radeon_tv_connector_helper_funcs);
1323 if (ret)
1324 goto failed;
1325 radeon_connector->dac_load_detect = true; 1301 radeon_connector->dac_load_detect = true;
1326 /* RS400,RC410,RS480 chipset seems to report a lot 1302 /* RS400,RC410,RS480 chipset seems to report a lot
1327 * of false positive on load detect, we haven't yet 1303 * of false positive on load detect, we haven't yet
@@ -1340,9 +1316,7 @@ radeon_add_legacy_connector(struct drm_device *dev,
1340 break; 1316 break;
1341 case DRM_MODE_CONNECTOR_LVDS: 1317 case DRM_MODE_CONNECTOR_LVDS:
1342 drm_connector_init(dev, &radeon_connector->base, &radeon_lvds_connector_funcs, connector_type); 1318 drm_connector_init(dev, &radeon_connector->base, &radeon_lvds_connector_funcs, connector_type);
1343 ret = drm_connector_helper_add(&radeon_connector->base, &radeon_lvds_connector_helper_funcs); 1319 drm_connector_helper_add(&radeon_connector->base, &radeon_lvds_connector_helper_funcs);
1344 if (ret)
1345 goto failed;
1346 if (i2c_bus->valid) { 1320 if (i2c_bus->valid) {
1347 radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "LVDS"); 1321 radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "LVDS");
1348 if (!radeon_connector->ddc_bus) 1322 if (!radeon_connector->ddc_bus)
diff --git a/drivers/gpu/drm/radeon/radeon_fb.c b/drivers/gpu/drm/radeon/radeon_fb.c
index 705425defba0..7275b2e09444 100644
--- a/drivers/gpu/drm/radeon/radeon_fb.c
+++ b/drivers/gpu/drm/radeon/radeon_fb.c
@@ -274,8 +274,6 @@ out_unref:
274 drm_framebuffer_cleanup(fb); 274 drm_framebuffer_cleanup(fb);
275 kfree(fb); 275 kfree(fb);
276 } 276 }
277
278out:
279 return ret; 277 return ret;
280} 278}
281 279
@@ -380,6 +378,9 @@ int radeon_fbdev_init(struct radeon_device *rdev)
380 rdev->num_crtc, 378 rdev->num_crtc,
381 RADEONFB_CONN_LIMIT); 379 RADEONFB_CONN_LIMIT);
382 rfbdev->helper.fb_probe = radeon_fb_find_or_create_single; 380 rfbdev->helper.fb_probe = radeon_fb_find_or_create_single;
381
382 drm_fb_helper_single_add_all_connectors(&rfbdev->helper);
383
383 drm_fb_helper_initial_config(&rfbdev->helper); 384 drm_fb_helper_initial_config(&rfbdev->helper);
384 radeonfb_probe(rfbdev); 385 radeonfb_probe(rfbdev);
385 return 0; 386 return 0;