aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/drm_modes.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/drm_modes.c')
-rw-r--r--drivers/gpu/drm/drm_modes.c156
1 files changed, 156 insertions, 0 deletions
diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c
index 25bf87390f53..c2d32f20e2fb 100644
--- a/drivers/gpu/drm/drm_modes.c
+++ b/drivers/gpu/drm/drm_modes.c
@@ -974,3 +974,159 @@ void drm_mode_connector_list_update(struct drm_connector *connector)
974 } 974 }
975} 975}
976EXPORT_SYMBOL(drm_mode_connector_list_update); 976EXPORT_SYMBOL(drm_mode_connector_list_update);
977
978/**
979 * drm_mode_parse_command_line_for_connector - parse command line for connector
980 * @mode_option - per connector mode option
981 * @connector - connector to parse line for
982 *
983 * This parses the connector specific then generic command lines for
984 * modes and options to configure the connector.
985 *
986 * This uses the same parameters as the fb modedb.c, except for extra
987 * <xres>x<yres>[M][R][-<bpp>][@<refresh>][i][m][eDd]
988 *
989 * enable/enable Digital/disable bit at the end
990 */
991bool drm_mode_parse_command_line_for_connector(const char *mode_option,
992 struct drm_connector *connector,
993 struct drm_cmdline_mode *mode)
994{
995 const char *name;
996 unsigned int namelen;
997 int res_specified = 0, bpp_specified = 0, refresh_specified = 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;
1000 int i;
1001 enum drm_connector_force force = DRM_FORCE_UNSPECIFIED;
1002
1003#ifdef CONFIG_FB
1004 if (!mode_option)
1005 mode_option = fb_mode_option;
1006#endif
1007
1008 if (!mode_option) {
1009 mode->specified = false;
1010 return false;
1011 }
1012
1013 name = mode_option;
1014 namelen = strlen(name);
1015 for (i = namelen-1; i >= 0; i--) {
1016 switch (name[i]) {
1017 case '@':
1018 namelen = i;
1019 if (!refresh_specified && !bpp_specified &&
1020 !yres_specified) {
1021 refresh = simple_strtol(&name[i+1], NULL, 10);
1022 refresh_specified = 1;
1023 if (cvt || rb)
1024 cvt = 0;
1025 } else
1026 goto done;
1027 break;
1028 case '-':
1029 namelen = i;
1030 if (!bpp_specified && !yres_specified) {
1031 bpp = simple_strtol(&name[i+1], NULL, 10);
1032 bpp_specified = 1;
1033 if (cvt || rb)
1034 cvt = 0;
1035 } else
1036 goto done;
1037 break;
1038 case 'x':
1039 if (!yres_specified) {
1040 yres = simple_strtol(&name[i+1], NULL, 10);
1041 yres_specified = 1;
1042 } else
1043 goto done;
1044 case '0' ... '9':
1045 break;
1046 case 'M':
1047 if (!yres_specified)
1048 cvt = 1;
1049 break;
1050 case 'R':
1051 if (cvt)
1052 rb = 1;
1053 break;
1054 case 'm':
1055 if (!cvt)
1056 margins = 1;
1057 break;
1058 case 'i':
1059 if (!cvt)
1060 interlace = 1;
1061 break;
1062 case 'e':
1063 force = DRM_FORCE_ON;
1064 break;
1065 case 'D':
1066 if ((connector->connector_type != DRM_MODE_CONNECTOR_DVII) &&
1067 (connector->connector_type != DRM_MODE_CONNECTOR_HDMIB))
1068 force = DRM_FORCE_ON;
1069 else
1070 force = DRM_FORCE_ON_DIGITAL;
1071 break;
1072 case 'd':
1073 force = DRM_FORCE_OFF;
1074 break;
1075 default:
1076 goto done;
1077 }
1078 }
1079 if (i < 0 && yres_specified) {
1080 xres = simple_strtol(name, NULL, 10);
1081 res_specified = 1;
1082 }
1083done:
1084 if (res_specified) {
1085 mode->specified = true;
1086 mode->xres = xres;
1087 mode->yres = yres;
1088 }
1089
1090 if (refresh_specified) {
1091 mode->refresh_specified = true;
1092 mode->refresh = refresh;
1093 }
1094
1095 if (bpp_specified) {
1096 mode->bpp_specified = true;
1097 mode->bpp = bpp;
1098 }
1099 mode->rb = rb ? true : false;
1100 mode->cvt = cvt ? true : false;
1101 mode->interlace = interlace ? true : false;
1102 mode->force = force;
1103
1104 return true;
1105}
1106EXPORT_SYMBOL(drm_mode_parse_command_line_for_connector);
1107
1108struct drm_display_mode *
1109drm_mode_create_from_cmdline_mode(struct drm_device *dev,
1110 struct drm_cmdline_mode *cmd)
1111{
1112 struct drm_display_mode *mode;
1113
1114 if (cmd->cvt)
1115 mode = drm_cvt_mode(dev,
1116 cmd->xres, cmd->yres,
1117 cmd->refresh_specified ? cmd->refresh : 60,
1118 cmd->rb, cmd->interlace,
1119 cmd->margins);
1120 else
1121 mode = drm_gtf_mode(dev,
1122 cmd->xres, cmd->yres,
1123 cmd->refresh_specified ? cmd->refresh : 60,
1124 cmd->interlace,
1125 cmd->margins);
1126 if (!mode)
1127 return NULL;
1128
1129 drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V);
1130 return mode;
1131}
1132EXPORT_SYMBOL(drm_mode_create_from_cmdline_mode);