aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/fb/modedb.txt21
-rw-r--r--drivers/gpu/drm/drm_modes.c87
2 files changed, 78 insertions, 30 deletions
diff --git a/Documentation/fb/modedb.txt b/Documentation/fb/modedb.txt
index ec4dee75a354..16aa08453911 100644
--- a/Documentation/fb/modedb.txt
+++ b/Documentation/fb/modedb.txt
@@ -20,7 +20,7 @@ in a video= option, fbmem considers that to be a global video mode option.
20 20
21Valid mode specifiers (mode_option argument): 21Valid mode specifiers (mode_option argument):
22 22
23 <xres>x<yres>[M][R][-<bpp>][@<refresh>][i][m] 23 <xres>x<yres>[M][R][-<bpp>][@<refresh>][i][m][eDd]
24 <name>[-<bpp>][@<refresh>] 24 <name>[-<bpp>][@<refresh>]
25 25
26with <xres>, <yres>, <bpp> and <refresh> decimal numbers and <name> a string. 26with <xres>, <yres>, <bpp> and <refresh> decimal numbers and <name> a string.
@@ -36,6 +36,21 @@ pixels and 1.8% of yres).
36 36
37 Sample usage: 1024x768M@60m - CVT timing with margins 37 Sample usage: 1024x768M@60m - CVT timing with margins
38 38
39DRM drivers also add options to enable or disable outputs:
40
41'e' will force the display to be enabled, i.e. it will override the detection
42if a display is connected. 'D' will force the display to be enabled and use
43digital output. This is useful for outputs that have both analog and digital
44signals (e.g. HDMI and DVI-I). For other outputs it behaves like 'e'. If 'd'
45is specified the output is disabled.
46
47You can additionally specify which output the options matches to.
48To force the VGA output to be enabled and drive a specific mode say:
49 video=VGA-1:1280x1024@60me
50
51Specifying the option multiple times for different ports is possible, e.g.:
52 video=LVDS-1:d video=HDMI-1:D
53
39***** oOo ***** oOo ***** oOo ***** oOo ***** oOo ***** oOo ***** oOo ***** 54***** oOo ***** oOo ***** oOo ***** oOo ***** oOo ***** oOo ***** oOo *****
40 55
41What is the VESA(TM) Coordinated Video Timings (CVT)? 56What is the VESA(TM) Coordinated Video Timings (CVT)?
@@ -132,5 +147,5 @@ There may be more modes.
132 tridentfb - Trident (Cyber)blade chipset frame buffer 147 tridentfb - Trident (Cyber)blade chipset frame buffer
133 vt8623fb - VIA 8623 frame buffer 148 vt8623fb - VIA 8623 frame buffer
134 149
135BTW, only a few drivers use this at the moment. Others are to follow 150BTW, only a few fb drivers use this at the moment. Others are to follow
136(feel free to send patches). 151(feel free to send patches). The DRM drivers also support this.
diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c
index c2d32f20e2fb..ad74fb4dc542 100644
--- a/drivers/gpu/drm/drm_modes.c
+++ b/drivers/gpu/drm/drm_modes.c
@@ -994,9 +994,10 @@ bool drm_mode_parse_command_line_for_connector(const char *mode_option,
994{ 994{
995 const char *name; 995 const char *name;
996 unsigned int namelen; 996 unsigned int namelen;
997 int res_specified = 0, bpp_specified = 0, refresh_specified = 0; 997 bool res_specified = false, bpp_specified = false, refresh_specified = false;
998 unsigned int xres = 0, yres = 0, bpp = 32, refresh = 0; 998 unsigned int xres = 0, yres = 0, bpp = 32, refresh = 0;
999 int yres_specified = 0, cvt = 0, rb = 0, interlace = 0, margins = 0; 999 bool yres_specified = false, cvt = false, rb = false;
1000 bool interlace = false, margins = false, was_digit = false;
1000 int i; 1001 int i;
1001 enum drm_connector_force force = DRM_FORCE_UNSPECIFIED; 1002 enum drm_connector_force force = DRM_FORCE_UNSPECIFIED;
1002 1003
@@ -1015,54 +1016,65 @@ bool drm_mode_parse_command_line_for_connector(const char *mode_option,
1015 for (i = namelen-1; i >= 0; i--) { 1016 for (i = namelen-1; i >= 0; i--) {
1016 switch (name[i]) { 1017 switch (name[i]) {
1017 case '@': 1018 case '@':
1018 namelen = i;
1019 if (!refresh_specified && !bpp_specified && 1019 if (!refresh_specified && !bpp_specified &&
1020 !yres_specified) { 1020 !yres_specified && !cvt && !rb && was_digit) {
1021 refresh = simple_strtol(&name[i+1], NULL, 10); 1021 refresh = simple_strtol(&name[i+1], NULL, 10);
1022 refresh_specified = 1; 1022 refresh_specified = true;
1023 if (cvt || rb) 1023 was_digit = false;
1024 cvt = 0;
1025 } else 1024 } else
1026 goto done; 1025 goto done;
1027 break; 1026 break;
1028 case '-': 1027 case '-':
1029 namelen = i; 1028 if (!bpp_specified && !yres_specified && !cvt &&
1030 if (!bpp_specified && !yres_specified) { 1029 !rb && was_digit) {
1031 bpp = simple_strtol(&name[i+1], NULL, 10); 1030 bpp = simple_strtol(&name[i+1], NULL, 10);
1032 bpp_specified = 1; 1031 bpp_specified = true;
1033 if (cvt || rb) 1032 was_digit = false;
1034 cvt = 0;
1035 } else 1033 } else
1036 goto done; 1034 goto done;
1037 break; 1035 break;
1038 case 'x': 1036 case 'x':
1039 if (!yres_specified) { 1037 if (!yres_specified && was_digit) {
1040 yres = simple_strtol(&name[i+1], NULL, 10); 1038 yres = simple_strtol(&name[i+1], NULL, 10);
1041 yres_specified = 1; 1039 yres_specified = true;
1040 was_digit = false;
1042 } else 1041 } else
1043 goto done; 1042 goto done;
1044 case '0' ... '9': 1043 case '0' ... '9':
1044 was_digit = true;
1045 break; 1045 break;
1046 case 'M': 1046 case 'M':
1047 if (!yres_specified) 1047 if (yres_specified || cvt || was_digit)
1048 cvt = 1; 1048 goto done;
1049 cvt = true;
1049 break; 1050 break;
1050 case 'R': 1051 case 'R':
1051 if (cvt) 1052 if (yres_specified || cvt || rb || was_digit)
1052 rb = 1; 1053 goto done;
1054 rb = true;
1053 break; 1055 break;
1054 case 'm': 1056 case 'm':
1055 if (!cvt) 1057 if (cvt || yres_specified || was_digit)
1056 margins = 1; 1058 goto done;
1059 margins = true;
1057 break; 1060 break;
1058 case 'i': 1061 case 'i':
1059 if (!cvt) 1062 if (cvt || yres_specified || was_digit)
1060 interlace = 1; 1063 goto done;
1064 interlace = true;
1061 break; 1065 break;
1062 case 'e': 1066 case 'e':
1067 if (yres_specified || bpp_specified || refresh_specified ||
1068 was_digit || (force != DRM_FORCE_UNSPECIFIED))
1069 goto done;
1070
1063 force = DRM_FORCE_ON; 1071 force = DRM_FORCE_ON;
1064 break; 1072 break;
1065 case 'D': 1073 case 'D':
1074 if (yres_specified || bpp_specified || refresh_specified ||
1075 was_digit || (force != DRM_FORCE_UNSPECIFIED))
1076 goto done;
1077
1066 if ((connector->connector_type != DRM_MODE_CONNECTOR_DVII) && 1078 if ((connector->connector_type != DRM_MODE_CONNECTOR_DVII) &&
1067 (connector->connector_type != DRM_MODE_CONNECTOR_HDMIB)) 1079 (connector->connector_type != DRM_MODE_CONNECTOR_HDMIB))
1068 force = DRM_FORCE_ON; 1080 force = DRM_FORCE_ON;
@@ -1070,17 +1082,37 @@ bool drm_mode_parse_command_line_for_connector(const char *mode_option,
1070 force = DRM_FORCE_ON_DIGITAL; 1082 force = DRM_FORCE_ON_DIGITAL;
1071 break; 1083 break;
1072 case 'd': 1084 case 'd':
1085 if (yres_specified || bpp_specified || refresh_specified ||
1086 was_digit || (force != DRM_FORCE_UNSPECIFIED))
1087 goto done;
1088
1073 force = DRM_FORCE_OFF; 1089 force = DRM_FORCE_OFF;
1074 break; 1090 break;
1075 default: 1091 default:
1076 goto done; 1092 goto done;
1077 } 1093 }
1078 } 1094 }
1095
1079 if (i < 0 && yres_specified) { 1096 if (i < 0 && yres_specified) {
1080 xres = simple_strtol(name, NULL, 10); 1097 char *ch;
1081 res_specified = 1; 1098 xres = simple_strtol(name, &ch, 10);
1099 if ((ch != NULL) && (*ch == 'x'))
1100 res_specified = true;
1101 else
1102 i = ch - name;
1103 } else if (!yres_specified && was_digit) {
1104 /* catch mode that begins with digits but has no 'x' */
1105 i = 0;
1082 } 1106 }
1083done: 1107done:
1108 if (i >= 0) {
1109 printk(KERN_WARNING
1110 "parse error at position %i in video mode '%s'\n",
1111 i, name);
1112 mode->specified = false;
1113 return false;
1114 }
1115
1084 if (res_specified) { 1116 if (res_specified) {
1085 mode->specified = true; 1117 mode->specified = true;
1086 mode->xres = xres; 1118 mode->xres = xres;
@@ -1096,9 +1128,10 @@ done:
1096 mode->bpp_specified = true; 1128 mode->bpp_specified = true;
1097 mode->bpp = bpp; 1129 mode->bpp = bpp;
1098 } 1130 }
1099 mode->rb = rb ? true : false; 1131 mode->rb = rb;
1100 mode->cvt = cvt ? true : false; 1132 mode->cvt = cvt;
1101 mode->interlace = interlace ? true : false; 1133 mode->interlace = interlace;
1134 mode->margins = margins;
1102 mode->force = force; 1135 mode->force = force;
1103 1136
1104 return true; 1137 return true;