aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/drm/Kconfig1
-rw-r--r--drivers/gpu/drm/drm_crtc.c55
-rw-r--r--drivers/gpu/drm/drm_fb_helper.c64
-rw-r--r--drivers/gpu/drm/drm_modes.c1
-rw-r--r--drivers/gpu/drm/drm_probe_helper.c17
-rw-r--r--drivers/gpu/drm/mgag200/mgag200_mode.c21
-rw-r--r--include/drm/drm_crtc.h1
-rw-r--r--include/drm/drm_fb_helper.h1
8 files changed, 83 insertions, 78 deletions
diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
index 31894c8c1773..367f5dd23291 100644
--- a/drivers/gpu/drm/Kconfig
+++ b/drivers/gpu/drm/Kconfig
@@ -8,6 +8,7 @@ menuconfig DRM
8 tristate "Direct Rendering Manager (XFree86 4.1.0 and higher DRI support)" 8 tristate "Direct Rendering Manager (XFree86 4.1.0 and higher DRI support)"
9 depends on (AGP || AGP=n) && !EMULATED_CMPXCHG && MMU && HAS_DMA 9 depends on (AGP || AGP=n) && !EMULATED_CMPXCHG && MMU && HAS_DMA
10 select HDMI 10 select HDMI
11 select FB_CMDLINE
11 select I2C 12 select I2C
12 select I2C_ALGOBIT 13 select I2C_ALGOBIT
13 select DMA_SHARED_BUFFER 14 select DMA_SHARED_BUFFER
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index 33ff631c8d23..66d3bfb8d264 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -863,6 +863,59 @@ static void drm_mode_remove(struct drm_connector *connector,
863} 863}
864 864
865/** 865/**
866 * drm_connector_get_cmdline_mode - reads the user's cmdline mode
867 * @connector: connector to quwery
868 * @mode: returned mode
869 *
870 * The kernel supports per-connector configration of its consoles through
871 * use of the video= parameter. This function parses that option and
872 * extracts the user's specified mode (or enable/disable status) for a
873 * particular connector. This is typically only used during the early fbdev
874 * setup.
875 */
876static void drm_connector_get_cmdline_mode(struct drm_connector *connector)
877{
878 struct drm_cmdline_mode *mode = &connector->cmdline_mode;
879 char *option = NULL;
880
881 if (fb_get_options(connector->name, &option))
882 return;
883
884 if (!drm_mode_parse_command_line_for_connector(option,
885 connector,
886 mode))
887 return;
888
889 if (mode->force) {
890 const char *s;
891
892 switch (mode->force) {
893 case DRM_FORCE_OFF:
894 s = "OFF";
895 break;
896 case DRM_FORCE_ON_DIGITAL:
897 s = "ON - dig";
898 break;
899 default:
900 case DRM_FORCE_ON:
901 s = "ON";
902 break;
903 }
904
905 DRM_INFO("forcing %s connector %s\n", connector->name, s);
906 connector->force = mode->force;
907 }
908
909 DRM_DEBUG_KMS("cmdline mode for connector %s %dx%d@%dHz%s%s%s\n",
910 connector->name,
911 mode->xres, mode->yres,
912 mode->refresh_specified ? mode->refresh : 60,
913 mode->rb ? " reduced blanking" : "",
914 mode->margins ? " with margins" : "",
915 mode->interlace ? " interlaced" : "");
916}
917
918/**
866 * drm_connector_init - Init a preallocated connector 919 * drm_connector_init - Init a preallocated connector
867 * @dev: DRM device 920 * @dev: DRM device
868 * @connector: the connector to init 921 * @connector: the connector to init
@@ -914,6 +967,8 @@ int drm_connector_init(struct drm_device *dev,
914 connector->edid_blob_ptr = NULL; 967 connector->edid_blob_ptr = NULL;
915 connector->status = connector_status_unknown; 968 connector->status = connector_status_unknown;
916 969
970 drm_connector_get_cmdline_mode(connector);
971
917 list_add_tail(&connector->head, &dev->mode_config.connector_list); 972 list_add_tail(&connector->head, &dev->mode_config.connector_list);
918 dev->mode_config.num_connector++; 973 dev->mode_config.num_connector++;
919 974
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c
index 3144db9dc0f1..3a6b6635e3f5 100644
--- a/drivers/gpu/drm/drm_fb_helper.c
+++ b/drivers/gpu/drm/drm_fb_helper.c
@@ -171,60 +171,6 @@ int drm_fb_helper_remove_one_connector(struct drm_fb_helper *fb_helper,
171} 171}
172EXPORT_SYMBOL(drm_fb_helper_remove_one_connector); 172EXPORT_SYMBOL(drm_fb_helper_remove_one_connector);
173 173
174static int drm_fb_helper_parse_command_line(struct drm_fb_helper *fb_helper)
175{
176 struct drm_fb_helper_connector *fb_helper_conn;
177 int i;
178
179 for (i = 0; i < fb_helper->connector_count; i++) {
180 struct drm_cmdline_mode *mode;
181 struct drm_connector *connector;
182 char *option = NULL;
183
184 fb_helper_conn = fb_helper->connector_info[i];
185 connector = fb_helper_conn->connector;
186 mode = &fb_helper_conn->cmdline_mode;
187
188 /* do something on return - turn off connector maybe */
189 if (fb_get_options(connector->name, &option))
190 continue;
191
192 if (drm_mode_parse_command_line_for_connector(option,
193 connector,
194 mode)) {
195 if (mode->force) {
196 const char *s;
197 switch (mode->force) {
198 case DRM_FORCE_OFF:
199 s = "OFF";
200 break;
201 case DRM_FORCE_ON_DIGITAL:
202 s = "ON - dig";
203 break;
204 default:
205 case DRM_FORCE_ON:
206 s = "ON";
207 break;
208 }
209
210 DRM_INFO("forcing %s connector %s\n",
211 connector->name, s);
212 connector->force = mode->force;
213 }
214
215 DRM_DEBUG_KMS("cmdline mode for connector %s %dx%d@%dHz%s%s%s\n",
216 connector->name,
217 mode->xres, mode->yres,
218 mode->refresh_specified ? mode->refresh : 60,
219 mode->rb ? " reduced blanking" : "",
220 mode->margins ? " with margins" : "",
221 mode->interlace ? " interlaced" : "");
222 }
223
224 }
225 return 0;
226}
227
228static void drm_fb_helper_save_lut_atomic(struct drm_crtc *crtc, struct drm_fb_helper *helper) 174static void drm_fb_helper_save_lut_atomic(struct drm_crtc *crtc, struct drm_fb_helper *helper)
229{ 175{
230 uint16_t *r_base, *g_base, *b_base; 176 uint16_t *r_base, *g_base, *b_base;
@@ -1013,7 +959,7 @@ static int drm_fb_helper_single_fb_probe(struct drm_fb_helper *fb_helper,
1013 struct drm_fb_helper_connector *fb_helper_conn = fb_helper->connector_info[i]; 959 struct drm_fb_helper_connector *fb_helper_conn = fb_helper->connector_info[i];
1014 struct drm_cmdline_mode *cmdline_mode; 960 struct drm_cmdline_mode *cmdline_mode;
1015 961
1016 cmdline_mode = &fb_helper_conn->cmdline_mode; 962 cmdline_mode = &fb_helper_conn->connector->cmdline_mode;
1017 963
1018 if (cmdline_mode->bpp_specified) { 964 if (cmdline_mode->bpp_specified) {
1019 switch (cmdline_mode->bpp) { 965 switch (cmdline_mode->bpp) {
@@ -1260,9 +1206,7 @@ EXPORT_SYMBOL(drm_has_preferred_mode);
1260 1206
1261static bool drm_has_cmdline_mode(struct drm_fb_helper_connector *fb_connector) 1207static bool drm_has_cmdline_mode(struct drm_fb_helper_connector *fb_connector)
1262{ 1208{
1263 struct drm_cmdline_mode *cmdline_mode; 1209 return fb_connector->connector->cmdline_mode.specified;
1264 cmdline_mode = &fb_connector->cmdline_mode;
1265 return cmdline_mode->specified;
1266} 1210}
1267 1211
1268struct drm_display_mode *drm_pick_cmdline_mode(struct drm_fb_helper_connector *fb_helper_conn, 1212struct drm_display_mode *drm_pick_cmdline_mode(struct drm_fb_helper_connector *fb_helper_conn,
@@ -1272,7 +1216,7 @@ struct drm_display_mode *drm_pick_cmdline_mode(struct drm_fb_helper_connector *f
1272 struct drm_display_mode *mode = NULL; 1216 struct drm_display_mode *mode = NULL;
1273 bool prefer_non_interlace; 1217 bool prefer_non_interlace;
1274 1218
1275 cmdline_mode = &fb_helper_conn->cmdline_mode; 1219 cmdline_mode = &fb_helper_conn->connector->cmdline_mode;
1276 if (cmdline_mode->specified == false) 1220 if (cmdline_mode->specified == false)
1277 return mode; 1221 return mode;
1278 1222
@@ -1657,8 +1601,6 @@ bool drm_fb_helper_initial_config(struct drm_fb_helper *fb_helper, int bpp_sel)
1657 struct drm_device *dev = fb_helper->dev; 1601 struct drm_device *dev = fb_helper->dev;
1658 int count = 0; 1602 int count = 0;
1659 1603
1660 drm_fb_helper_parse_command_line(fb_helper);
1661
1662 mutex_lock(&dev->mode_config.mutex); 1604 mutex_lock(&dev->mode_config.mutex);
1663 count = drm_fb_helper_probe_connector_modes(fb_helper, 1605 count = drm_fb_helper_probe_connector_modes(fb_helper,
1664 dev->mode_config.max_width, 1606 dev->mode_config.max_width,
diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c
index bedf1894e17e..d1b7d2006529 100644
--- a/drivers/gpu/drm/drm_modes.c
+++ b/drivers/gpu/drm/drm_modes.c
@@ -1259,6 +1259,7 @@ drm_mode_create_from_cmdline_mode(struct drm_device *dev,
1259 if (!mode) 1259 if (!mode)
1260 return NULL; 1260 return NULL;
1261 1261
1262 mode->type |= DRM_MODE_TYPE_USERDEF;
1262 drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V); 1263 drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V);
1263 return mode; 1264 return mode;
1264} 1265}
diff --git a/drivers/gpu/drm/drm_probe_helper.c b/drivers/gpu/drm/drm_probe_helper.c
index db7d250f7ac7..6857e9ad6339 100644
--- a/drivers/gpu/drm/drm_probe_helper.c
+++ b/drivers/gpu/drm/drm_probe_helper.c
@@ -82,6 +82,22 @@ static void drm_mode_validate_flag(struct drm_connector *connector,
82 return; 82 return;
83} 83}
84 84
85static int drm_helper_probe_add_cmdline_mode(struct drm_connector *connector)
86{
87 struct drm_display_mode *mode;
88
89 if (!connector->cmdline_mode.specified)
90 return 0;
91
92 mode = drm_mode_create_from_cmdline_mode(connector->dev,
93 &connector->cmdline_mode);
94 if (mode == NULL)
95 return 0;
96
97 drm_mode_probed_add(connector, mode);
98 return 1;
99}
100
85static int drm_helper_probe_single_connector_modes_merge_bits(struct drm_connector *connector, 101static int drm_helper_probe_single_connector_modes_merge_bits(struct drm_connector *connector,
86 uint32_t maxX, uint32_t maxY, bool merge_type_bits) 102 uint32_t maxX, uint32_t maxY, bool merge_type_bits)
87{ 103{
@@ -141,6 +157,7 @@ static int drm_helper_probe_single_connector_modes_merge_bits(struct drm_connect
141 157
142 if (count == 0 && connector->status == connector_status_connected) 158 if (count == 0 && connector->status == connector_status_connected)
143 count = drm_add_modes_noedid(connector, 1024, 768); 159 count = drm_add_modes_noedid(connector, 1024, 768);
160 count += drm_helper_probe_add_cmdline_mode(connector);
144 if (count == 0) 161 if (count == 0)
145 goto prune; 162 goto prune;
146 163
diff --git a/drivers/gpu/drm/mgag200/mgag200_mode.c b/drivers/gpu/drm/mgag200/mgag200_mode.c
index 45f04dea0ac2..83485ab81ce8 100644
--- a/drivers/gpu/drm/mgag200/mgag200_mode.c
+++ b/drivers/gpu/drm/mgag200/mgag200_mode.c
@@ -1483,11 +1483,7 @@ static int mga_vga_mode_valid(struct drm_connector *connector,
1483{ 1483{
1484 struct drm_device *dev = connector->dev; 1484 struct drm_device *dev = connector->dev;
1485 struct mga_device *mdev = (struct mga_device*)dev->dev_private; 1485 struct mga_device *mdev = (struct mga_device*)dev->dev_private;
1486 struct mga_fbdev *mfbdev = mdev->mfbdev;
1487 struct drm_fb_helper *fb_helper = &mfbdev->helper;
1488 struct drm_fb_helper_connector *fb_helper_conn = NULL;
1489 int bpp = 32; 1486 int bpp = 32;
1490 int i = 0;
1491 1487
1492 if (IS_G200_SE(mdev)) { 1488 if (IS_G200_SE(mdev)) {
1493 if (mdev->unique_rev_id == 0x01) { 1489 if (mdev->unique_rev_id == 0x01) {
@@ -1537,21 +1533,14 @@ static int mga_vga_mode_valid(struct drm_connector *connector,
1537 } 1533 }
1538 1534
1539 /* Validate the mode input by the user */ 1535 /* Validate the mode input by the user */
1540 for (i = 0; i < fb_helper->connector_count; i++) { 1536 if (connector->cmdline_mode.specified) {
1541 if (fb_helper->connector_info[i]->connector == connector) { 1537 if (connector->cmdline_mode.bpp_specified)
1542 /* Found the helper for this connector */ 1538 bpp = connector->cmdline_mode.bpp;
1543 fb_helper_conn = fb_helper->connector_info[i];
1544 if (fb_helper_conn->cmdline_mode.specified) {
1545 if (fb_helper_conn->cmdline_mode.bpp_specified) {
1546 bpp = fb_helper_conn->cmdline_mode.bpp;
1547 }
1548 }
1549 }
1550 } 1539 }
1551 1540
1552 if ((mode->hdisplay * mode->vdisplay * (bpp/8)) > mdev->mc.vram_size) { 1541 if ((mode->hdisplay * mode->vdisplay * (bpp/8)) > mdev->mc.vram_size) {
1553 if (fb_helper_conn) 1542 if (connector->cmdline_mode.specified)
1554 fb_helper_conn->cmdline_mode.specified = false; 1543 connector->cmdline_mode.specified = false;
1555 return MODE_BAD; 1544 return MODE_BAD;
1556 } 1545 }
1557 1546
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index f1105d0da059..c530b4920a09 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -548,6 +548,7 @@ struct drm_connector {
548 void *helper_private; 548 void *helper_private;
549 549
550 /* forced on connector */ 550 /* forced on connector */
551 struct drm_cmdline_mode cmdline_mode;
551 enum drm_connector_force force; 552 enum drm_connector_force force;
552 bool override_edid; 553 bool override_edid;
553 uint32_t encoder_ids[DRM_CONNECTOR_MAX_ENCODER]; 554 uint32_t encoder_ids[DRM_CONNECTOR_MAX_ENCODER];
diff --git a/include/drm/drm_fb_helper.h b/include/drm/drm_fb_helper.h
index bfd329d613c4..f4ad254e3488 100644
--- a/include/drm/drm_fb_helper.h
+++ b/include/drm/drm_fb_helper.h
@@ -77,7 +77,6 @@ struct drm_fb_helper_funcs {
77 77
78struct drm_fb_helper_connector { 78struct drm_fb_helper_connector {
79 struct drm_connector *connector; 79 struct drm_connector *connector;
80 struct drm_cmdline_mode cmdline_mode;
81}; 80};
82 81
83struct drm_fb_helper { 82struct drm_fb_helper {