diff options
| -rw-r--r-- | drivers/gpu/drm/drm_fb_helper.c | 74 | ||||
| -rw-r--r-- | include/drm/drm_crtc_helper.h | 2 | ||||
| -rw-r--r-- | include/drm/drm_fb_helper.h | 5 |
3 files changed, 81 insertions, 0 deletions
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index 719662034bbf..6245add3768a 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c | |||
| @@ -241,6 +241,80 @@ static int drm_fb_helper_parse_command_line(struct drm_fb_helper *fb_helper) | |||
| 241 | return 0; | 241 | return 0; |
| 242 | } | 242 | } |
| 243 | 243 | ||
| 244 | int drm_fb_helper_debug_enter(struct fb_info *info) | ||
| 245 | { | ||
| 246 | struct drm_fb_helper *helper = info->par; | ||
| 247 | struct drm_crtc_helper_funcs *funcs; | ||
| 248 | int i; | ||
| 249 | |||
| 250 | if (list_empty(&kernel_fb_helper_list)) | ||
| 251 | return false; | ||
| 252 | |||
| 253 | list_for_each_entry(helper, &kernel_fb_helper_list, kernel_fb_list) { | ||
| 254 | for (i = 0; i < helper->crtc_count; i++) { | ||
| 255 | struct drm_mode_set *mode_set = | ||
| 256 | &helper->crtc_info[i].mode_set; | ||
| 257 | |||
| 258 | if (!mode_set->crtc->enabled) | ||
| 259 | continue; | ||
| 260 | |||
| 261 | funcs = mode_set->crtc->helper_private; | ||
| 262 | funcs->mode_set_base_atomic(mode_set->crtc, | ||
| 263 | mode_set->fb, | ||
| 264 | mode_set->x, | ||
| 265 | mode_set->y); | ||
| 266 | |||
| 267 | } | ||
| 268 | } | ||
| 269 | |||
| 270 | return 0; | ||
| 271 | } | ||
| 272 | EXPORT_SYMBOL(drm_fb_helper_debug_enter); | ||
| 273 | |||
| 274 | /* Find the real fb for a given fb helper CRTC */ | ||
| 275 | static struct drm_framebuffer *drm_mode_config_fb(struct drm_crtc *crtc) | ||
| 276 | { | ||
| 277 | struct drm_device *dev = crtc->dev; | ||
| 278 | struct drm_crtc *c; | ||
| 279 | |||
| 280 | list_for_each_entry(c, &dev->mode_config.crtc_list, head) { | ||
| 281 | if (crtc->base.id == c->base.id) | ||
| 282 | return c->fb; | ||
| 283 | } | ||
| 284 | |||
| 285 | return NULL; | ||
| 286 | } | ||
| 287 | |||
| 288 | int drm_fb_helper_debug_leave(struct fb_info *info) | ||
| 289 | { | ||
| 290 | struct drm_fb_helper *helper = info->par; | ||
| 291 | struct drm_crtc *crtc; | ||
| 292 | struct drm_crtc_helper_funcs *funcs; | ||
| 293 | struct drm_framebuffer *fb; | ||
| 294 | int i; | ||
| 295 | |||
| 296 | for (i = 0; i < helper->crtc_count; i++) { | ||
| 297 | struct drm_mode_set *mode_set = &helper->crtc_info[i].mode_set; | ||
| 298 | crtc = mode_set->crtc; | ||
| 299 | funcs = crtc->helper_private; | ||
| 300 | fb = drm_mode_config_fb(crtc); | ||
| 301 | |||
| 302 | if (!crtc->enabled) | ||
| 303 | continue; | ||
| 304 | |||
| 305 | if (!fb) { | ||
| 306 | DRM_ERROR("no fb to restore??\n"); | ||
| 307 | continue; | ||
| 308 | } | ||
| 309 | |||
| 310 | funcs->mode_set_base_atomic(mode_set->crtc, fb, crtc->x, | ||
| 311 | crtc->y); | ||
| 312 | } | ||
| 313 | |||
| 314 | return 0; | ||
| 315 | } | ||
| 316 | EXPORT_SYMBOL(drm_fb_helper_debug_leave); | ||
| 317 | |||
| 244 | bool drm_fb_helper_force_kernel_mode(void) | 318 | bool drm_fb_helper_force_kernel_mode(void) |
| 245 | { | 319 | { |
| 246 | int i = 0; | 320 | int i = 0; |
diff --git a/include/drm/drm_crtc_helper.h b/include/drm/drm_crtc_helper.h index 1121f7799c6f..10f7d03e58a9 100644 --- a/include/drm/drm_crtc_helper.h +++ b/include/drm/drm_crtc_helper.h | |||
| @@ -60,6 +60,8 @@ struct drm_crtc_helper_funcs { | |||
| 60 | /* Move the crtc on the current fb to the given position *optional* */ | 60 | /* Move the crtc on the current fb to the given position *optional* */ |
| 61 | int (*mode_set_base)(struct drm_crtc *crtc, int x, int y, | 61 | int (*mode_set_base)(struct drm_crtc *crtc, int x, int y, |
| 62 | struct drm_framebuffer *old_fb); | 62 | struct drm_framebuffer *old_fb); |
| 63 | int (*mode_set_base_atomic)(struct drm_crtc *crtc, | ||
| 64 | struct drm_framebuffer *fb, int x, int y); | ||
| 63 | 65 | ||
| 64 | /* reload the current crtc LUT */ | 66 | /* reload the current crtc LUT */ |
| 65 | void (*load_lut)(struct drm_crtc *crtc); | 67 | void (*load_lut)(struct drm_crtc *crtc); |
diff --git a/include/drm/drm_fb_helper.h b/include/drm/drm_fb_helper.h index f0a6afc47e76..f22e7fe4b6db 100644 --- a/include/drm/drm_fb_helper.h +++ b/include/drm/drm_fb_helper.h | |||
| @@ -32,6 +32,8 @@ | |||
| 32 | 32 | ||
| 33 | struct drm_fb_helper; | 33 | struct drm_fb_helper; |
| 34 | 34 | ||
| 35 | #include <linux/kgdb.h> | ||
| 36 | |||
| 35 | struct drm_fb_helper_crtc { | 37 | struct drm_fb_helper_crtc { |
| 36 | uint32_t crtc_id; | 38 | uint32_t crtc_id; |
| 37 | struct drm_mode_set mode_set; | 39 | struct drm_mode_set mode_set; |
| @@ -78,6 +80,7 @@ struct drm_fb_helper_connector { | |||
| 78 | 80 | ||
| 79 | struct drm_fb_helper { | 81 | struct drm_fb_helper { |
| 80 | struct drm_framebuffer *fb; | 82 | struct drm_framebuffer *fb; |
| 83 | struct drm_framebuffer *saved_fb; | ||
| 81 | struct drm_device *dev; | 84 | struct drm_device *dev; |
| 82 | struct drm_display_mode *mode; | 85 | struct drm_display_mode *mode; |
| 83 | int crtc_count; | 86 | int crtc_count; |
| @@ -126,5 +129,7 @@ int drm_fb_helper_setcmap(struct fb_cmap *cmap, struct fb_info *info); | |||
| 126 | bool drm_fb_helper_hotplug_event(struct drm_fb_helper *fb_helper); | 129 | bool drm_fb_helper_hotplug_event(struct drm_fb_helper *fb_helper); |
| 127 | bool drm_fb_helper_initial_config(struct drm_fb_helper *fb_helper, int bpp_sel); | 130 | bool drm_fb_helper_initial_config(struct drm_fb_helper *fb_helper, int bpp_sel); |
| 128 | int drm_fb_helper_single_add_all_connectors(struct drm_fb_helper *fb_helper); | 131 | int drm_fb_helper_single_add_all_connectors(struct drm_fb_helper *fb_helper); |
| 132 | int drm_fb_helper_debug_enter(struct fb_info *info); | ||
| 133 | int drm_fb_helper_debug_leave(struct fb_info *info); | ||
| 129 | 134 | ||
| 130 | #endif | 135 | #endif |
