Lines Matching refs:fb_helper
122 static int __drm_fb_helper_add_one_connector(struct drm_fb_helper *fb_helper, in __drm_fb_helper_add_one_connector() argument
132 lockdep_assert_held(&fb_helper->lock); in __drm_fb_helper_add_one_connector()
134 count = fb_helper->connector_count + 1; in __drm_fb_helper_add_one_connector()
136 if (count > fb_helper->connector_info_alloc_count) { in __drm_fb_helper_add_one_connector()
139 temp = krealloc(fb_helper->connector_info, size, GFP_KERNEL); in __drm_fb_helper_add_one_connector()
143 fb_helper->connector_info_alloc_count = count; in __drm_fb_helper_add_one_connector()
144 fb_helper->connector_info = temp; in __drm_fb_helper_add_one_connector()
153 fb_helper->connector_info[fb_helper->connector_count++] = fb_conn; in __drm_fb_helper_add_one_connector()
158 int drm_fb_helper_add_one_connector(struct drm_fb_helper *fb_helper, in drm_fb_helper_add_one_connector() argument
163 if (!fb_helper) in drm_fb_helper_add_one_connector()
166 mutex_lock(&fb_helper->lock); in drm_fb_helper_add_one_connector()
167 err = __drm_fb_helper_add_one_connector(fb_helper, connector); in drm_fb_helper_add_one_connector()
168 mutex_unlock(&fb_helper->lock); in drm_fb_helper_add_one_connector()
188 int drm_fb_helper_single_add_all_connectors(struct drm_fb_helper *fb_helper) in drm_fb_helper_single_add_all_connectors() argument
195 if (!drm_fbdev_emulation || !fb_helper) in drm_fb_helper_single_add_all_connectors()
198 dev = fb_helper->dev; in drm_fb_helper_single_add_all_connectors()
200 mutex_lock(&fb_helper->lock); in drm_fb_helper_single_add_all_connectors()
203 ret = __drm_fb_helper_add_one_connector(fb_helper, connector); in drm_fb_helper_single_add_all_connectors()
210 drm_fb_helper_for_each_connector(fb_helper, i) { in drm_fb_helper_single_add_all_connectors()
212 fb_helper->connector_info[i]; in drm_fb_helper_single_add_all_connectors()
217 fb_helper->connector_info[i] = NULL; in drm_fb_helper_single_add_all_connectors()
219 fb_helper->connector_count = 0; in drm_fb_helper_single_add_all_connectors()
222 mutex_unlock(&fb_helper->lock); in drm_fb_helper_single_add_all_connectors()
228 static int __drm_fb_helper_remove_one_connector(struct drm_fb_helper *fb_helper, in __drm_fb_helper_remove_one_connector() argument
237 lockdep_assert_held(&fb_helper->lock); in __drm_fb_helper_remove_one_connector()
239 drm_fb_helper_for_each_connector(fb_helper, i) { in __drm_fb_helper_remove_one_connector()
240 if (fb_helper->connector_info[i]->connector == connector) in __drm_fb_helper_remove_one_connector()
244 if (i == fb_helper->connector_count) in __drm_fb_helper_remove_one_connector()
246 fb_helper_connector = fb_helper->connector_info[i]; in __drm_fb_helper_remove_one_connector()
249 for (j = i + 1; j < fb_helper->connector_count; j++) in __drm_fb_helper_remove_one_connector()
250 fb_helper->connector_info[j - 1] = fb_helper->connector_info[j]; in __drm_fb_helper_remove_one_connector()
252 fb_helper->connector_count--; in __drm_fb_helper_remove_one_connector()
258 int drm_fb_helper_remove_one_connector(struct drm_fb_helper *fb_helper, in drm_fb_helper_remove_one_connector() argument
263 if (!fb_helper) in drm_fb_helper_remove_one_connector()
266 mutex_lock(&fb_helper->lock); in drm_fb_helper_remove_one_connector()
267 err = __drm_fb_helper_remove_one_connector(fb_helper, connector); in drm_fb_helper_remove_one_connector()
268 mutex_unlock(&fb_helper->lock); in drm_fb_helper_remove_one_connector()
368 static int restore_fbdev_mode_atomic(struct drm_fb_helper *fb_helper, bool active) in restore_fbdev_mode_atomic() argument
370 struct drm_device *dev = fb_helper->dev; in restore_fbdev_mode_atomic()
405 for (i = 0; i < fb_helper->crtc_count; i++) { in restore_fbdev_mode_atomic()
406 struct drm_mode_set *mode_set = &fb_helper->crtc_info[i].mode_set; in restore_fbdev_mode_atomic()
411 plane_state->rotation = fb_helper->crtc_info[i].rotation; in restore_fbdev_mode_atomic()
449 static int restore_fbdev_mode_legacy(struct drm_fb_helper *fb_helper) in restore_fbdev_mode_legacy() argument
451 struct drm_device *dev = fb_helper->dev; in restore_fbdev_mode_legacy()
455 drm_modeset_lock_all(fb_helper->dev); in restore_fbdev_mode_legacy()
466 for (i = 0; i < fb_helper->crtc_count; i++) { in restore_fbdev_mode_legacy()
467 struct drm_mode_set *mode_set = &fb_helper->crtc_info[i].mode_set; in restore_fbdev_mode_legacy()
485 drm_modeset_unlock_all(fb_helper->dev); in restore_fbdev_mode_legacy()
490 static int restore_fbdev_mode(struct drm_fb_helper *fb_helper) in restore_fbdev_mode() argument
492 struct drm_device *dev = fb_helper->dev; in restore_fbdev_mode()
495 return restore_fbdev_mode_atomic(fb_helper, true); in restore_fbdev_mode()
497 return restore_fbdev_mode_legacy(fb_helper); in restore_fbdev_mode()
511 int drm_fb_helper_restore_fbdev_mode_unlocked(struct drm_fb_helper *fb_helper) in drm_fb_helper_restore_fbdev_mode_unlocked() argument
516 if (!drm_fbdev_emulation || !fb_helper) in drm_fb_helper_restore_fbdev_mode_unlocked()
519 if (READ_ONCE(fb_helper->deferred_setup)) in drm_fb_helper_restore_fbdev_mode_unlocked()
522 mutex_lock(&fb_helper->lock); in drm_fb_helper_restore_fbdev_mode_unlocked()
523 ret = restore_fbdev_mode(fb_helper); in drm_fb_helper_restore_fbdev_mode_unlocked()
525 do_delayed = fb_helper->delayed_hotplug; in drm_fb_helper_restore_fbdev_mode_unlocked()
527 fb_helper->delayed_hotplug = false; in drm_fb_helper_restore_fbdev_mode_unlocked()
528 mutex_unlock(&fb_helper->lock); in drm_fb_helper_restore_fbdev_mode_unlocked()
531 drm_fb_helper_hotplug_event(fb_helper); in drm_fb_helper_restore_fbdev_mode_unlocked()
537 static bool drm_fb_helper_is_bound(struct drm_fb_helper *fb_helper) in drm_fb_helper_is_bound() argument
539 struct drm_device *dev = fb_helper->dev; in drm_fb_helper_is_bound()
554 if (crtc->primary->fb == fb_helper->fb) in drm_fb_helper_is_bound()
617 static void dpms_legacy(struct drm_fb_helper *fb_helper, int dpms_mode) in dpms_legacy() argument
619 struct drm_device *dev = fb_helper->dev; in dpms_legacy()
625 for (i = 0; i < fb_helper->crtc_count; i++) { in dpms_legacy()
626 crtc = fb_helper->crtc_info[i].mode_set.crtc; in dpms_legacy()
632 drm_fb_helper_for_each_connector(fb_helper, j) { in dpms_legacy()
633 connector = fb_helper->connector_info[j]->connector; in dpms_legacy()
644 struct drm_fb_helper *fb_helper = info->par; in drm_fb_helper_dpms() local
649 mutex_lock(&fb_helper->lock); in drm_fb_helper_dpms()
650 if (!drm_fb_helper_is_bound(fb_helper)) { in drm_fb_helper_dpms()
651 mutex_unlock(&fb_helper->lock); in drm_fb_helper_dpms()
655 if (drm_drv_uses_atomic_modeset(fb_helper->dev)) in drm_fb_helper_dpms()
656 restore_fbdev_mode_atomic(fb_helper, dpms_mode == DRM_MODE_DPMS_ON); in drm_fb_helper_dpms()
658 dpms_legacy(fb_helper, dpms_mode); in drm_fb_helper_dpms()
659 mutex_unlock(&fb_helper->lock); in drm_fb_helper_dpms()
745 static void drm_fb_helper_dirty_blit_real(struct drm_fb_helper *fb_helper, in drm_fb_helper_dirty_blit_real() argument
748 struct drm_framebuffer *fb = fb_helper->fb; in drm_fb_helper_dirty_blit_real()
751 void *src = fb_helper->fbdev->screen_buffer + offset; in drm_fb_helper_dirty_blit_real()
752 void *dst = fb_helper->buffer->vaddr + offset; in drm_fb_helper_dirty_blit_real()
826 struct drm_fb_helper *fb_helper, in drm_fb_helper_init() argument
834 dev->fb_helper = fb_helper; in drm_fb_helper_init()
841 fb_helper->crtc_info = kcalloc(config->num_crtc, sizeof(struct drm_fb_helper_crtc), GFP_KERNEL); in drm_fb_helper_init()
842 if (!fb_helper->crtc_info) in drm_fb_helper_init()
845 fb_helper->crtc_count = config->num_crtc; in drm_fb_helper_init()
846 …fb_helper->connector_info = kcalloc(dev->mode_config.num_connector, sizeof(struct drm_fb_helper_co… in drm_fb_helper_init()
847 if (!fb_helper->connector_info) { in drm_fb_helper_init()
848 kfree(fb_helper->crtc_info); in drm_fb_helper_init()
851 fb_helper->connector_info_alloc_count = dev->mode_config.num_connector; in drm_fb_helper_init()
852 fb_helper->connector_count = 0; in drm_fb_helper_init()
854 for (i = 0; i < fb_helper->crtc_count; i++) { in drm_fb_helper_init()
855 fb_helper->crtc_info[i].mode_set.connectors = in drm_fb_helper_init()
860 if (!fb_helper->crtc_info[i].mode_set.connectors) in drm_fb_helper_init()
862 fb_helper->crtc_info[i].mode_set.num_connectors = 0; in drm_fb_helper_init()
863 fb_helper->crtc_info[i].rotation = DRM_MODE_ROTATE_0; in drm_fb_helper_init()
868 fb_helper->crtc_info[i].mode_set.crtc = crtc; in drm_fb_helper_init()
872 dev->fb_helper = fb_helper; in drm_fb_helper_init()
876 drm_fb_helper_crtc_free(fb_helper); in drm_fb_helper_init()
894 struct fb_info *drm_fb_helper_alloc_fbi(struct drm_fb_helper *fb_helper) in drm_fb_helper_alloc_fbi() argument
896 struct device *dev = fb_helper->dev->dev; in drm_fb_helper_alloc_fbi()
914 fb_helper->fbdev = info; in drm_fb_helper_alloc_fbi()
934 void drm_fb_helper_unregister_fbi(struct drm_fb_helper *fb_helper) in drm_fb_helper_unregister_fbi() argument
936 if (fb_helper && fb_helper->fbdev) in drm_fb_helper_unregister_fbi()
937 unregister_framebuffer(fb_helper->fbdev); in drm_fb_helper_unregister_fbi()
948 void drm_fb_helper_fini(struct drm_fb_helper *fb_helper) in drm_fb_helper_fini() argument
952 if (!fb_helper) in drm_fb_helper_fini()
955 fb_helper->dev->fb_helper = NULL; in drm_fb_helper_fini()
960 cancel_work_sync(&fb_helper->resume_work); in drm_fb_helper_fini()
961 cancel_work_sync(&fb_helper->dirty_work); in drm_fb_helper_fini()
963 info = fb_helper->fbdev; in drm_fb_helper_fini()
969 fb_helper->fbdev = NULL; in drm_fb_helper_fini()
972 if (!list_empty(&fb_helper->kernel_fb_list)) { in drm_fb_helper_fini()
973 list_del(&fb_helper->kernel_fb_list); in drm_fb_helper_fini()
979 mutex_destroy(&fb_helper->lock); in drm_fb_helper_fini()
980 drm_fb_helper_crtc_free(fb_helper); in drm_fb_helper_fini()
991 void drm_fb_helper_unlink_fbi(struct drm_fb_helper *fb_helper) in drm_fb_helper_unlink_fbi() argument
993 if (fb_helper && fb_helper->fbdev) in drm_fb_helper_unlink_fbi()
994 unlink_framebuffer(fb_helper->fbdev); in drm_fb_helper_unlink_fbi()
1067 int drm_fb_helper_defio_init(struct drm_fb_helper *fb_helper) in drm_fb_helper_defio_init() argument
1069 struct fb_info *info = fb_helper->fbdev; in drm_fb_helper_defio_init()
1238 void drm_fb_helper_set_suspend(struct drm_fb_helper *fb_helper, bool suspend) in drm_fb_helper_set_suspend() argument
1240 if (fb_helper && fb_helper->fbdev) in drm_fb_helper_set_suspend()
1241 fb_set_suspend(fb_helper->fbdev, suspend); in drm_fb_helper_set_suspend()
1261 void drm_fb_helper_set_suspend_unlocked(struct drm_fb_helper *fb_helper, in drm_fb_helper_set_suspend_unlocked() argument
1264 if (!fb_helper || !fb_helper->fbdev) in drm_fb_helper_set_suspend_unlocked()
1268 flush_work(&fb_helper->resume_work); in drm_fb_helper_set_suspend_unlocked()
1271 if (fb_helper->fbdev->state != FBINFO_STATE_RUNNING) in drm_fb_helper_set_suspend_unlocked()
1277 if (fb_helper->fbdev->state == FBINFO_STATE_RUNNING) in drm_fb_helper_set_suspend_unlocked()
1281 schedule_work(&fb_helper->resume_work); in drm_fb_helper_set_suspend_unlocked()
1286 fb_set_suspend(fb_helper->fbdev, suspend); in drm_fb_helper_set_suspend_unlocked()
1325 struct drm_fb_helper *fb_helper = info->par; in setcmap_legacy() local
1330 drm_modeset_lock_all(fb_helper->dev); in setcmap_legacy()
1331 for (i = 0; i < fb_helper->crtc_count; i++) { in setcmap_legacy()
1332 crtc = fb_helper->crtc_info[i].mode_set.crtc; in setcmap_legacy()
1352 drm_modeset_unlock_all(fb_helper->dev); in setcmap_legacy()
1402 struct drm_fb_helper *fb_helper = info->par; in setcmap_atomic() local
1403 struct drm_device *dev = fb_helper->dev; in setcmap_atomic()
1423 for (i = 0; i < fb_helper->crtc_count; i++) { in setcmap_atomic()
1424 crtc = fb_helper->crtc_info[i].mode_set.crtc; in setcmap_atomic()
1452 for (i = 0; i < fb_helper->crtc_count; i++) { in setcmap_atomic()
1453 crtc = fb_helper->crtc_info[i].mode_set.crtc; in setcmap_atomic()
1489 struct drm_fb_helper *fb_helper = info->par; in drm_fb_helper_setcmap() local
1495 mutex_lock(&fb_helper->lock); in drm_fb_helper_setcmap()
1497 if (!drm_fb_helper_is_bound(fb_helper)) { in drm_fb_helper_setcmap()
1504 else if (drm_drv_uses_atomic_modeset(fb_helper->dev)) in drm_fb_helper_setcmap()
1510 mutex_unlock(&fb_helper->lock); in drm_fb_helper_setcmap()
1528 struct drm_fb_helper *fb_helper = info->par; in drm_fb_helper_ioctl() local
1533 mutex_lock(&fb_helper->lock); in drm_fb_helper_ioctl()
1534 if (!drm_fb_helper_is_bound(fb_helper)) { in drm_fb_helper_ioctl()
1557 mode_set = &fb_helper->crtc_info[0].mode_set; in drm_fb_helper_ioctl()
1578 mutex_unlock(&fb_helper->lock); in drm_fb_helper_ioctl()
1610 struct drm_fb_helper *fb_helper = info->par; in drm_fb_helper_check_var() local
1611 struct drm_framebuffer *fb = fb_helper->fb; in drm_fb_helper_check_var()
1654 struct drm_fb_helper *fb_helper = info->par; in drm_fb_helper_set_par() local
1665 drm_fb_helper_restore_fbdev_mode_unlocked(fb_helper); in drm_fb_helper_set_par()
1671 static void pan_set(struct drm_fb_helper *fb_helper, int x, int y) in pan_set() argument
1675 for (i = 0; i < fb_helper->crtc_count; i++) { in pan_set()
1678 mode_set = &fb_helper->crtc_info[i].mode_set; in pan_set()
1688 struct drm_fb_helper *fb_helper = info->par; in pan_display_atomic() local
1691 pan_set(fb_helper, var->xoffset, var->yoffset); in pan_display_atomic()
1693 ret = restore_fbdev_mode_atomic(fb_helper, true); in pan_display_atomic()
1698 pan_set(fb_helper, info->var.xoffset, info->var.yoffset); in pan_display_atomic()
1706 struct drm_fb_helper *fb_helper = info->par; in pan_display_legacy() local
1711 drm_modeset_lock_all(fb_helper->dev); in pan_display_legacy()
1712 for (i = 0; i < fb_helper->crtc_count; i++) { in pan_display_legacy()
1713 modeset = &fb_helper->crtc_info[i].mode_set; in pan_display_legacy()
1726 drm_modeset_unlock_all(fb_helper->dev); in pan_display_legacy()
1739 struct drm_fb_helper *fb_helper = info->par; in drm_fb_helper_pan_display() local
1740 struct drm_device *dev = fb_helper->dev; in drm_fb_helper_pan_display()
1746 mutex_lock(&fb_helper->lock); in drm_fb_helper_pan_display()
1747 if (!drm_fb_helper_is_bound(fb_helper)) { in drm_fb_helper_pan_display()
1748 mutex_unlock(&fb_helper->lock); in drm_fb_helper_pan_display()
1756 mutex_unlock(&fb_helper->lock); in drm_fb_helper_pan_display()
1766 static int drm_fb_helper_single_fb_probe(struct drm_fb_helper *fb_helper, in drm_fb_helper_single_fb_probe() argument
1786 drm_fb_helper_for_each_connector(fb_helper, i) { in drm_fb_helper_single_fb_probe()
1787 struct drm_fb_helper_connector *fb_helper_conn = fb_helper->connector_info[i]; in drm_fb_helper_single_fb_probe()
1817 for (i = 0; i < fb_helper->crtc_count; i++) { in drm_fb_helper_single_fb_probe()
1827 desired_mode = fb_helper->crtc_info[i].desired_mode; in drm_fb_helper_single_fb_probe()
1828 mode_set = &fb_helper->crtc_info[i].mode_set; in drm_fb_helper_single_fb_probe()
1835 x = fb_helper->crtc_info[i].x; in drm_fb_helper_single_fb_probe()
1836 y = fb_helper->crtc_info[i].y; in drm_fb_helper_single_fb_probe()
1839 gamma_size = fb_helper->crtc_info[i].mode_set.crtc->gamma_size; in drm_fb_helper_single_fb_probe()
1865 if (!fb_helper->deferred_setup && !READ_ONCE(fb_helper->dev->master)) in drm_fb_helper_single_fb_probe()
1866 restore_fbdev_mode(fb_helper); in drm_fb_helper_single_fb_probe()
1875 ret = (*fb_helper->funcs->fb_probe)(fb_helper, &sizes); in drm_fb_helper_single_fb_probe()
1879 strcpy(fb_helper->fb->comm, "[fbcon]"); in drm_fb_helper_single_fb_probe()
1928 void drm_fb_helper_fill_var(struct fb_info *info, struct drm_fb_helper *fb_helper, in drm_fb_helper_fill_var() argument
1931 struct drm_framebuffer *fb = fb_helper->fb; in drm_fb_helper_fill_var()
1933 info->pseudo_palette = fb_helper->pseudo_palette; in drm_fb_helper_fill_var()
2001 static int drm_fb_helper_probe_connector_modes(struct drm_fb_helper *fb_helper, in drm_fb_helper_probe_connector_modes() argument
2008 drm_fb_helper_for_each_connector(fb_helper, i) { in drm_fb_helper_probe_connector_modes()
2009 connector = fb_helper->connector_info[i]->connector; in drm_fb_helper_probe_connector_modes()
2103 static void drm_enable_connectors(struct drm_fb_helper *fb_helper, in drm_enable_connectors() argument
2110 drm_fb_helper_for_each_connector(fb_helper, i) { in drm_enable_connectors()
2111 connector = fb_helper->connector_info[i]->connector; in drm_enable_connectors()
2122 drm_fb_helper_for_each_connector(fb_helper, i) { in drm_enable_connectors()
2123 connector = fb_helper->connector_info[i]->connector; in drm_enable_connectors()
2128 static bool drm_target_cloned(struct drm_fb_helper *fb_helper, in drm_target_cloned() argument
2139 if (fb_helper->crtc_count > 1) in drm_target_cloned()
2143 drm_fb_helper_for_each_connector(fb_helper, i) { in drm_target_cloned()
2154 drm_fb_helper_for_each_connector(fb_helper, i) { in drm_target_cloned()
2157 fb_helper_conn = fb_helper->connector_info[i]; in drm_target_cloned()
2182 dmt_mode = drm_mode_find_dmt(fb_helper->dev, 1024, 768, 60, false); in drm_target_cloned()
2184 drm_fb_helper_for_each_connector(fb_helper, i) { in drm_target_cloned()
2188 fb_helper_conn = fb_helper->connector_info[i]; in drm_target_cloned()
2209 static int drm_get_tile_offsets(struct drm_fb_helper *fb_helper, in drm_get_tile_offsets() argument
2219 drm_fb_helper_for_each_connector(fb_helper, i) { in drm_get_tile_offsets()
2220 fb_helper_conn = fb_helper->connector_info[i]; in drm_get_tile_offsets()
2241 static bool drm_target_preferred(struct drm_fb_helper *fb_helper, in drm_target_preferred() argument
2247 const u64 mask = BIT_ULL(fb_helper->connector_count) - 1; in drm_target_preferred()
2253 drm_fb_helper_for_each_connector(fb_helper, i) { in drm_target_preferred()
2254 fb_helper_conn = fb_helper->connector_info[i]; in drm_target_preferred()
2283 drm_get_tile_offsets(fb_helper, modes, offsets, in drm_target_preferred()
2327 static int drm_pick_crtcs(struct drm_fb_helper *fb_helper, in drm_pick_crtcs() argument
2338 if (n == fb_helper->connector_count) in drm_pick_crtcs()
2341 fb_helper_conn = fb_helper->connector_info[n]; in drm_pick_crtcs()
2345 best_score = drm_pick_crtcs(fb_helper, best_crtcs, modes, n+1, width, height); in drm_pick_crtcs()
2349 crtcs = kcalloc(fb_helper->connector_count, in drm_pick_crtcs()
2366 for (c = 0; c < fb_helper->crtc_count; c++) { in drm_pick_crtcs()
2367 crtc = &fb_helper->crtc_info[c]; in drm_pick_crtcs()
2379 if (fb_helper->crtc_count > 1) in drm_pick_crtcs()
2388 score = my_score + drm_pick_crtcs(fb_helper, crtcs, modes, n + 1, in drm_pick_crtcs()
2393 fb_helper->connector_count * in drm_pick_crtcs()
2411 static void drm_setup_crtc_rotation(struct drm_fb_helper *fb_helper, in drm_setup_crtc_rotation() argument
2441 fb_helper->sw_rotations |= rotation; in drm_setup_crtc_rotation()
2449 fb_helper->sw_rotations |= rotation; in drm_setup_crtc_rotation()
2455 fb_helper->sw_rotations |= DRM_MODE_ROTATE_0; in drm_setup_crtc_rotation()
2458 static void drm_setup_crtcs(struct drm_fb_helper *fb_helper, in drm_setup_crtcs() argument
2461 struct drm_device *dev = fb_helper->dev; in drm_setup_crtcs()
2470 lockdep_assert_held(&fb_helper->lock); in drm_setup_crtcs()
2472 crtcs = kcalloc(fb_helper->connector_count, in drm_setup_crtcs()
2474 modes = kcalloc(fb_helper->connector_count, in drm_setup_crtcs()
2476 offsets = kcalloc(fb_helper->connector_count, in drm_setup_crtcs()
2478 enabled = kcalloc(fb_helper->connector_count, in drm_setup_crtcs()
2485 mutex_lock(&fb_helper->dev->mode_config.mutex); in drm_setup_crtcs()
2486 if (drm_fb_helper_probe_connector_modes(fb_helper, width, height) == 0) in drm_setup_crtcs()
2488 drm_enable_connectors(fb_helper, enabled); in drm_setup_crtcs()
2490 if (!(fb_helper->funcs->initial_config && in drm_setup_crtcs()
2491 fb_helper->funcs->initial_config(fb_helper, crtcs, modes, in drm_setup_crtcs()
2494 memset(modes, 0, fb_helper->connector_count*sizeof(modes[0])); in drm_setup_crtcs()
2495 memset(crtcs, 0, fb_helper->connector_count*sizeof(crtcs[0])); in drm_setup_crtcs()
2496 memset(offsets, 0, fb_helper->connector_count*sizeof(offsets[0])); in drm_setup_crtcs()
2498 if (!drm_target_cloned(fb_helper, modes, offsets, in drm_setup_crtcs()
2500 !drm_target_preferred(fb_helper, modes, offsets, in drm_setup_crtcs()
2507 drm_pick_crtcs(fb_helper, crtcs, modes, 0, width, height); in drm_setup_crtcs()
2509 mutex_unlock(&fb_helper->dev->mode_config.mutex); in drm_setup_crtcs()
2513 for (i = 0; i < fb_helper->crtc_count; i++) in drm_setup_crtcs()
2514 drm_fb_helper_modeset_release(fb_helper, in drm_setup_crtcs()
2515 &fb_helper->crtc_info[i].mode_set); in drm_setup_crtcs()
2517 fb_helper->sw_rotations = 0; in drm_setup_crtcs()
2518 drm_fb_helper_for_each_connector(fb_helper, i) { in drm_setup_crtcs()
2526 fb_helper->connector_info[i]->connector; in drm_setup_crtcs()
2537 drm_setup_crtc_rotation(fb_helper, fb_crtc, connector); in drm_setup_crtcs()
2557 static void drm_setup_crtcs_fb(struct drm_fb_helper *fb_helper) in drm_setup_crtcs_fb() argument
2559 struct fb_info *info = fb_helper->fbdev; in drm_setup_crtcs_fb()
2562 for (i = 0; i < fb_helper->crtc_count; i++) in drm_setup_crtcs_fb()
2563 if (fb_helper->crtc_info[i].mode_set.num_connectors) in drm_setup_crtcs_fb()
2564 fb_helper->crtc_info[i].mode_set.fb = fb_helper->fb; in drm_setup_crtcs_fb()
2566 mutex_lock(&fb_helper->dev->mode_config.mutex); in drm_setup_crtcs_fb()
2567 drm_fb_helper_for_each_connector(fb_helper, i) { in drm_setup_crtcs_fb()
2569 fb_helper->connector_info[i]->connector; in drm_setup_crtcs_fb()
2578 mutex_unlock(&fb_helper->dev->mode_config.mutex); in drm_setup_crtcs_fb()
2580 switch (fb_helper->sw_rotations) { in drm_setup_crtcs_fb()
2605 __drm_fb_helper_initial_config_and_unlock(struct drm_fb_helper *fb_helper, in __drm_fb_helper_initial_config_and_unlock() argument
2608 struct drm_device *dev = fb_helper->dev; in __drm_fb_helper_initial_config_and_unlock()
2616 drm_setup_crtcs(fb_helper, width, height); in __drm_fb_helper_initial_config_and_unlock()
2617 ret = drm_fb_helper_single_fb_probe(fb_helper, bpp_sel); in __drm_fb_helper_initial_config_and_unlock()
2620 fb_helper->preferred_bpp = bpp_sel; in __drm_fb_helper_initial_config_and_unlock()
2621 fb_helper->deferred_setup = true; in __drm_fb_helper_initial_config_and_unlock()
2624 mutex_unlock(&fb_helper->lock); in __drm_fb_helper_initial_config_and_unlock()
2628 drm_setup_crtcs_fb(fb_helper); in __drm_fb_helper_initial_config_and_unlock()
2630 fb_helper->deferred_setup = false; in __drm_fb_helper_initial_config_and_unlock()
2632 info = fb_helper->fbdev; in __drm_fb_helper_initial_config_and_unlock()
2638 mutex_unlock(&fb_helper->lock); in __drm_fb_helper_initial_config_and_unlock()
2651 list_add(&fb_helper->kernel_fb_list, &kernel_fb_helper_list); in __drm_fb_helper_initial_config_and_unlock()
2699 int drm_fb_helper_initial_config(struct drm_fb_helper *fb_helper, int bpp_sel) in drm_fb_helper_initial_config() argument
2706 mutex_lock(&fb_helper->lock); in drm_fb_helper_initial_config()
2707 ret = __drm_fb_helper_initial_config_and_unlock(fb_helper, bpp_sel); in drm_fb_helper_initial_config()
2734 int drm_fb_helper_hotplug_event(struct drm_fb_helper *fb_helper) in drm_fb_helper_hotplug_event() argument
2738 if (!drm_fbdev_emulation || !fb_helper) in drm_fb_helper_hotplug_event()
2741 mutex_lock(&fb_helper->lock); in drm_fb_helper_hotplug_event()
2742 if (fb_helper->deferred_setup) { in drm_fb_helper_hotplug_event()
2743 err = __drm_fb_helper_initial_config_and_unlock(fb_helper, in drm_fb_helper_hotplug_event()
2744 fb_helper->preferred_bpp); in drm_fb_helper_hotplug_event()
2748 if (!fb_helper->fb || !drm_fb_helper_is_bound(fb_helper)) { in drm_fb_helper_hotplug_event()
2749 fb_helper->delayed_hotplug = true; in drm_fb_helper_hotplug_event()
2750 mutex_unlock(&fb_helper->lock); in drm_fb_helper_hotplug_event()
2756 drm_setup_crtcs(fb_helper, fb_helper->fb->width, fb_helper->fb->height); in drm_fb_helper_hotplug_event()
2757 drm_setup_crtcs_fb(fb_helper); in drm_fb_helper_hotplug_event()
2758 mutex_unlock(&fb_helper->lock); in drm_fb_helper_hotplug_event()
2760 drm_fb_helper_set_par(fb_helper->fbdev); in drm_fb_helper_hotplug_event()
2788 struct drm_fb_helper *fb_helper, in drm_fb_helper_fbdev_setup() argument
2807 drm_fb_helper_prepare(dev, fb_helper, funcs); in drm_fb_helper_fbdev_setup()
2809 ret = drm_fb_helper_init(dev, fb_helper, max_conn_count); in drm_fb_helper_fbdev_setup()
2815 ret = drm_fb_helper_single_add_all_connectors(fb_helper); in drm_fb_helper_fbdev_setup()
2824 ret = drm_fb_helper_initial_config(fb_helper, preferred_bpp); in drm_fb_helper_fbdev_setup()
2833 drm_fb_helper_fini(fb_helper); in drm_fb_helper_fbdev_setup()
2856 struct drm_fb_helper *fb_helper = dev->fb_helper; in drm_fb_helper_fbdev_teardown() local
2859 if (!fb_helper) in drm_fb_helper_fbdev_teardown()
2863 if (fb_helper->fbdev && fb_helper->fbdev->dev) in drm_fb_helper_fbdev_teardown()
2864 drm_fb_helper_unregister_fbi(fb_helper); in drm_fb_helper_fbdev_teardown()
2866 if (fb_helper->fbdev && fb_helper->fbdev->fbdefio) { in drm_fb_helper_fbdev_teardown()
2867 fb_deferred_io_cleanup(fb_helper->fbdev); in drm_fb_helper_fbdev_teardown()
2868 kfree(fb_helper->fbdev->fbdefio); in drm_fb_helper_fbdev_teardown()
2869 fbops = fb_helper->fbdev->fbops; in drm_fb_helper_fbdev_teardown()
2872 drm_fb_helper_fini(fb_helper); in drm_fb_helper_fbdev_teardown()
2875 if (fb_helper->fb) in drm_fb_helper_fbdev_teardown()
2876 drm_framebuffer_remove(fb_helper->fb); in drm_fb_helper_fbdev_teardown()
2889 drm_fb_helper_restore_fbdev_mode_unlocked(dev->fb_helper); in drm_fb_helper_lastclose()
2904 drm_fb_helper_hotplug_event(dev->fb_helper); in drm_fb_helper_output_poll_changed()
2911 struct drm_fb_helper *fb_helper = info->par; in drm_fbdev_fb_open() local
2913 if (!try_module_get(fb_helper->dev->driver->fops->owner)) in drm_fbdev_fb_open()
2921 struct drm_fb_helper *fb_helper = info->par; in drm_fbdev_fb_release() local
2923 module_put(fb_helper->dev->driver->fops->owner); in drm_fbdev_fb_release()
2934 struct drm_fb_helper *fb_helper = info->par; in drm_fbdev_fb_destroy() local
2935 struct fb_info *fbi = fb_helper->fbdev; in drm_fbdev_fb_destroy()
2945 drm_fb_helper_fini(fb_helper); in drm_fbdev_fb_destroy()
2952 drm_client_framebuffer_delete(fb_helper->buffer); in drm_fbdev_fb_destroy()
2958 if (fb_helper->client.funcs) { in drm_fbdev_fb_destroy()
2959 drm_client_release(&fb_helper->client); in drm_fbdev_fb_destroy()
2960 kfree(fb_helper); in drm_fbdev_fb_destroy()
2966 struct drm_fb_helper *fb_helper = info->par; in drm_fbdev_fb_mmap() local
2968 if (fb_helper->dev->driver->gem_prime_mmap) in drm_fbdev_fb_mmap()
2969 return fb_helper->dev->driver->gem_prime_mmap(fb_helper->buffer->gem, vma); in drm_fbdev_fb_mmap()
3006 int drm_fb_helper_generic_probe(struct drm_fb_helper *fb_helper, in drm_fb_helper_generic_probe() argument
3009 struct drm_client_dev *client = &fb_helper->client; in drm_fb_helper_generic_probe()
3026 fb_helper->buffer = buffer; in drm_fb_helper_generic_probe()
3027 fb_helper->fb = buffer->fb; in drm_fb_helper_generic_probe()
3030 fbi = drm_fb_helper_alloc_fbi(fb_helper); in drm_fb_helper_generic_probe()
3036 fbi->par = fb_helper; in drm_fb_helper_generic_probe()
3044 drm_fb_helper_fill_var(fbi, fb_helper, sizes->fb_width, sizes->fb_height); in drm_fb_helper_generic_probe()
3074 drm_fb_helper_fini(fb_helper); in drm_fb_helper_generic_probe()
3088 struct drm_fb_helper *fb_helper = drm_fb_helper_from_client(client); in drm_fbdev_client_unregister() local
3090 if (fb_helper->fbdev) { in drm_fbdev_client_unregister()
3091 drm_fb_helper_unregister_fbi(fb_helper); in drm_fbdev_client_unregister()
3097 if (fb_helper->dev) in drm_fbdev_client_unregister()
3098 drm_fb_helper_fini(fb_helper); in drm_fbdev_client_unregister()
3101 kfree(fb_helper); in drm_fbdev_client_unregister()
3106 struct drm_fb_helper *fb_helper = drm_fb_helper_from_client(client); in drm_fbdev_client_restore() local
3108 drm_fb_helper_restore_fbdev_mode_unlocked(fb_helper); in drm_fbdev_client_restore()
3115 struct drm_fb_helper *fb_helper = drm_fb_helper_from_client(client); in drm_fbdev_client_hotplug() local
3120 if (!fb_helper->dev && fb_helper->funcs) in drm_fbdev_client_hotplug()
3123 if (dev->fb_helper) in drm_fbdev_client_hotplug()
3124 return drm_fb_helper_hotplug_event(dev->fb_helper); in drm_fbdev_client_hotplug()
3129 ret = drm_fb_helper_fbdev_setup(dev, fb_helper, &drm_fb_helper_generic_funcs, in drm_fbdev_client_hotplug()
3130 fb_helper->preferred_bpp, 0); in drm_fbdev_client_hotplug()
3132 fb_helper->dev = NULL; in drm_fbdev_client_hotplug()
3133 fb_helper->fbdev = NULL; in drm_fbdev_client_hotplug()
3172 struct drm_fb_helper *fb_helper; in drm_fbdev_generic_setup() local
3178 fb_helper = kzalloc(sizeof(*fb_helper), GFP_KERNEL); in drm_fbdev_generic_setup()
3179 if (!fb_helper) in drm_fbdev_generic_setup()
3182 ret = drm_client_init(dev, &fb_helper->client, "fbdev", &drm_fbdev_client_funcs); in drm_fbdev_generic_setup()
3184 kfree(fb_helper); in drm_fbdev_generic_setup()
3188 drm_client_add(&fb_helper->client); in drm_fbdev_generic_setup()
3190 fb_helper->preferred_bpp = preferred_bpp; in drm_fbdev_generic_setup()
3192 drm_fbdev_client_hotplug(&fb_helper->client); in drm_fbdev_generic_setup()