diff options
Diffstat (limited to 'drivers/gpu/drm/drm_fb_helper.c')
-rw-r--r-- | drivers/gpu/drm/drm_fb_helper.c | 196 |
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 | ||
42 | static LIST_HEAD(kernel_fb_helper_list); | 42 | static LIST_HEAD(kernel_fb_helper_list); |
43 | 43 | ||
44 | int drm_fb_helper_add_connector(struct drm_connector *connector) | 44 | /* simple single crtc case helper function */ |
45 | int 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; |
62 | fail: | ||
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 | } |
52 | EXPORT_SYMBOL(drm_fb_helper_add_connector); | 70 | EXPORT_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 | */ |
67 | static bool drm_fb_helper_connector_parse_command_line(struct drm_connector *connector, | 85 | static 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 | ||
206 | int drm_fb_helper_parse_command_line(struct drm_device *dev) | 224 | static 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); | |||
722 | int drm_fb_helper_single_fb_probe(struct drm_fb_helper *fb_helper, | 749 | int 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 | } |
955 | EXPORT_SYMBOL(drm_fb_helper_fill_var); | 977 | EXPORT_SYMBOL(drm_fb_helper_fill_var); |
956 | 978 | ||
957 | static int drm_helper_probe_connector_modes(struct drm_device *dev, uint32_t maxX, | 979 | static 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 | ||
970 | static struct drm_display_mode *drm_has_preferred_mode(struct drm_connector *connector, int width, int height) | 995 | static 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 | ||
984 | static bool drm_has_cmdline_mode(struct drm_connector *connector) | 1009 | static 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 | ||
996 | static struct drm_display_mode *drm_pick_cmdline_mode(struct drm_connector *connector, int width, int height) | 1016 | static 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 | ||
1033 | create_mode: | 1050 | create_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 | ||
1056 | static void drm_enable_connectors(struct drm_device *dev, bool *enabled) | 1073 | static 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 | ||
1080 | static bool drm_target_preferred(struct drm_device *dev, | 1097 | static 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 | ||