diff options
Diffstat (limited to 'drivers/gpu/drm/drm_fb_helper.c')
-rw-r--r-- | drivers/gpu/drm/drm_fb_helper.c | 85 |
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 | } |
172 | EXPORT_SYMBOL(drm_fb_helper_remove_one_connector); | 172 | EXPORT_SYMBOL(drm_fb_helper_remove_one_connector); |
173 | 173 | ||
174 | static 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 | |||
228 | static void drm_fb_helper_save_lut_atomic(struct drm_crtc *crtc, struct drm_fb_helper *helper) | 174 | static 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 | ||
1261 | static bool drm_has_cmdline_mode(struct drm_fb_helper_connector *fb_connector) | 1214 | static 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 | ||
1268 | struct drm_display_mode *drm_pick_cmdline_mode(struct drm_fb_helper_connector *fb_helper_conn, | 1219 | struct 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, |