aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/drm_modes.c
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2011-04-17 02:43:32 -0400
committerDave Airlie <airlied@redhat.com>2011-04-28 00:56:23 -0400
commit1794d257fa7bab3ea5162f8abdca749996b65343 (patch)
treeea8d035a218a0cb0ee83443b3c25bd8df25567e2 /drivers/gpu/drm/drm_modes.c
parentbbb0aef5cfe95fe9b51a7eeba4a440b69037b01f (diff)
drm: Export the command-line mode parser
In the absence of configuration data for providing the fixed mode for a panel, I would like to be able to pass such modes along a separate module paramenter. To do so, I then need to parse a modeline from a string, which drm is already capable of. Export that capability to the drivers. Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/drm_modes.c')
-rw-r--r--drivers/gpu/drm/drm_modes.c154
1 files changed, 154 insertions, 0 deletions
diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c
index 25bf87390f53..207b7ebf8150 100644
--- a/drivers/gpu/drm/drm_modes.c
+++ b/drivers/gpu/drm/drm_modes.c
@@ -974,3 +974,157 @@ 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 if (!mode_option)
1004 mode_option = fb_mode_option;
1005
1006 if (!mode_option) {
1007 mode->specified = false;
1008 return false;
1009 }
1010
1011 name = mode_option;
1012 namelen = strlen(name);
1013 for (i = namelen-1; i >= 0; i--) {
1014 switch (name[i]) {
1015 case '@':
1016 namelen = i;
1017 if (!refresh_specified && !bpp_specified &&
1018 !yres_specified) {
1019 refresh = simple_strtol(&name[i+1], NULL, 10);
1020 refresh_specified = 1;
1021 if (cvt || rb)
1022 cvt = 0;
1023 } else
1024 goto done;
1025 break;
1026 case '-':
1027 namelen = i;
1028 if (!bpp_specified && !yres_specified) {
1029 bpp = simple_strtol(&name[i+1], NULL, 10);
1030 bpp_specified = 1;
1031 if (cvt || rb)
1032 cvt = 0;
1033 } else
1034 goto done;
1035 break;
1036 case 'x':
1037 if (!yres_specified) {
1038 yres = simple_strtol(&name[i+1], NULL, 10);
1039 yres_specified = 1;
1040 } else
1041 goto done;
1042 case '0' ... '9':
1043 break;
1044 case 'M':
1045 if (!yres_specified)
1046 cvt = 1;
1047 break;
1048 case 'R':
1049 if (cvt)
1050 rb = 1;
1051 break;
1052 case 'm':
1053 if (!cvt)
1054 margins = 1;
1055 break;
1056 case 'i':
1057 if (!cvt)
1058 interlace = 1;
1059 break;
1060 case 'e':
1061 force = DRM_FORCE_ON;
1062 break;
1063 case 'D':
1064 if ((connector->connector_type != DRM_MODE_CONNECTOR_DVII) &&
1065 (connector->connector_type != DRM_MODE_CONNECTOR_HDMIB))
1066 force = DRM_FORCE_ON;
1067 else
1068 force = DRM_FORCE_ON_DIGITAL;
1069 break;
1070 case 'd':
1071 force = DRM_FORCE_OFF;
1072 break;
1073 default:
1074 goto done;
1075 }
1076 }
1077 if (i < 0 && yres_specified) {
1078 xres = simple_strtol(name, NULL, 10);
1079 res_specified = 1;
1080 }
1081done:
1082 if (res_specified) {
1083 mode->specified = true;
1084 mode->xres = xres;
1085 mode->yres = yres;
1086 }
1087
1088 if (refresh_specified) {
1089 mode->refresh_specified = true;
1090 mode->refresh = refresh;
1091 }
1092
1093 if (bpp_specified) {
1094 mode->bpp_specified = true;
1095 mode->bpp = bpp;
1096 }
1097 mode->rb = rb ? true : false;
1098 mode->cvt = cvt ? true : false;
1099 mode->interlace = interlace ? true : false;
1100 mode->force = force;
1101
1102 return true;
1103}
1104EXPORT_SYMBOL(drm_mode_parse_command_line_for_connector);
1105
1106struct drm_display_mode *
1107drm_mode_create_from_cmdline_mode(struct drm_device *dev,
1108 struct drm_cmdline_mode *cmd)
1109{
1110 struct drm_display_mode *mode;
1111
1112 if (cmd->cvt)
1113 mode = drm_cvt_mode(dev,
1114 cmd->xres, cmd->yres,
1115 cmd->refresh_specified ? cmd->refresh : 60,
1116 cmd->rb, cmd->interlace,
1117 cmd->margins);
1118 else
1119 mode = drm_gtf_mode(dev,
1120 cmd->xres, cmd->yres,
1121 cmd->refresh_specified ? cmd->refresh : 60,
1122 cmd->interlace,
1123 cmd->margins);
1124 if (!mode)
1125 return NULL;
1126
1127 drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V);
1128 return mode;
1129}
1130EXPORT_SYMBOL(drm_mode_create_from_cmdline_mode);