aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/drm_crtc_helper.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/drm_crtc_helper.c')
-rw-r--r--drivers/gpu/drm/drm_crtc_helper.c89
1 files changed, 84 insertions, 5 deletions
diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c
index fe8697447f32..bbfd110a7168 100644
--- a/drivers/gpu/drm/drm_crtc_helper.c
+++ b/drivers/gpu/drm/drm_crtc_helper.c
@@ -32,6 +32,7 @@
32#include "drmP.h" 32#include "drmP.h"
33#include "drm_crtc.h" 33#include "drm_crtc.h"
34#include "drm_crtc_helper.h" 34#include "drm_crtc_helper.h"
35#include "drm_fb_helper.h"
35 36
36static void drm_mode_validate_flag(struct drm_connector *connector, 37static void drm_mode_validate_flag(struct drm_connector *connector,
37 int flags) 38 int flags)
@@ -90,7 +91,15 @@ int drm_helper_probe_single_connector_modes(struct drm_connector *connector,
90 list_for_each_entry_safe(mode, t, &connector->modes, head) 91 list_for_each_entry_safe(mode, t, &connector->modes, head)
91 mode->status = MODE_UNVERIFIED; 92 mode->status = MODE_UNVERIFIED;
92 93
93 connector->status = connector->funcs->detect(connector); 94 if (connector->force) {
95 if (connector->force == DRM_FORCE_ON)
96 connector->status = connector_status_connected;
97 else
98 connector->status = connector_status_disconnected;
99 if (connector->funcs->force)
100 connector->funcs->force(connector);
101 } else
102 connector->status = connector->funcs->detect(connector);
94 103
95 if (connector->status == connector_status_disconnected) { 104 if (connector->status == connector_status_disconnected) {
96 DRM_DEBUG_KMS("%s is disconnected\n", 105 DRM_DEBUG_KMS("%s is disconnected\n",
@@ -267,6 +276,66 @@ static struct drm_display_mode *drm_has_preferred_mode(struct drm_connector *con
267 return NULL; 276 return NULL;
268} 277}
269 278
279static bool drm_has_cmdline_mode(struct drm_connector *connector)
280{
281 struct drm_fb_helper_connector *fb_help_conn = connector->fb_helper_private;
282 struct drm_fb_helper_cmdline_mode *cmdline_mode;
283
284 if (!fb_help_conn)
285 return false;
286
287 cmdline_mode = &fb_help_conn->cmdline_mode;
288 return cmdline_mode->specified;
289}
290
291static struct drm_display_mode *drm_pick_cmdline_mode(struct drm_connector *connector, int width, int height)
292{
293 struct drm_fb_helper_connector *fb_help_conn = connector->fb_helper_private;
294 struct drm_fb_helper_cmdline_mode *cmdline_mode;
295 struct drm_display_mode *mode = NULL;
296
297 if (!fb_help_conn)
298 return mode;
299
300 cmdline_mode = &fb_help_conn->cmdline_mode;
301 if (cmdline_mode->specified == false)
302 return mode;
303
304 /* attempt to find a matching mode in the list of modes
305 * we have gotten so far, if not add a CVT mode that conforms
306 */
307 if (cmdline_mode->rb || cmdline_mode->margins)
308 goto create_mode;
309
310 list_for_each_entry(mode, &connector->modes, head) {
311 /* check width/height */
312 if (mode->hdisplay != cmdline_mode->xres ||
313 mode->vdisplay != cmdline_mode->yres)
314 continue;
315
316 if (cmdline_mode->refresh_specified) {
317 if (mode->vrefresh != cmdline_mode->refresh)
318 continue;
319 }
320
321 if (cmdline_mode->interlace) {
322 if (!(mode->flags & DRM_MODE_FLAG_INTERLACE))
323 continue;
324 }
325 return mode;
326 }
327
328create_mode:
329 mode = drm_cvt_mode(connector->dev, cmdline_mode->xres,
330 cmdline_mode->yres,
331 cmdline_mode->refresh_specified ? cmdline_mode->refresh : 60,
332 cmdline_mode->rb, cmdline_mode->interlace,
333 cmdline_mode->margins);
334 drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V);
335 list_add(&mode->head, &connector->modes);
336 return mode;
337}
338
270static bool drm_connector_enabled(struct drm_connector *connector, bool strict) 339static bool drm_connector_enabled(struct drm_connector *connector, bool strict)
271{ 340{
272 bool enable; 341 bool enable;
@@ -317,10 +386,16 @@ static bool drm_target_preferred(struct drm_device *dev,
317 continue; 386 continue;
318 } 387 }
319 388
320 DRM_DEBUG_KMS("looking for preferred mode on connector %d\n", 389 DRM_DEBUG_KMS("looking for cmdline mode on connector %d\n",
321 connector->base.id); 390 connector->base.id);
322 391
323 modes[i] = drm_has_preferred_mode(connector, width, height); 392 /* got for command line mode first */
393 modes[i] = drm_pick_cmdline_mode(connector, width, height);
394 if (!modes[i]) {
395 DRM_DEBUG_KMS("looking for preferred mode on connector %d\n",
396 connector->base.id);
397 modes[i] = drm_has_preferred_mode(connector, width, height);
398 }
324 /* No preferred modes, pick one off the list */ 399 /* No preferred modes, pick one off the list */
325 if (!modes[i] && !list_empty(&connector->modes)) { 400 if (!modes[i] && !list_empty(&connector->modes)) {
326 list_for_each_entry(modes[i], &connector->modes, head) 401 list_for_each_entry(modes[i], &connector->modes, head)
@@ -369,6 +444,8 @@ static int drm_pick_crtcs(struct drm_device *dev,
369 my_score = 1; 444 my_score = 1;
370 if (connector->status == connector_status_connected) 445 if (connector->status == connector_status_connected)
371 my_score++; 446 my_score++;
447 if (drm_has_cmdline_mode(connector))
448 my_score++;
372 if (drm_has_preferred_mode(connector, width, height)) 449 if (drm_has_preferred_mode(connector, width, height))
373 my_score++; 450 my_score++;
374 451
@@ -943,6 +1020,8 @@ bool drm_helper_initial_config(struct drm_device *dev)
943{ 1020{
944 int count = 0; 1021 int count = 0;
945 1022
1023 drm_fb_helper_parse_command_line(dev);
1024
946 count = drm_helper_probe_connector_modes(dev, 1025 count = drm_helper_probe_connector_modes(dev,
947 dev->mode_config.max_width, 1026 dev->mode_config.max_width,
948 dev->mode_config.max_height); 1027 dev->mode_config.max_height);
@@ -950,7 +1029,7 @@ bool drm_helper_initial_config(struct drm_device *dev)
950 /* 1029 /*
951 * we shouldn't end up with no modes here. 1030 * we shouldn't end up with no modes here.
952 */ 1031 */
953 WARN(!count, "Connected connector with 0 modes\n"); 1032 WARN(!count, "No connectors reported connected with modes\n");
954 1033
955 drm_setup_crtcs(dev); 1034 drm_setup_crtcs(dev);
956 1035