71
71
EXPORT_SYMBOL(drm_fb_helper_single_add_all_connectors);
74
* drm_fb_helper_connector_parse_command_line - parse command line for connector
75
* @connector - connector to parse line for
76
* @mode_option - per connector mode option
78
* This parses the connector specific then generic command lines for
79
* modes and options to configure the connector.
81
* This uses the same parameters as the fb modedb.c, except for extra
82
* <xres>x<yres>[M][R][-<bpp>][@<refresh>][i][m][eDd]
84
* enable/enable Digital/disable bit at the end
86
static bool drm_fb_helper_connector_parse_command_line(struct drm_fb_helper_connector *fb_helper_conn,
87
const char *mode_option)
91
int res_specified = 0, bpp_specified = 0, refresh_specified = 0;
92
unsigned int xres = 0, yres = 0, bpp = 32, refresh = 0;
93
int yres_specified = 0, cvt = 0, rb = 0, interlace = 0, margins = 0;
95
enum drm_connector_force force = DRM_FORCE_UNSPECIFIED;
96
struct drm_fb_helper_cmdline_mode *cmdline_mode;
97
struct drm_connector *connector;
101
connector = fb_helper_conn->connector;
103
cmdline_mode = &fb_helper_conn->cmdline_mode;
105
mode_option = fb_mode_option;
108
cmdline_mode->specified = false;
113
namelen = strlen(name);
114
for (i = namelen-1; i >= 0; i--) {
118
if (!refresh_specified && !bpp_specified &&
120
refresh = simple_strtol(&name[i+1], NULL, 10);
121
refresh_specified = 1;
129
if (!bpp_specified && !yres_specified) {
130
bpp = simple_strtol(&name[i+1], NULL, 10);
138
if (!yres_specified) {
139
yres = simple_strtol(&name[i+1], NULL, 10);
162
force = DRM_FORCE_ON;
165
if ((connector->connector_type != DRM_MODE_CONNECTOR_DVII) &&
166
(connector->connector_type != DRM_MODE_CONNECTOR_HDMIB))
167
force = DRM_FORCE_ON;
169
force = DRM_FORCE_ON_DIGITAL;
172
force = DRM_FORCE_OFF;
178
if (i < 0 && yres_specified) {
179
xres = simple_strtol(name, NULL, 10);
184
DRM_DEBUG_KMS("cmdline mode for connector %s %dx%d@%dHz%s%s%s\n",
185
drm_get_connector_name(connector), xres, yres,
186
(refresh) ? refresh : 60, (rb) ? " reduced blanking" :
187
"", (margins) ? " with margins" : "", (interlace) ?
193
case DRM_FORCE_OFF: s = "OFF"; break;
194
case DRM_FORCE_ON_DIGITAL: s = "ON - dig"; break;
196
case DRM_FORCE_ON: s = "ON"; break;
199
DRM_INFO("forcing %s connector %s\n",
200
drm_get_connector_name(connector), s);
201
connector->force = force;
205
cmdline_mode->specified = true;
206
cmdline_mode->xres = xres;
207
cmdline_mode->yres = yres;
210
if (refresh_specified) {
211
cmdline_mode->refresh_specified = true;
212
cmdline_mode->refresh = refresh;
216
cmdline_mode->bpp_specified = true;
217
cmdline_mode->bpp = bpp;
219
cmdline_mode->rb = rb ? true : false;
220
cmdline_mode->cvt = cvt ? true : false;
221
cmdline_mode->interlace = interlace ? true : false;
226
73
static int drm_fb_helper_parse_command_line(struct drm_fb_helper *fb_helper)
228
75
struct drm_fb_helper_connector *fb_helper_conn;
231
78
for (i = 0; i < fb_helper->connector_count; i++) {
79
struct drm_cmdline_mode *mode;
80
struct drm_connector *connector;
232
81
char *option = NULL;
234
83
fb_helper_conn = fb_helper->connector_info[i];
84
connector = fb_helper_conn->connector;
85
mode = &fb_helper_conn->cmdline_mode;
236
87
/* do something on return - turn off connector maybe */
237
if (fb_get_options(drm_get_connector_name(fb_helper_conn->connector), &option))
88
if (fb_get_options(drm_get_connector_name(connector), &option))
240
drm_fb_helper_connector_parse_command_line(fb_helper_conn, option);
91
if (drm_mode_parse_command_line_for_connector(option,
96
switch (mode->force) {
97
case DRM_FORCE_OFF: s = "OFF"; break;
98
case DRM_FORCE_ON_DIGITAL: s = "ON - dig"; break;
100
case DRM_FORCE_ON: s = "ON"; break;
103
DRM_INFO("forcing %s connector %s\n",
104
drm_get_connector_name(connector), s);
105
connector->force = mode->force;
108
DRM_DEBUG_KMS("cmdline mode for connector %s %dx%d@%dHz%s%s%s\n",
109
drm_get_connector_name(connector),
110
mode->xres, mode->yres,
111
mode->refresh_specified ? mode->refresh : 60,
112
mode->rb ? " reduced blanking" : "",
113
mode->margins ? " with margins" : "",
114
mode->interlace ? " interlaced" : "");
1148
if (cmdline_mode->cvt)
1149
mode = drm_cvt_mode(fb_helper_conn->connector->dev,
1150
cmdline_mode->xres, cmdline_mode->yres,
1151
cmdline_mode->refresh_specified ? cmdline_mode->refresh : 60,
1152
cmdline_mode->rb, cmdline_mode->interlace,
1153
cmdline_mode->margins);
1155
mode = drm_gtf_mode(fb_helper_conn->connector->dev,
1156
cmdline_mode->xres, cmdline_mode->yres,
1157
cmdline_mode->refresh_specified ? cmdline_mode->refresh : 60,
1158
cmdline_mode->interlace,
1159
cmdline_mode->margins);
1160
drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V);
1042
mode = drm_mode_create_from_cmdline_mode(fb_helper_conn->connector->dev,
1161
1044
list_add(&mode->head, &fb_helper_conn->connector->modes);
1499
1382
EXPORT_SYMBOL(drm_fb_helper_initial_config);
1501
bool drm_fb_helper_hotplug_event(struct drm_fb_helper *fb_helper)
1385
* drm_fb_helper_hotplug_event - respond to a hotplug notification by
1386
* probing all the outputs attached to the fb.
1387
* @fb_helper: the drm_fb_helper
1390
* Called at runtime, must take mode config lock.
1392
* Scan the connectors attached to the fb_helper and try to put together a
1393
* setup after *notification of a change in output configuration.
1396
* 0 on success and a non-zero error code otherwise.
1398
int drm_fb_helper_hotplug_event(struct drm_fb_helper *fb_helper)
1400
struct drm_device *dev = fb_helper->dev;
1504
1402
u32 max_width, max_height, bpp_sel;
1505
1403
bool bound = false, crtcs_bound = false;
1506
1404
struct drm_crtc *crtc;
1508
1406
if (!fb_helper->fb)
1511
list_for_each_entry(crtc, &fb_helper->dev->mode_config.crtc_list, head) {
1409
mutex_lock(&dev->mode_config.mutex);
1410
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
1513
1412
crtcs_bound = true;
1514
1413
if (crtc->fb == fb_helper->fb)