aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/drm_fb_helper.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/drm_fb_helper.c')
-rw-r--r--drivers/gpu/drm/drm_fb_helper.c85
1 files changed, 17 insertions, 68 deletions
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c
index 3144db9dc0f1..0c0c39bac23d 100644
--- a/drivers/gpu/drm/drm_fb_helper.c
+++ b/drivers/gpu/drm/drm_fb_helper.c
@@ -126,7 +126,7 @@ int drm_fb_helper_add_one_connector(struct drm_fb_helper *fb_helper, struct drm_
126 126
127 WARN_ON(!mutex_is_locked(&fb_helper->dev->mode_config.mutex)); 127 WARN_ON(!mutex_is_locked(&fb_helper->dev->mode_config.mutex));
128 if (fb_helper->connector_count + 1 > fb_helper->connector_info_alloc_count) { 128 if (fb_helper->connector_count + 1 > fb_helper->connector_info_alloc_count) {
129 temp = krealloc(fb_helper->connector_info, sizeof(struct drm_fb_helper_connector) * (fb_helper->connector_count + 1), GFP_KERNEL); 129 temp = krealloc(fb_helper->connector_info, sizeof(struct drm_fb_helper_connector *) * (fb_helper->connector_count + 1), GFP_KERNEL);
130 if (!temp) 130 if (!temp)
131 return -ENOMEM; 131 return -ENOMEM;
132 132
@@ -171,60 +171,6 @@ int drm_fb_helper_remove_one_connector(struct drm_fb_helper *fb_helper,
171} 171}
172EXPORT_SYMBOL(drm_fb_helper_remove_one_connector); 172EXPORT_SYMBOL(drm_fb_helper_remove_one_connector);
173 173
174static int drm_fb_helper_parse_command_line(struct drm_fb_helper *fb_helper)
175{
176 struct drm_fb_helper_connector *fb_helper_conn;
177 int i;
178
179 for (i = 0; i < fb_helper->connector_count; i++) {
180 struct drm_cmdline_mode *mode;
181 struct drm_connector *connector;
182 char *option = NULL;
183
184 fb_helper_conn = fb_helper->connector_info[i];
185 connector = fb_helper_conn->connector;
186 mode = &fb_helper_conn->cmdline_mode;
187
188 /* do something on return - turn off connector maybe */
189 if (fb_get_options(connector->name, &option))
190 continue;
191
192 if (drm_mode_parse_command_line_for_connector(option,
193 connector,
194 mode)) {
195 if (mode->force) {
196 const char *s;
197 switch (mode->force) {
198 case DRM_FORCE_OFF:
199 s = "OFF";
200 break;
201 case DRM_FORCE_ON_DIGITAL:
202 s = "ON - dig";
203 break;
204 default:
205 case DRM_FORCE_ON:
206 s = "ON";
207 break;
208 }
209
210 DRM_INFO("forcing %s connector %s\n",
211 connector->name, s);
212 connector->force = mode->force;
213 }
214
215 DRM_DEBUG_KMS("cmdline mode for connector %s %dx%d@%dHz%s%s%s\n",
216 connector->name,
217 mode->xres, mode->yres,
218 mode->refresh_specified ? mode->refresh : 60,
219 mode->rb ? " reduced blanking" : "",
220 mode->margins ? " with margins" : "",
221 mode->interlace ? " interlaced" : "");
222 }
223
224 }
225 return 0;
226}
227
228static void drm_fb_helper_save_lut_atomic(struct drm_crtc *crtc, struct drm_fb_helper *helper) 174static void drm_fb_helper_save_lut_atomic(struct drm_crtc *crtc, struct drm_fb_helper *helper)
229{ 175{
230 uint16_t *r_base, *g_base, *b_base; 176 uint16_t *r_base, *g_base, *b_base;
@@ -345,10 +291,17 @@ static bool restore_fbdev_mode(struct drm_fb_helper *fb_helper)
345 291
346 drm_warn_on_modeset_not_all_locked(dev); 292 drm_warn_on_modeset_not_all_locked(dev);
347 293
348 list_for_each_entry(plane, &dev->mode_config.plane_list, head) 294 list_for_each_entry(plane, &dev->mode_config.plane_list, head) {
349 if (plane->type != DRM_PLANE_TYPE_PRIMARY) 295 if (plane->type != DRM_PLANE_TYPE_PRIMARY)
350 drm_plane_force_disable(plane); 296 drm_plane_force_disable(plane);
351 297
298 if (dev->mode_config.rotation_property) {
299 drm_mode_plane_set_obj_prop(plane,
300 dev->mode_config.rotation_property,
301 BIT(DRM_ROTATE_0));
302 }
303 }
304
352 for (i = 0; i < fb_helper->crtc_count; i++) { 305 for (i = 0; i < fb_helper->crtc_count; i++) {
353 struct drm_mode_set *mode_set = &fb_helper->crtc_info[i].mode_set; 306 struct drm_mode_set *mode_set = &fb_helper->crtc_info[i].mode_set;
354 struct drm_crtc *crtc = mode_set->crtc; 307 struct drm_crtc *crtc = mode_set->crtc;
@@ -419,11 +372,11 @@ static bool drm_fb_helper_force_kernel_mode(void)
419 if (dev->switch_power_state == DRM_SWITCH_POWER_OFF) 372 if (dev->switch_power_state == DRM_SWITCH_POWER_OFF)
420 continue; 373 continue;
421 374
422 /* NOTE: we use lockless flag below to avoid grabbing other 375 /*
423 * modeset locks. So just trylock the underlying mutex 376 * NOTE: Use trylock mode to avoid deadlocks and sleeping in
424 * directly: 377 * panic context.
425 */ 378 */
426 if (!mutex_trylock(&dev->mode_config.mutex)) { 379 if (__drm_modeset_lock_all(dev, true) != 0) {
427 error = true; 380 error = true;
428 continue; 381 continue;
429 } 382 }
@@ -432,7 +385,7 @@ static bool drm_fb_helper_force_kernel_mode(void)
432 if (ret) 385 if (ret)
433 error = true; 386 error = true;
434 387
435 mutex_unlock(&dev->mode_config.mutex); 388 drm_modeset_unlock_all(dev);
436 } 389 }
437 return error; 390 return error;
438} 391}
@@ -1013,7 +966,7 @@ static int drm_fb_helper_single_fb_probe(struct drm_fb_helper *fb_helper,
1013 struct drm_fb_helper_connector *fb_helper_conn = fb_helper->connector_info[i]; 966 struct drm_fb_helper_connector *fb_helper_conn = fb_helper->connector_info[i];
1014 struct drm_cmdline_mode *cmdline_mode; 967 struct drm_cmdline_mode *cmdline_mode;
1015 968
1016 cmdline_mode = &fb_helper_conn->cmdline_mode; 969 cmdline_mode = &fb_helper_conn->connector->cmdline_mode;
1017 970
1018 if (cmdline_mode->bpp_specified) { 971 if (cmdline_mode->bpp_specified) {
1019 switch (cmdline_mode->bpp) { 972 switch (cmdline_mode->bpp) {
@@ -1260,9 +1213,7 @@ EXPORT_SYMBOL(drm_has_preferred_mode);
1260 1213
1261static bool drm_has_cmdline_mode(struct drm_fb_helper_connector *fb_connector) 1214static bool drm_has_cmdline_mode(struct drm_fb_helper_connector *fb_connector)
1262{ 1215{
1263 struct drm_cmdline_mode *cmdline_mode; 1216 return fb_connector->connector->cmdline_mode.specified;
1264 cmdline_mode = &fb_connector->cmdline_mode;
1265 return cmdline_mode->specified;
1266} 1217}
1267 1218
1268struct drm_display_mode *drm_pick_cmdline_mode(struct drm_fb_helper_connector *fb_helper_conn, 1219struct drm_display_mode *drm_pick_cmdline_mode(struct drm_fb_helper_connector *fb_helper_conn,
@@ -1272,7 +1223,7 @@ struct drm_display_mode *drm_pick_cmdline_mode(struct drm_fb_helper_connector *f
1272 struct drm_display_mode *mode = NULL; 1223 struct drm_display_mode *mode = NULL;
1273 bool prefer_non_interlace; 1224 bool prefer_non_interlace;
1274 1225
1275 cmdline_mode = &fb_helper_conn->cmdline_mode; 1226 cmdline_mode = &fb_helper_conn->connector->cmdline_mode;
1276 if (cmdline_mode->specified == false) 1227 if (cmdline_mode->specified == false)
1277 return mode; 1228 return mode;
1278 1229
@@ -1657,8 +1608,6 @@ bool drm_fb_helper_initial_config(struct drm_fb_helper *fb_helper, int bpp_sel)
1657 struct drm_device *dev = fb_helper->dev; 1608 struct drm_device *dev = fb_helper->dev;
1658 int count = 0; 1609 int count = 0;
1659 1610
1660 drm_fb_helper_parse_command_line(fb_helper);
1661
1662 mutex_lock(&dev->mode_config.mutex); 1611 mutex_lock(&dev->mode_config.mutex);
1663 count = drm_fb_helper_probe_connector_modes(fb_helper, 1612 count = drm_fb_helper_probe_connector_modes(fb_helper,
1664 dev->mode_config.max_width, 1613 dev->mode_config.max_width,