1 /* 2 * Copyright (c) 2006-2009 Red Hat Inc. 3 * Copyright (c) 2006-2008 Intel Corporation 4 * Copyright (c) 2007 Dave Airlie <airlied@linux.ie> 5 * 6 * DRM framebuffer helper functions 7 * 8 * Permission to use, copy, modify, distribute, and sell this software and its 9 * documentation for any purpose is hereby granted without fee, provided that 10 * the above copyright notice appear in all copies and that both that copyright 11 * notice and this permission notice appear in supporting documentation, and 12 * that the name of the copyright holders not be used in advertising or 13 * publicity pertaining to distribution of the software without specific, 14 * written prior permission. The copyright holders make no representations 15 * about the suitability of this software for any purpose. It is provided "as 16 * is" without express or implied warranty. 17 * 18 * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 19 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 20 * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR 21 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 22 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 23 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 24 * OF THIS SOFTWARE. 25 * 26 * Authors: 27 * Dave Airlie <airlied@linux.ie> 28 * Jesse Barnes <jesse.barnes@intel.com> 29 */ 30 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 31 32 #include <linux/console.h> 33 #include <linux/dma-buf.h> 34 #include <linux/kernel.h> 35 #include <linux/sysrq.h> 36 #include <linux/slab.h> 37 #include <linux/module.h> 38 #include <drm/drmP.h> 39 #include <drm/drm_crtc.h> 40 #include <drm/drm_fb_helper.h> 41 #include <drm/drm_crtc_helper.h> 42 #include <drm/drm_atomic.h> 43 #include <drm/drm_atomic_helper.h> 44 45 #include "drm_crtc_internal.h" 46 #include "drm_crtc_helper_internal.h" 47 48 static bool drm_fbdev_emulation = true; 49 module_param_named(fbdev_emulation, drm_fbdev_emulation, bool, 0600); 50 MODULE_PARM_DESC(fbdev_emulation, 51 "Enable legacy fbdev emulation [default=true]"); 52 53 static int drm_fbdev_overalloc = CONFIG_DRM_FBDEV_OVERALLOC; 54 module_param(drm_fbdev_overalloc, int, 0444); 55 MODULE_PARM_DESC(drm_fbdev_overalloc, 56 "Overallocation of the fbdev buffer (%) [default=" 57 __MODULE_STRING(CONFIG_DRM_FBDEV_OVERALLOC) "]"); 58 59 static LIST_HEAD(kernel_fb_helper_list); 60 static DEFINE_MUTEX(kernel_fb_helper_lock); 61 62 /** 63 * DOC: fbdev helpers 64 * 65 * The fb helper functions are useful to provide an fbdev on top of a drm kernel 66 * mode setting driver. They can be used mostly independently from the crtc 67 * helper functions used by many drivers to implement the kernel mode setting 68 * interfaces. 69 * 70 * Drivers that support a dumb buffer with a virtual address and mmap support, 71 * should try out the generic fbdev emulation using drm_fbdev_generic_setup(). 72 * 73 * Setup fbdev emulation by calling drm_fb_helper_fbdev_setup() and tear it 74 * down by calling drm_fb_helper_fbdev_teardown(). 75 * 76 * Drivers that need to handle connector hotplugging (e.g. dp mst) can't use 77 * the setup helper and will need to do the whole four-step setup process with 78 * drm_fb_helper_prepare(), drm_fb_helper_init(), 79 * drm_fb_helper_single_add_all_connectors(), enable hotplugging and 80 * drm_fb_helper_initial_config() to avoid a possible race window. 81 * 82 * At runtime drivers should restore the fbdev console by using 83 * drm_fb_helper_lastclose() as their &drm_driver.lastclose callback. 84 * They should also notify the fb helper code from updates to the output 85 * configuration by using drm_fb_helper_output_poll_changed() as their 86 * &drm_mode_config_funcs.output_poll_changed callback. 87 * 88 * For suspend/resume consider using drm_mode_config_helper_suspend() and 89 * drm_mode_config_helper_resume() which takes care of fbdev as well. 90 * 91 * All other functions exported by the fb helper library can be used to 92 * implement the fbdev driver interface by the driver. 93 * 94 * It is possible, though perhaps somewhat tricky, to implement race-free 95 * hotplug detection using the fbdev helpers. The drm_fb_helper_prepare() 96 * helper must be called first to initialize the minimum required to make 97 * hotplug detection work. Drivers also need to make sure to properly set up 98 * the &drm_mode_config.funcs member. After calling drm_kms_helper_poll_init() 99 * it is safe to enable interrupts and start processing hotplug events. At the 100 * same time, drivers should initialize all modeset objects such as CRTCs, 101 * encoders and connectors. To finish up the fbdev helper initialization, the 102 * drm_fb_helper_init() function is called. To probe for all attached displays 103 * and set up an initial configuration using the detected hardware, drivers 104 * should call drm_fb_helper_single_add_all_connectors() followed by 105 * drm_fb_helper_initial_config(). 106 * 107 * If &drm_framebuffer_funcs.dirty is set, the 108 * drm_fb_helper_{cfb,sys}_{write,fillrect,copyarea,imageblit} functions will 109 * accumulate changes and schedule &drm_fb_helper.dirty_work to run right 110 * away. This worker then calls the dirty() function ensuring that it will 111 * always run in process context since the fb_*() function could be running in 112 * atomic context. If drm_fb_helper_deferred_io() is used as the deferred_io 113 * callback it will also schedule dirty_work with the damage collected from the 114 * mmap page writes. Drivers can use drm_fb_helper_defio_init() to setup 115 * deferred I/O (coupled with drm_fb_helper_fbdev_teardown()). 116 */ 117 118 #define drm_fb_helper_for_each_connector(fbh, i__) \ 119 for (({ lockdep_assert_held(&(fbh)->lock); }), \ 120 i__ = 0; i__ < (fbh)->connector_count; i__++) 121 122 static int __drm_fb_helper_add_one_connector(struct drm_fb_helper *fb_helper, 123 struct drm_connector *connector) 124 { 125 struct drm_fb_helper_connector *fb_conn; 126 struct drm_fb_helper_connector **temp; 127 unsigned int count; 128 129 if (!drm_fbdev_emulation) 130 return 0; 131 132 lockdep_assert_held(&fb_helper->lock); 133 134 count = fb_helper->connector_count + 1; 135 136 if (count > fb_helper->connector_info_alloc_count) { 137 size_t size = count * sizeof(fb_conn); 138 139 temp = krealloc(fb_helper->connector_info, size, GFP_KERNEL); 140 if (!temp) 141 return -ENOMEM; 142 143 fb_helper->connector_info_alloc_count = count; 144 fb_helper->connector_info = temp; 145 } 146 147 fb_conn = kzalloc(sizeof(*fb_conn), GFP_KERNEL); 148 if (!fb_conn) 149 return -ENOMEM; 150 151 drm_connector_get(connector); 152 fb_conn->connector = connector; 153 fb_helper->connector_info[fb_helper->connector_count++] = fb_conn; 154 155 return 0; 156 } 157 158 int drm_fb_helper_add_one_connector(struct drm_fb_helper *fb_helper, 159 struct drm_connector *connector) 160 { 161 int err; 162 163 if (!fb_helper) 164 return 0; 165 166 mutex_lock(&fb_helper->lock); 167 err = __drm_fb_helper_add_one_connector(fb_helper, connector); 168 mutex_unlock(&fb_helper->lock); 169 170 return err; 171 } 172 EXPORT_SYMBOL(drm_fb_helper_add_one_connector); 173 174 /** 175 * drm_fb_helper_single_add_all_connectors() - add all connectors to fbdev 176 * emulation helper 177 * @fb_helper: fbdev initialized with drm_fb_helper_init, can be NULL 178 * 179 * This functions adds all the available connectors for use with the given 180 * fb_helper. This is a separate step to allow drivers to freely assign 181 * connectors to the fbdev, e.g. if some are reserved for special purposes or 182 * not adequate to be used for the fbcon. 183 * 184 * This function is protected against concurrent connector hotadds/removals 185 * using drm_fb_helper_add_one_connector() and 186 * drm_fb_helper_remove_one_connector(). 187 */ 188 int drm_fb_helper_single_add_all_connectors(struct drm_fb_helper *fb_helper) 189 { 190 struct drm_device *dev; 191 struct drm_connector *connector; 192 struct drm_connector_list_iter conn_iter; 193 int i, ret = 0; 194 195 if (!drm_fbdev_emulation || !fb_helper) 196 return 0; 197 198 dev = fb_helper->dev; 199 200 mutex_lock(&fb_helper->lock); 201 drm_connector_list_iter_begin(dev, &conn_iter); 202 drm_for_each_connector_iter(connector, &conn_iter) { 203 ret = __drm_fb_helper_add_one_connector(fb_helper, connector); 204 if (ret) 205 goto fail; 206 } 207 goto out; 208 209 fail: 210 drm_fb_helper_for_each_connector(fb_helper, i) { 211 struct drm_fb_helper_connector *fb_helper_connector = 212 fb_helper->connector_info[i]; 213 214 drm_connector_put(fb_helper_connector->connector); 215 216 kfree(fb_helper_connector); 217 fb_helper->connector_info[i] = NULL; 218 } 219 fb_helper->connector_count = 0; 220 out: 221 drm_connector_list_iter_end(&conn_iter); 222 mutex_unlock(&fb_helper->lock); 223 224 return ret; 225 } 226 EXPORT_SYMBOL(drm_fb_helper_single_add_all_connectors); 227 228 static int __drm_fb_helper_remove_one_connector(struct drm_fb_helper *fb_helper, 229 struct drm_connector *connector) 230 { 231 struct drm_fb_helper_connector *fb_helper_connector; 232 int i, j; 233 234 if (!drm_fbdev_emulation) 235 return 0; 236 237 lockdep_assert_held(&fb_helper->lock); 238 239 drm_fb_helper_for_each_connector(fb_helper, i) { 240 if (fb_helper->connector_info[i]->connector == connector) 241 break; 242 } 243 244 if (i == fb_helper->connector_count) 245 return -EINVAL; 246 fb_helper_connector = fb_helper->connector_info[i]; 247 drm_connector_put(fb_helper_connector->connector); 248 249 for (j = i + 1; j < fb_helper->connector_count; j++) 250 fb_helper->connector_info[j - 1] = fb_helper->connector_info[j]; 251 252 fb_helper->connector_count--; 253 kfree(fb_helper_connector); 254 255 return 0; 256 } 257 258 int drm_fb_helper_remove_one_connector(struct drm_fb_helper *fb_helper, 259 struct drm_connector *connector) 260 { 261 int err; 262 263 if (!fb_helper) 264 return 0; 265 266 mutex_lock(&fb_helper->lock); 267 err = __drm_fb_helper_remove_one_connector(fb_helper, connector); 268 mutex_unlock(&fb_helper->lock); 269 270 return err; 271 } 272 EXPORT_SYMBOL(drm_fb_helper_remove_one_connector); 273 274 static void drm_fb_helper_restore_lut_atomic(struct drm_crtc *crtc) 275 { 276 uint16_t *r_base, *g_base, *b_base; 277 278 if (crtc->funcs->gamma_set == NULL) 279 return; 280 281 r_base = crtc->gamma_store; 282 g_base = r_base + crtc->gamma_size; 283 b_base = g_base + crtc->gamma_size; 284 285 crtc->funcs->gamma_set(crtc, r_base, g_base, b_base, 286 crtc->gamma_size, NULL); 287 } 288 289 /** 290 * drm_fb_helper_debug_enter - implementation for &fb_ops.fb_debug_enter 291 * @info: fbdev registered by the helper 292 */ 293 int drm_fb_helper_debug_enter(struct fb_info *info) 294 { 295 struct drm_fb_helper *helper = info->par; 296 const struct drm_crtc_helper_funcs *funcs; 297 int i; 298 299 list_for_each_entry(helper, &kernel_fb_helper_list, kernel_fb_list) { 300 for (i = 0; i < helper->crtc_count; i++) { 301 struct drm_mode_set *mode_set = 302 &helper->crtc_info[i].mode_set; 303 304 if (!mode_set->crtc->enabled) 305 continue; 306 307 funcs = mode_set->crtc->helper_private; 308 if (funcs->mode_set_base_atomic == NULL) 309 continue; 310 311 if (drm_drv_uses_atomic_modeset(mode_set->crtc->dev)) 312 continue; 313 314 funcs->mode_set_base_atomic(mode_set->crtc, 315 mode_set->fb, 316 mode_set->x, 317 mode_set->y, 318 ENTER_ATOMIC_MODE_SET); 319 } 320 } 321 322 return 0; 323 } 324 EXPORT_SYMBOL(drm_fb_helper_debug_enter); 325 326 /** 327 * drm_fb_helper_debug_leave - implementation for &fb_ops.fb_debug_leave 328 * @info: fbdev registered by the helper 329 */ 330 int drm_fb_helper_debug_leave(struct fb_info *info) 331 { 332 struct drm_fb_helper *helper = info->par; 333 struct drm_crtc *crtc; 334 const struct drm_crtc_helper_funcs *funcs; 335 struct drm_framebuffer *fb; 336 int i; 337 338 for (i = 0; i < helper->crtc_count; i++) { 339 struct drm_mode_set *mode_set = &helper->crtc_info[i].mode_set; 340 341 crtc = mode_set->crtc; 342 if (drm_drv_uses_atomic_modeset(crtc->dev)) 343 continue; 344 345 funcs = crtc->helper_private; 346 fb = crtc->primary->fb; 347 348 if (!crtc->enabled) 349 continue; 350 351 if (!fb) { 352 DRM_ERROR("no fb to restore??\n"); 353 continue; 354 } 355 356 if (funcs->mode_set_base_atomic == NULL) 357 continue; 358 359 drm_fb_helper_restore_lut_atomic(mode_set->crtc); 360 funcs->mode_set_base_atomic(mode_set->crtc, fb, crtc->x, 361 crtc->y, LEAVE_ATOMIC_MODE_SET); 362 } 363 364 return 0; 365 } 366 EXPORT_SYMBOL(drm_fb_helper_debug_leave); 367 368 static int restore_fbdev_mode_atomic(struct drm_fb_helper *fb_helper, bool active) 369 { 370 struct drm_device *dev = fb_helper->dev; 371 struct drm_plane_state *plane_state; 372 struct drm_plane *plane; 373 struct drm_atomic_state *state; 374 int i, ret; 375 struct drm_modeset_acquire_ctx ctx; 376 377 drm_modeset_acquire_init(&ctx, 0); 378 379 state = drm_atomic_state_alloc(dev); 380 if (!state) { 381 ret = -ENOMEM; 382 goto out_ctx; 383 } 384 385 state->acquire_ctx = &ctx; 386 retry: 387 drm_for_each_plane(plane, dev) { 388 plane_state = drm_atomic_get_plane_state(state, plane); 389 if (IS_ERR(plane_state)) { 390 ret = PTR_ERR(plane_state); 391 goto out_state; 392 } 393 394 plane_state->rotation = DRM_MODE_ROTATE_0; 395 396 /* disable non-primary: */ 397 if (plane->type == DRM_PLANE_TYPE_PRIMARY) 398 continue; 399 400 ret = __drm_atomic_helper_disable_plane(plane, plane_state); 401 if (ret != 0) 402 goto out_state; 403 } 404 405 for (i = 0; i < fb_helper->crtc_count; i++) { 406 struct drm_mode_set *mode_set = &fb_helper->crtc_info[i].mode_set; 407 struct drm_plane *primary = mode_set->crtc->primary; 408 409 /* Cannot fail as we've already gotten the plane state above */ 410 plane_state = drm_atomic_get_new_plane_state(state, primary); 411 plane_state->rotation = fb_helper->crtc_info[i].rotation; 412 413 ret = __drm_atomic_helper_set_config(mode_set, state); 414 if (ret != 0) 415 goto out_state; 416 417 /* 418 * __drm_atomic_helper_set_config() sets active when a 419 * mode is set, unconditionally clear it if we force DPMS off 420 */ 421 if (!active) { 422 struct drm_crtc *crtc = mode_set->crtc; 423 struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state, crtc); 424 425 crtc_state->active = false; 426 } 427 } 428 429 ret = drm_atomic_commit(state); 430 431 out_state: 432 if (ret == -EDEADLK) 433 goto backoff; 434 435 drm_atomic_state_put(state); 436 out_ctx: 437 drm_modeset_drop_locks(&ctx); 438 drm_modeset_acquire_fini(&ctx); 439 440 return ret; 441 442 backoff: 443 drm_atomic_state_clear(state); 444 drm_modeset_backoff(&ctx); 445 446 goto retry; 447 } 448 449 static int restore_fbdev_mode_legacy(struct drm_fb_helper *fb_helper) 450 { 451 struct drm_device *dev = fb_helper->dev; 452 struct drm_plane *plane; 453 int i, ret = 0; 454 455 drm_modeset_lock_all(fb_helper->dev); 456 drm_for_each_plane(plane, dev) { 457 if (plane->type != DRM_PLANE_TYPE_PRIMARY) 458 drm_plane_force_disable(plane); 459 460 if (plane->rotation_property) 461 drm_mode_plane_set_obj_prop(plane, 462 plane->rotation_property, 463 DRM_MODE_ROTATE_0); 464 } 465 466 for (i = 0; i < fb_helper->crtc_count; i++) { 467 struct drm_mode_set *mode_set = &fb_helper->crtc_info[i].mode_set; 468 struct drm_crtc *crtc = mode_set->crtc; 469 470 if (crtc->funcs->cursor_set2) { 471 ret = crtc->funcs->cursor_set2(crtc, NULL, 0, 0, 0, 0, 0); 472 if (ret) 473 goto out; 474 } else if (crtc->funcs->cursor_set) { 475 ret = crtc->funcs->cursor_set(crtc, NULL, 0, 0, 0); 476 if (ret) 477 goto out; 478 } 479 480 ret = drm_mode_set_config_internal(mode_set); 481 if (ret) 482 goto out; 483 } 484 out: 485 drm_modeset_unlock_all(fb_helper->dev); 486 487 return ret; 488 } 489 490 static int restore_fbdev_mode(struct drm_fb_helper *fb_helper) 491 { 492 struct drm_device *dev = fb_helper->dev; 493 494 if (drm_drv_uses_atomic_modeset(dev)) 495 return restore_fbdev_mode_atomic(fb_helper, true); 496 else 497 return restore_fbdev_mode_legacy(fb_helper); 498 } 499 500 /** 501 * drm_fb_helper_restore_fbdev_mode_unlocked - restore fbdev configuration 502 * @fb_helper: driver-allocated fbdev helper, can be NULL 503 * 504 * This should be called from driver's drm &drm_driver.lastclose callback 505 * when implementing an fbcon on top of kms using this helper. This ensures that 506 * the user isn't greeted with a black screen when e.g. X dies. 507 * 508 * RETURNS: 509 * Zero if everything went ok, negative error code otherwise. 510 */ 511 int drm_fb_helper_restore_fbdev_mode_unlocked(struct drm_fb_helper *fb_helper) 512 { 513 bool do_delayed; 514 int ret; 515 516 if (!drm_fbdev_emulation || !fb_helper) 517 return -ENODEV; 518 519 if (READ_ONCE(fb_helper->deferred_setup)) 520 return 0; 521 522 mutex_lock(&fb_helper->lock); 523 ret = restore_fbdev_mode(fb_helper); 524 525 do_delayed = fb_helper->delayed_hotplug; 526 if (do_delayed) 527 fb_helper->delayed_hotplug = false; 528 mutex_unlock(&fb_helper->lock); 529 530 if (do_delayed) 531 drm_fb_helper_hotplug_event(fb_helper); 532 533 return ret; 534 } 535 EXPORT_SYMBOL(drm_fb_helper_restore_fbdev_mode_unlocked); 536 537 static bool drm_fb_helper_is_bound(struct drm_fb_helper *fb_helper) 538 { 539 struct drm_device *dev = fb_helper->dev; 540 struct drm_crtc *crtc; 541 int bound = 0, crtcs_bound = 0; 542 543 /* 544 * Sometimes user space wants everything disabled, so don't steal the 545 * display if there's a master. 546 */ 547 if (READ_ONCE(dev->master)) 548 return false; 549 550 drm_for_each_crtc(crtc, dev) { 551 drm_modeset_lock(&crtc->mutex, NULL); 552 if (crtc->primary->fb) 553 crtcs_bound++; 554 if (crtc->primary->fb == fb_helper->fb) 555 bound++; 556 drm_modeset_unlock(&crtc->mutex); 557 } 558 559 if (bound < crtcs_bound) 560 return false; 561 562 return true; 563 } 564 565 #ifdef CONFIG_MAGIC_SYSRQ 566 /* 567 * restore fbcon display for all kms driver's using this helper, used for sysrq 568 * and panic handling. 569 */ 570 static bool drm_fb_helper_force_kernel_mode(void) 571 { 572 bool ret, error = false; 573 struct drm_fb_helper *helper; 574 575 if (list_empty(&kernel_fb_helper_list)) 576 return false; 577 578 list_for_each_entry(helper, &kernel_fb_helper_list, kernel_fb_list) { 579 struct drm_device *dev = helper->dev; 580 581 if (dev->switch_power_state == DRM_SWITCH_POWER_OFF) 582 continue; 583 584 mutex_lock(&helper->lock); 585 ret = restore_fbdev_mode(helper); 586 if (ret) 587 error = true; 588 mutex_unlock(&helper->lock); 589 } 590 return error; 591 } 592 593 static void drm_fb_helper_restore_work_fn(struct work_struct *ignored) 594 { 595 bool ret; 596 597 ret = drm_fb_helper_force_kernel_mode(); 598 if (ret == true) 599 DRM_ERROR("Failed to restore crtc configuration\n"); 600 } 601 static DECLARE_WORK(drm_fb_helper_restore_work, drm_fb_helper_restore_work_fn); 602 603 static void drm_fb_helper_sysrq(int dummy1) 604 { 605 schedule_work(&drm_fb_helper_restore_work); 606 } 607 608 static struct sysrq_key_op sysrq_drm_fb_helper_restore_op = { 609 .handler = drm_fb_helper_sysrq, 610 .help_msg = "force-fb(V)", 611 .action_msg = "Restore framebuffer console", 612 }; 613 #else 614 static struct sysrq_key_op sysrq_drm_fb_helper_restore_op = { }; 615 #endif 616 617 static void dpms_legacy(struct drm_fb_helper *fb_helper, int dpms_mode) 618 { 619 struct drm_device *dev = fb_helper->dev; 620 struct drm_crtc *crtc; 621 struct drm_connector *connector; 622 int i, j; 623 624 drm_modeset_lock_all(dev); 625 for (i = 0; i < fb_helper->crtc_count; i++) { 626 crtc = fb_helper->crtc_info[i].mode_set.crtc; 627 628 if (!crtc->enabled) 629 continue; 630 631 /* Walk the connectors & encoders on this fb turning them on/off */ 632 drm_fb_helper_for_each_connector(fb_helper, j) { 633 connector = fb_helper->connector_info[j]->connector; 634 connector->funcs->dpms(connector, dpms_mode); 635 drm_object_property_set_value(&connector->base, 636 dev->mode_config.dpms_property, dpms_mode); 637 } 638 } 639 drm_modeset_unlock_all(dev); 640 } 641 642 static void drm_fb_helper_dpms(struct fb_info *info, int dpms_mode) 643 { 644 struct drm_fb_helper *fb_helper = info->par; 645 646 /* 647 * For each CRTC in this fb, turn the connectors on/off. 648 */ 649 mutex_lock(&fb_helper->lock); 650 if (!drm_fb_helper_is_bound(fb_helper)) { 651 mutex_unlock(&fb_helper->lock); 652 return; 653 } 654 655 if (drm_drv_uses_atomic_modeset(fb_helper->dev)) 656 restore_fbdev_mode_atomic(fb_helper, dpms_mode == DRM_MODE_DPMS_ON); 657 else 658 dpms_legacy(fb_helper, dpms_mode); 659 mutex_unlock(&fb_helper->lock); 660 } 661 662 /** 663 * drm_fb_helper_blank - implementation for &fb_ops.fb_blank 664 * @blank: desired blanking state 665 * @info: fbdev registered by the helper 666 */ 667 int drm_fb_helper_blank(int blank, struct fb_info *info) 668 { 669 if (oops_in_progress) 670 return -EBUSY; 671 672 switch (blank) { 673 /* Display: On; HSync: On, VSync: On */ 674 case FB_BLANK_UNBLANK: 675 drm_fb_helper_dpms(info, DRM_MODE_DPMS_ON); 676 break; 677 /* Display: Off; HSync: On, VSync: On */ 678 case FB_BLANK_NORMAL: 679 drm_fb_helper_dpms(info, DRM_MODE_DPMS_STANDBY); 680 break; 681 /* Display: Off; HSync: Off, VSync: On */ 682 case FB_BLANK_HSYNC_SUSPEND: 683 drm_fb_helper_dpms(info, DRM_MODE_DPMS_STANDBY); 684 break; 685 /* Display: Off; HSync: On, VSync: Off */ 686 case FB_BLANK_VSYNC_SUSPEND: 687 drm_fb_helper_dpms(info, DRM_MODE_DPMS_SUSPEND); 688 break; 689 /* Display: Off; HSync: Off, VSync: Off */ 690 case FB_BLANK_POWERDOWN: 691 drm_fb_helper_dpms(info, DRM_MODE_DPMS_OFF); 692 break; 693 } 694 return 0; 695 } 696 EXPORT_SYMBOL(drm_fb_helper_blank); 697 698 static void drm_fb_helper_modeset_release(struct drm_fb_helper *helper, 699 struct drm_mode_set *modeset) 700 { 701 int i; 702 703 for (i = 0; i < modeset->num_connectors; i++) { 704 drm_connector_put(modeset->connectors[i]); 705 modeset->connectors[i] = NULL; 706 } 707 modeset->num_connectors = 0; 708 709 drm_mode_destroy(helper->dev, modeset->mode); 710 modeset->mode = NULL; 711 712 /* FIXME should hold a ref? */ 713 modeset->fb = NULL; 714 } 715 716 static void drm_fb_helper_crtc_free(struct drm_fb_helper *helper) 717 { 718 int i; 719 720 for (i = 0; i < helper->connector_count; i++) { 721 drm_connector_put(helper->connector_info[i]->connector); 722 kfree(helper->connector_info[i]); 723 } 724 kfree(helper->connector_info); 725 726 for (i = 0; i < helper->crtc_count; i++) { 727 struct drm_mode_set *modeset = &helper->crtc_info[i].mode_set; 728 729 drm_fb_helper_modeset_release(helper, modeset); 730 kfree(modeset->connectors); 731 } 732 kfree(helper->crtc_info); 733 } 734 735 static void drm_fb_helper_resume_worker(struct work_struct *work) 736 { 737 struct drm_fb_helper *helper = container_of(work, struct drm_fb_helper, 738 resume_work); 739 740 console_lock(); 741 fb_set_suspend(helper->fbdev, 0); 742 console_unlock(); 743 } 744 745 static void drm_fb_helper_dirty_blit_real(struct drm_fb_helper *fb_helper, 746 struct drm_clip_rect *clip) 747 { 748 struct drm_framebuffer *fb = fb_helper->fb; 749 unsigned int cpp = drm_format_plane_cpp(fb->format->format, 0); 750 size_t offset = clip->y1 * fb->pitches[0] + clip->x1 * cpp; 751 void *src = fb_helper->fbdev->screen_buffer + offset; 752 void *dst = fb_helper->buffer->vaddr + offset; 753 size_t len = (clip->x2 - clip->x1) * cpp; 754 unsigned int y; 755 756 for (y = clip->y1; y < clip->y2; y++) { 757 memcpy(dst, src, len); 758 src += fb->pitches[0]; 759 dst += fb->pitches[0]; 760 } 761 } 762 763 static void drm_fb_helper_dirty_work(struct work_struct *work) 764 { 765 struct drm_fb_helper *helper = container_of(work, struct drm_fb_helper, 766 dirty_work); 767 struct drm_clip_rect *clip = &helper->dirty_clip; 768 struct drm_clip_rect clip_copy; 769 unsigned long flags; 770 771 spin_lock_irqsave(&helper->dirty_lock, flags); 772 clip_copy = *clip; 773 clip->x1 = clip->y1 = ~0; 774 clip->x2 = clip->y2 = 0; 775 spin_unlock_irqrestore(&helper->dirty_lock, flags); 776 777 /* call dirty callback only when it has been really touched */ 778 if (clip_copy.x1 < clip_copy.x2 && clip_copy.y1 < clip_copy.y2) { 779 /* Generic fbdev uses a shadow buffer */ 780 if (helper->buffer) 781 drm_fb_helper_dirty_blit_real(helper, &clip_copy); 782 helper->fb->funcs->dirty(helper->fb, NULL, 0, 0, &clip_copy, 1); 783 } 784 } 785 786 /** 787 * drm_fb_helper_prepare - setup a drm_fb_helper structure 788 * @dev: DRM device 789 * @helper: driver-allocated fbdev helper structure to set up 790 * @funcs: pointer to structure of functions associate with this helper 791 * 792 * Sets up the bare minimum to make the framebuffer helper usable. This is 793 * useful to implement race-free initialization of the polling helpers. 794 */ 795 void drm_fb_helper_prepare(struct drm_device *dev, struct drm_fb_helper *helper, 796 const struct drm_fb_helper_funcs *funcs) 797 { 798 INIT_LIST_HEAD(&helper->kernel_fb_list); 799 spin_lock_init(&helper->dirty_lock); 800 INIT_WORK(&helper->resume_work, drm_fb_helper_resume_worker); 801 INIT_WORK(&helper->dirty_work, drm_fb_helper_dirty_work); 802 helper->dirty_clip.x1 = helper->dirty_clip.y1 = ~0; 803 mutex_init(&helper->lock); 804 helper->funcs = funcs; 805 helper->dev = dev; 806 } 807 EXPORT_SYMBOL(drm_fb_helper_prepare); 808 809 /** 810 * drm_fb_helper_init - initialize a &struct drm_fb_helper 811 * @dev: drm device 812 * @fb_helper: driver-allocated fbdev helper structure to initialize 813 * @max_conn_count: max connector count 814 * 815 * This allocates the structures for the fbdev helper with the given limits. 816 * Note that this won't yet touch the hardware (through the driver interfaces) 817 * nor register the fbdev. This is only done in drm_fb_helper_initial_config() 818 * to allow driver writes more control over the exact init sequence. 819 * 820 * Drivers must call drm_fb_helper_prepare() before calling this function. 821 * 822 * RETURNS: 823 * Zero if everything went ok, nonzero otherwise. 824 */ 825 int drm_fb_helper_init(struct drm_device *dev, 826 struct drm_fb_helper *fb_helper, 827 int max_conn_count) 828 { 829 struct drm_crtc *crtc; 830 struct drm_mode_config *config = &dev->mode_config; 831 int i; 832 833 if (!drm_fbdev_emulation) { 834 dev->fb_helper = fb_helper; 835 return 0; 836 } 837 838 if (!max_conn_count) 839 return -EINVAL; 840 841 fb_helper->crtc_info = kcalloc(config->num_crtc, sizeof(struct drm_fb_helper_crtc), GFP_KERNEL); 842 if (!fb_helper->crtc_info) 843 return -ENOMEM; 844 845 fb_helper->crtc_count = config->num_crtc; 846 fb_helper->connector_info = kcalloc(dev->mode_config.num_connector, sizeof(struct drm_fb_helper_connector *), GFP_KERNEL); 847 if (!fb_helper->connector_info) { 848 kfree(fb_helper->crtc_info); 849 return -ENOMEM; 850 } 851 fb_helper->connector_info_alloc_count = dev->mode_config.num_connector; 852 fb_helper->connector_count = 0; 853 854 for (i = 0; i < fb_helper->crtc_count; i++) { 855 fb_helper->crtc_info[i].mode_set.connectors = 856 kcalloc(max_conn_count, 857 sizeof(struct drm_connector *), 858 GFP_KERNEL); 859 860 if (!fb_helper->crtc_info[i].mode_set.connectors) 861 goto out_free; 862 fb_helper->crtc_info[i].mode_set.num_connectors = 0; 863 fb_helper->crtc_info[i].rotation = DRM_MODE_ROTATE_0; 864 } 865 866 i = 0; 867 drm_for_each_crtc(crtc, dev) { 868 fb_helper->crtc_info[i].mode_set.crtc = crtc; 869 i++; 870 } 871 872 dev->fb_helper = fb_helper; 873 874 return 0; 875 out_free: 876 drm_fb_helper_crtc_free(fb_helper); 877 return -ENOMEM; 878 } 879 EXPORT_SYMBOL(drm_fb_helper_init); 880 881 /** 882 * drm_fb_helper_alloc_fbi - allocate fb_info and some of its members 883 * @fb_helper: driver-allocated fbdev helper 884 * 885 * A helper to alloc fb_info and the members cmap and apertures. Called 886 * by the driver within the fb_probe fb_helper callback function. Drivers do not 887 * need to release the allocated fb_info structure themselves, this is 888 * automatically done when calling drm_fb_helper_fini(). 889 * 890 * RETURNS: 891 * fb_info pointer if things went okay, pointer containing error code 892 * otherwise 893 */ 894 struct fb_info *drm_fb_helper_alloc_fbi(struct drm_fb_helper *fb_helper) 895 { 896 struct device *dev = fb_helper->dev->dev; 897 struct fb_info *info; 898 int ret; 899 900 info = framebuffer_alloc(0, dev); 901 if (!info) 902 return ERR_PTR(-ENOMEM); 903 904 ret = fb_alloc_cmap(&info->cmap, 256, 0); 905 if (ret) 906 goto err_release; 907 908 info->apertures = alloc_apertures(1); 909 if (!info->apertures) { 910 ret = -ENOMEM; 911 goto err_free_cmap; 912 } 913 914 fb_helper->fbdev = info; 915 916 return info; 917 918 err_free_cmap: 919 fb_dealloc_cmap(&info->cmap); 920 err_release: 921 framebuffer_release(info); 922 return ERR_PTR(ret); 923 } 924 EXPORT_SYMBOL(drm_fb_helper_alloc_fbi); 925 926 /** 927 * drm_fb_helper_unregister_fbi - unregister fb_info framebuffer device 928 * @fb_helper: driver-allocated fbdev helper, can be NULL 929 * 930 * A wrapper around unregister_framebuffer, to release the fb_info 931 * framebuffer device. This must be called before releasing all resources for 932 * @fb_helper by calling drm_fb_helper_fini(). 933 */ 934 void drm_fb_helper_unregister_fbi(struct drm_fb_helper *fb_helper) 935 { 936 if (fb_helper && fb_helper->fbdev) 937 unregister_framebuffer(fb_helper->fbdev); 938 } 939 EXPORT_SYMBOL(drm_fb_helper_unregister_fbi); 940 941 /** 942 * drm_fb_helper_fini - finialize a &struct drm_fb_helper 943 * @fb_helper: driver-allocated fbdev helper, can be NULL 944 * 945 * This cleans up all remaining resources associated with @fb_helper. Must be 946 * called after drm_fb_helper_unlink_fbi() was called. 947 */ 948 void drm_fb_helper_fini(struct drm_fb_helper *fb_helper) 949 { 950 struct fb_info *info; 951 952 if (!fb_helper) 953 return; 954 955 fb_helper->dev->fb_helper = NULL; 956 957 if (!drm_fbdev_emulation) 958 return; 959 960 cancel_work_sync(&fb_helper->resume_work); 961 cancel_work_sync(&fb_helper->dirty_work); 962 963 info = fb_helper->fbdev; 964 if (info) { 965 if (info->cmap.len) 966 fb_dealloc_cmap(&info->cmap); 967 framebuffer_release(info); 968 } 969 fb_helper->fbdev = NULL; 970 971 mutex_lock(&kernel_fb_helper_lock); 972 if (!list_empty(&fb_helper->kernel_fb_list)) { 973 list_del(&fb_helper->kernel_fb_list); 974 if (list_empty(&kernel_fb_helper_list)) 975 unregister_sysrq_key('v', &sysrq_drm_fb_helper_restore_op); 976 } 977 mutex_unlock(&kernel_fb_helper_lock); 978 979 mutex_destroy(&fb_helper->lock); 980 drm_fb_helper_crtc_free(fb_helper); 981 982 } 983 EXPORT_SYMBOL(drm_fb_helper_fini); 984 985 /** 986 * drm_fb_helper_unlink_fbi - wrapper around unlink_framebuffer 987 * @fb_helper: driver-allocated fbdev helper, can be NULL 988 * 989 * A wrapper around unlink_framebuffer implemented by fbdev core 990 */ 991 void drm_fb_helper_unlink_fbi(struct drm_fb_helper *fb_helper) 992 { 993 if (fb_helper && fb_helper->fbdev) 994 unlink_framebuffer(fb_helper->fbdev); 995 } 996 EXPORT_SYMBOL(drm_fb_helper_unlink_fbi); 997 998 static void drm_fb_helper_dirty(struct fb_info *info, u32 x, u32 y, 999 u32 width, u32 height) 1000 { 1001 struct drm_fb_helper *helper = info->par; 1002 struct drm_clip_rect *clip = &helper->dirty_clip; 1003 unsigned long flags; 1004 1005 if (!helper->fb->funcs->dirty) 1006 return; 1007 1008 spin_lock_irqsave(&helper->dirty_lock, flags); 1009 clip->x1 = min_t(u32, clip->x1, x); 1010 clip->y1 = min_t(u32, clip->y1, y); 1011 clip->x2 = max_t(u32, clip->x2, x + width); 1012 clip->y2 = max_t(u32, clip->y2, y + height); 1013 spin_unlock_irqrestore(&helper->dirty_lock, flags); 1014 1015 schedule_work(&helper->dirty_work); 1016 } 1017 1018 /** 1019 * drm_fb_helper_deferred_io() - fbdev deferred_io callback function 1020 * @info: fb_info struct pointer 1021 * @pagelist: list of dirty mmap framebuffer pages 1022 * 1023 * This function is used as the &fb_deferred_io.deferred_io 1024 * callback function for flushing the fbdev mmap writes. 1025 */ 1026 void drm_fb_helper_deferred_io(struct fb_info *info, 1027 struct list_head *pagelist) 1028 { 1029 unsigned long start, end, min, max; 1030 struct page *page; 1031 u32 y1, y2; 1032 1033 min = ULONG_MAX; 1034 max = 0; 1035 list_for_each_entry(page, pagelist, lru) { 1036 start = page->index << PAGE_SHIFT; 1037 end = start + PAGE_SIZE - 1; 1038 min = min(min, start); 1039 max = max(max, end); 1040 } 1041 1042 if (min < max) { 1043 y1 = min / info->fix.line_length; 1044 y2 = min_t(u32, DIV_ROUND_UP(max, info->fix.line_length), 1045 info->var.yres); 1046 drm_fb_helper_dirty(info, 0, y1, info->var.xres, y2 - y1); 1047 } 1048 } 1049 EXPORT_SYMBOL(drm_fb_helper_deferred_io); 1050 1051 /** 1052 * drm_fb_helper_defio_init - fbdev deferred I/O initialization 1053 * @fb_helper: driver-allocated fbdev helper 1054 * 1055 * This function allocates &fb_deferred_io, sets callback to 1056 * drm_fb_helper_deferred_io(), delay to 50ms and calls fb_deferred_io_init(). 1057 * It should be called from the &drm_fb_helper_funcs->fb_probe callback. 1058 * drm_fb_helper_fbdev_teardown() cleans up deferred I/O. 1059 * 1060 * NOTE: A copy of &fb_ops is made and assigned to &info->fbops. This is done 1061 * because fb_deferred_io_cleanup() clears &fbops->fb_mmap and would thereby 1062 * affect other instances of that &fb_ops. 1063 * 1064 * Returns: 1065 * 0 on success or a negative error code on failure. 1066 */ 1067 int drm_fb_helper_defio_init(struct drm_fb_helper *fb_helper) 1068 { 1069 struct fb_info *info = fb_helper->fbdev; 1070 struct fb_deferred_io *fbdefio; 1071 struct fb_ops *fbops; 1072 1073 fbdefio = kzalloc(sizeof(*fbdefio), GFP_KERNEL); 1074 fbops = kzalloc(sizeof(*fbops), GFP_KERNEL); 1075 if (!fbdefio || !fbops) { 1076 kfree(fbdefio); 1077 kfree(fbops); 1078 return -ENOMEM; 1079 } 1080 1081 info->fbdefio = fbdefio; 1082 fbdefio->delay = msecs_to_jiffies(50); 1083 fbdefio->deferred_io = drm_fb_helper_deferred_io; 1084 1085 *fbops = *info->fbops; 1086 info->fbops = fbops; 1087 1088 fb_deferred_io_init(info); 1089 1090 return 0; 1091 } 1092 EXPORT_SYMBOL(drm_fb_helper_defio_init); 1093 1094 /** 1095 * drm_fb_helper_sys_read - wrapper around fb_sys_read 1096 * @info: fb_info struct pointer 1097 * @buf: userspace buffer to read from framebuffer memory 1098 * @count: number of bytes to read from framebuffer memory 1099 * @ppos: read offset within framebuffer memory 1100 * 1101 * A wrapper around fb_sys_read implemented by fbdev core 1102 */ 1103 ssize_t drm_fb_helper_sys_read(struct fb_info *info, char __user *buf, 1104 size_t count, loff_t *ppos) 1105 { 1106 return fb_sys_read(info, buf, count, ppos); 1107 } 1108 EXPORT_SYMBOL(drm_fb_helper_sys_read); 1109 1110 /** 1111 * drm_fb_helper_sys_write - wrapper around fb_sys_write 1112 * @info: fb_info struct pointer 1113 * @buf: userspace buffer to write to framebuffer memory 1114 * @count: number of bytes to write to framebuffer memory 1115 * @ppos: write offset within framebuffer memory 1116 * 1117 * A wrapper around fb_sys_write implemented by fbdev core 1118 */ 1119 ssize_t drm_fb_helper_sys_write(struct fb_info *info, const char __user *buf, 1120 size_t count, loff_t *ppos) 1121 { 1122 ssize_t ret; 1123 1124 ret = fb_sys_write(info, buf, count, ppos); 1125 if (ret > 0) 1126 drm_fb_helper_dirty(info, 0, 0, info->var.xres, 1127 info->var.yres); 1128 1129 return ret; 1130 } 1131 EXPORT_SYMBOL(drm_fb_helper_sys_write); 1132 1133 /** 1134 * drm_fb_helper_sys_fillrect - wrapper around sys_fillrect 1135 * @info: fbdev registered by the helper 1136 * @rect: info about rectangle to fill 1137 * 1138 * A wrapper around sys_fillrect implemented by fbdev core 1139 */ 1140 void drm_fb_helper_sys_fillrect(struct fb_info *info, 1141 const struct fb_fillrect *rect) 1142 { 1143 sys_fillrect(info, rect); 1144 drm_fb_helper_dirty(info, rect->dx, rect->dy, 1145 rect->width, rect->height); 1146 } 1147 EXPORT_SYMBOL(drm_fb_helper_sys_fillrect); 1148 1149 /** 1150 * drm_fb_helper_sys_copyarea - wrapper around sys_copyarea 1151 * @info: fbdev registered by the helper 1152 * @area: info about area to copy 1153 * 1154 * A wrapper around sys_copyarea implemented by fbdev core 1155 */ 1156 void drm_fb_helper_sys_copyarea(struct fb_info *info, 1157 const struct fb_copyarea *area) 1158 { 1159 sys_copyarea(info, area); 1160 drm_fb_helper_dirty(info, area->dx, area->dy, 1161 area->width, area->height); 1162 } 1163 EXPORT_SYMBOL(drm_fb_helper_sys_copyarea); 1164 1165 /** 1166 * drm_fb_helper_sys_imageblit - wrapper around sys_imageblit 1167 * @info: fbdev registered by the helper 1168 * @image: info about image to blit 1169 * 1170 * A wrapper around sys_imageblit implemented by fbdev core 1171 */ 1172 void drm_fb_helper_sys_imageblit(struct fb_info *info, 1173 const struct fb_image *image) 1174 { 1175 sys_imageblit(info, image); 1176 drm_fb_helper_dirty(info, image->dx, image->dy, 1177 image->width, image->height); 1178 } 1179 EXPORT_SYMBOL(drm_fb_helper_sys_imageblit); 1180 1181 /** 1182 * drm_fb_helper_cfb_fillrect - wrapper around cfb_fillrect 1183 * @info: fbdev registered by the helper 1184 * @rect: info about rectangle to fill 1185 * 1186 * A wrapper around cfb_fillrect implemented by fbdev core 1187 */ 1188 void drm_fb_helper_cfb_fillrect(struct fb_info *info, 1189 const struct fb_fillrect *rect) 1190 { 1191 cfb_fillrect(info, rect); 1192 drm_fb_helper_dirty(info, rect->dx, rect->dy, 1193 rect->width, rect->height); 1194 } 1195 EXPORT_SYMBOL(drm_fb_helper_cfb_fillrect); 1196 1197 /** 1198 * drm_fb_helper_cfb_copyarea - wrapper around cfb_copyarea 1199 * @info: fbdev registered by the helper 1200 * @area: info about area to copy 1201 * 1202 * A wrapper around cfb_copyarea implemented by fbdev core 1203 */ 1204 void drm_fb_helper_cfb_copyarea(struct fb_info *info, 1205 const struct fb_copyarea *area) 1206 { 1207 cfb_copyarea(info, area); 1208 drm_fb_helper_dirty(info, area->dx, area->dy, 1209 area->width, area->height); 1210 } 1211 EXPORT_SYMBOL(drm_fb_helper_cfb_copyarea); 1212 1213 /** 1214 * drm_fb_helper_cfb_imageblit - wrapper around cfb_imageblit 1215 * @info: fbdev registered by the helper 1216 * @image: info about image to blit 1217 * 1218 * A wrapper around cfb_imageblit implemented by fbdev core 1219 */ 1220 void drm_fb_helper_cfb_imageblit(struct fb_info *info, 1221 const struct fb_image *image) 1222 { 1223 cfb_imageblit(info, image); 1224 drm_fb_helper_dirty(info, image->dx, image->dy, 1225 image->width, image->height); 1226 } 1227 EXPORT_SYMBOL(drm_fb_helper_cfb_imageblit); 1228 1229 /** 1230 * drm_fb_helper_set_suspend - wrapper around fb_set_suspend 1231 * @fb_helper: driver-allocated fbdev helper, can be NULL 1232 * @suspend: whether to suspend or resume 1233 * 1234 * A wrapper around fb_set_suspend implemented by fbdev core. 1235 * Use drm_fb_helper_set_suspend_unlocked() if you don't need to take 1236 * the lock yourself 1237 */ 1238 void drm_fb_helper_set_suspend(struct drm_fb_helper *fb_helper, bool suspend) 1239 { 1240 if (fb_helper && fb_helper->fbdev) 1241 fb_set_suspend(fb_helper->fbdev, suspend); 1242 } 1243 EXPORT_SYMBOL(drm_fb_helper_set_suspend); 1244 1245 /** 1246 * drm_fb_helper_set_suspend_unlocked - wrapper around fb_set_suspend that also 1247 * takes the console lock 1248 * @fb_helper: driver-allocated fbdev helper, can be NULL 1249 * @suspend: whether to suspend or resume 1250 * 1251 * A wrapper around fb_set_suspend() that takes the console lock. If the lock 1252 * isn't available on resume, a worker is tasked with waiting for the lock 1253 * to become available. The console lock can be pretty contented on resume 1254 * due to all the printk activity. 1255 * 1256 * This function can be called multiple times with the same state since 1257 * &fb_info.state is checked to see if fbdev is running or not before locking. 1258 * 1259 * Use drm_fb_helper_set_suspend() if you need to take the lock yourself. 1260 */ 1261 void drm_fb_helper_set_suspend_unlocked(struct drm_fb_helper *fb_helper, 1262 bool suspend) 1263 { 1264 if (!fb_helper || !fb_helper->fbdev) 1265 return; 1266 1267 /* make sure there's no pending/ongoing resume */ 1268 flush_work(&fb_helper->resume_work); 1269 1270 if (suspend) { 1271 if (fb_helper->fbdev->state != FBINFO_STATE_RUNNING) 1272 return; 1273 1274 console_lock(); 1275 1276 } else { 1277 if (fb_helper->fbdev->state == FBINFO_STATE_RUNNING) 1278 return; 1279 1280 if (!console_trylock()) { 1281 schedule_work(&fb_helper->resume_work); 1282 return; 1283 } 1284 } 1285 1286 fb_set_suspend(fb_helper->fbdev, suspend); 1287 console_unlock(); 1288 } 1289 EXPORT_SYMBOL(drm_fb_helper_set_suspend_unlocked); 1290 1291 static int setcmap_pseudo_palette(struct fb_cmap *cmap, struct fb_info *info) 1292 { 1293 u32 *palette = (u32 *)info->pseudo_palette; 1294 int i; 1295 1296 if (cmap->start + cmap->len > 16) 1297 return -EINVAL; 1298 1299 for (i = 0; i < cmap->len; ++i) { 1300 u16 red = cmap->red[i]; 1301 u16 green = cmap->green[i]; 1302 u16 blue = cmap->blue[i]; 1303 u32 value; 1304 1305 red >>= 16 - info->var.red.length; 1306 green >>= 16 - info->var.green.length; 1307 blue >>= 16 - info->var.blue.length; 1308 value = (red << info->var.red.offset) | 1309 (green << info->var.green.offset) | 1310 (blue << info->var.blue.offset); 1311 if (info->var.transp.length > 0) { 1312 u32 mask = (1 << info->var.transp.length) - 1; 1313 1314 mask <<= info->var.transp.offset; 1315 value |= mask; 1316 } 1317 palette[cmap->start + i] = value; 1318 } 1319 1320 return 0; 1321 } 1322 1323 static int setcmap_legacy(struct fb_cmap *cmap, struct fb_info *info) 1324 { 1325 struct drm_fb_helper *fb_helper = info->par; 1326 struct drm_crtc *crtc; 1327 u16 *r, *g, *b; 1328 int i, ret = 0; 1329 1330 drm_modeset_lock_all(fb_helper->dev); 1331 for (i = 0; i < fb_helper->crtc_count; i++) { 1332 crtc = fb_helper->crtc_info[i].mode_set.crtc; 1333 if (!crtc->funcs->gamma_set || !crtc->gamma_size) 1334 return -EINVAL; 1335 1336 if (cmap->start + cmap->len > crtc->gamma_size) 1337 return -EINVAL; 1338 1339 r = crtc->gamma_store; 1340 g = r + crtc->gamma_size; 1341 b = g + crtc->gamma_size; 1342 1343 memcpy(r + cmap->start, cmap->red, cmap->len * sizeof(*r)); 1344 memcpy(g + cmap->start, cmap->green, cmap->len * sizeof(*g)); 1345 memcpy(b + cmap->start, cmap->blue, cmap->len * sizeof(*b)); 1346 1347 ret = crtc->funcs->gamma_set(crtc, r, g, b, 1348 crtc->gamma_size, NULL); 1349 if (ret) 1350 return ret; 1351 } 1352 drm_modeset_unlock_all(fb_helper->dev); 1353 1354 return ret; 1355 } 1356 1357 static struct drm_property_blob *setcmap_new_gamma_lut(struct drm_crtc *crtc, 1358 struct fb_cmap *cmap) 1359 { 1360 struct drm_device *dev = crtc->dev; 1361 struct drm_property_blob *gamma_lut; 1362 struct drm_color_lut *lut; 1363 int size = crtc->gamma_size; 1364 int i; 1365 1366 if (!size || cmap->start + cmap->len > size) 1367 return ERR_PTR(-EINVAL); 1368 1369 gamma_lut = drm_property_create_blob(dev, sizeof(*lut) * size, NULL); 1370 if (IS_ERR(gamma_lut)) 1371 return gamma_lut; 1372 1373 lut = gamma_lut->data; 1374 if (cmap->start || cmap->len != size) { 1375 u16 *r = crtc->gamma_store; 1376 u16 *g = r + crtc->gamma_size; 1377 u16 *b = g + crtc->gamma_size; 1378 1379 for (i = 0; i < cmap->start; i++) { 1380 lut[i].red = r[i]; 1381 lut[i].green = g[i]; 1382 lut[i].blue = b[i]; 1383 } 1384 for (i = cmap->start + cmap->len; i < size; i++) { 1385 lut[i].red = r[i]; 1386 lut[i].green = g[i]; 1387 lut[i].blue = b[i]; 1388 } 1389 } 1390 1391 for (i = 0; i < cmap->len; i++) { 1392 lut[cmap->start + i].red = cmap->red[i]; 1393 lut[cmap->start + i].green = cmap->green[i]; 1394 lut[cmap->start + i].blue = cmap->blue[i]; 1395 } 1396 1397 return gamma_lut; 1398 } 1399 1400 static int setcmap_atomic(struct fb_cmap *cmap, struct fb_info *info) 1401 { 1402 struct drm_fb_helper *fb_helper = info->par; 1403 struct drm_device *dev = fb_helper->dev; 1404 struct drm_property_blob *gamma_lut = NULL; 1405 struct drm_modeset_acquire_ctx ctx; 1406 struct drm_crtc_state *crtc_state; 1407 struct drm_atomic_state *state; 1408 struct drm_crtc *crtc; 1409 u16 *r, *g, *b; 1410 int i, ret = 0; 1411 bool replaced; 1412 1413 drm_modeset_acquire_init(&ctx, 0); 1414 1415 state = drm_atomic_state_alloc(dev); 1416 if (!state) { 1417 ret = -ENOMEM; 1418 goto out_ctx; 1419 } 1420 1421 state->acquire_ctx = &ctx; 1422 retry: 1423 for (i = 0; i < fb_helper->crtc_count; i++) { 1424 crtc = fb_helper->crtc_info[i].mode_set.crtc; 1425 1426 if (!gamma_lut) 1427 gamma_lut = setcmap_new_gamma_lut(crtc, cmap); 1428 if (IS_ERR(gamma_lut)) { 1429 ret = PTR_ERR(gamma_lut); 1430 gamma_lut = NULL; 1431 goto out_state; 1432 } 1433 1434 crtc_state = drm_atomic_get_crtc_state(state, crtc); 1435 if (IS_ERR(crtc_state)) { 1436 ret = PTR_ERR(crtc_state); 1437 goto out_state; 1438 } 1439 1440 replaced = drm_property_replace_blob(&crtc_state->degamma_lut, 1441 NULL); 1442 replaced |= drm_property_replace_blob(&crtc_state->ctm, NULL); 1443 replaced |= drm_property_replace_blob(&crtc_state->gamma_lut, 1444 gamma_lut); 1445 crtc_state->color_mgmt_changed |= replaced; 1446 } 1447 1448 ret = drm_atomic_commit(state); 1449 if (ret) 1450 goto out_state; 1451 1452 for (i = 0; i < fb_helper->crtc_count; i++) { 1453 crtc = fb_helper->crtc_info[i].mode_set.crtc; 1454 1455 r = crtc->gamma_store; 1456 g = r + crtc->gamma_size; 1457 b = g + crtc->gamma_size; 1458 1459 memcpy(r + cmap->start, cmap->red, cmap->len * sizeof(*r)); 1460 memcpy(g + cmap->start, cmap->green, cmap->len * sizeof(*g)); 1461 memcpy(b + cmap->start, cmap->blue, cmap->len * sizeof(*b)); 1462 } 1463 1464 out_state: 1465 if (ret == -EDEADLK) 1466 goto backoff; 1467 1468 drm_property_blob_put(gamma_lut); 1469 drm_atomic_state_put(state); 1470 out_ctx: 1471 drm_modeset_drop_locks(&ctx); 1472 drm_modeset_acquire_fini(&ctx); 1473 1474 return ret; 1475 1476 backoff: 1477 drm_atomic_state_clear(state); 1478 drm_modeset_backoff(&ctx); 1479 goto retry; 1480 } 1481 1482 /** 1483 * drm_fb_helper_setcmap - implementation for &fb_ops.fb_setcmap 1484 * @cmap: cmap to set 1485 * @info: fbdev registered by the helper 1486 */ 1487 int drm_fb_helper_setcmap(struct fb_cmap *cmap, struct fb_info *info) 1488 { 1489 struct drm_fb_helper *fb_helper = info->par; 1490 int ret; 1491 1492 if (oops_in_progress) 1493 return -EBUSY; 1494 1495 mutex_lock(&fb_helper->lock); 1496 1497 if (!drm_fb_helper_is_bound(fb_helper)) { 1498 ret = -EBUSY; 1499 goto out; 1500 } 1501 1502 if (info->fix.visual == FB_VISUAL_TRUECOLOR) 1503 ret = setcmap_pseudo_palette(cmap, info); 1504 else if (drm_drv_uses_atomic_modeset(fb_helper->dev)) 1505 ret = setcmap_atomic(cmap, info); 1506 else 1507 ret = setcmap_legacy(cmap, info); 1508 1509 out: 1510 mutex_unlock(&fb_helper->lock); 1511 1512 return ret; 1513 } 1514 EXPORT_SYMBOL(drm_fb_helper_setcmap); 1515 1516 /** 1517 * drm_fb_helper_ioctl - legacy ioctl implementation 1518 * @info: fbdev registered by the helper 1519 * @cmd: ioctl command 1520 * @arg: ioctl argument 1521 * 1522 * A helper to implement the standard fbdev ioctl. Only 1523 * FBIO_WAITFORVSYNC is implemented for now. 1524 */ 1525 int drm_fb_helper_ioctl(struct fb_info *info, unsigned int cmd, 1526 unsigned long arg) 1527 { 1528 struct drm_fb_helper *fb_helper = info->par; 1529 struct drm_mode_set *mode_set; 1530 struct drm_crtc *crtc; 1531 int ret = 0; 1532 1533 mutex_lock(&fb_helper->lock); 1534 if (!drm_fb_helper_is_bound(fb_helper)) { 1535 ret = -EBUSY; 1536 goto unlock; 1537 } 1538 1539 switch (cmd) { 1540 case FBIO_WAITFORVSYNC: 1541 /* 1542 * Only consider the first CRTC. 1543 * 1544 * This ioctl is supposed to take the CRTC number as 1545 * an argument, but in fbdev times, what that number 1546 * was supposed to be was quite unclear, different 1547 * drivers were passing that argument differently 1548 * (some by reference, some by value), and most of the 1549 * userspace applications were just hardcoding 0 as an 1550 * argument. 1551 * 1552 * The first CRTC should be the integrated panel on 1553 * most drivers, so this is the best choice we can 1554 * make. If we're not smart enough here, one should 1555 * just consider switch the userspace to KMS. 1556 */ 1557 mode_set = &fb_helper->crtc_info[0].mode_set; 1558 crtc = mode_set->crtc; 1559 1560 /* 1561 * Only wait for a vblank event if the CRTC is 1562 * enabled, otherwise just don't do anythintg, 1563 * not even report an error. 1564 */ 1565 ret = drm_crtc_vblank_get(crtc); 1566 if (!ret) { 1567 drm_crtc_wait_one_vblank(crtc); 1568 drm_crtc_vblank_put(crtc); 1569 } 1570 1571 ret = 0; 1572 goto unlock; 1573 default: 1574 ret = -ENOTTY; 1575 } 1576 1577 unlock: 1578 mutex_unlock(&fb_helper->lock); 1579 return ret; 1580 } 1581 EXPORT_SYMBOL(drm_fb_helper_ioctl); 1582 1583 static bool drm_fb_pixel_format_equal(const struct fb_var_screeninfo *var_1, 1584 const struct fb_var_screeninfo *var_2) 1585 { 1586 return var_1->bits_per_pixel == var_2->bits_per_pixel && 1587 var_1->grayscale == var_2->grayscale && 1588 var_1->red.offset == var_2->red.offset && 1589 var_1->red.length == var_2->red.length && 1590 var_1->red.msb_right == var_2->red.msb_right && 1591 var_1->green.offset == var_2->green.offset && 1592 var_1->green.length == var_2->green.length && 1593 var_1->green.msb_right == var_2->green.msb_right && 1594 var_1->blue.offset == var_2->blue.offset && 1595 var_1->blue.length == var_2->blue.length && 1596 var_1->blue.msb_right == var_2->blue.msb_right && 1597 var_1->transp.offset == var_2->transp.offset && 1598 var_1->transp.length == var_2->transp.length && 1599 var_1->transp.msb_right == var_2->transp.msb_right; 1600 } 1601 1602 /** 1603 * drm_fb_helper_check_var - implementation for &fb_ops.fb_check_var 1604 * @var: screeninfo to check 1605 * @info: fbdev registered by the helper 1606 */ 1607 int drm_fb_helper_check_var(struct fb_var_screeninfo *var, 1608 struct fb_info *info) 1609 { 1610 struct drm_fb_helper *fb_helper = info->par; 1611 struct drm_framebuffer *fb = fb_helper->fb; 1612 1613 if (var->pixclock != 0 || in_dbg_master()) 1614 return -EINVAL; 1615 1616 /* 1617 * Changes struct fb_var_screeninfo are currently not pushed back 1618 * to KMS, hence fail if different settings are requested. 1619 */ 1620 if (var->bits_per_pixel != fb->format->cpp[0] * 8 || 1621 var->xres > fb->width || var->yres > fb->height || 1622 var->xres_virtual > fb->width || var->yres_virtual > fb->height) { 1623 DRM_DEBUG("fb requested width/height/bpp can't fit in current fb " 1624 "request %dx%d-%d (virtual %dx%d) > %dx%d-%d\n", 1625 var->xres, var->yres, var->bits_per_pixel, 1626 var->xres_virtual, var->yres_virtual, 1627 fb->width, fb->height, fb->format->cpp[0] * 8); 1628 return -EINVAL; 1629 } 1630 1631 /* 1632 * drm fbdev emulation doesn't support changing the pixel format at all, 1633 * so reject all pixel format changing requests. 1634 */ 1635 if (!drm_fb_pixel_format_equal(var, &info->var)) { 1636 DRM_DEBUG("fbdev emulation doesn't support changing the pixel format\n"); 1637 return -EINVAL; 1638 } 1639 1640 return 0; 1641 } 1642 EXPORT_SYMBOL(drm_fb_helper_check_var); 1643 1644 /** 1645 * drm_fb_helper_set_par - implementation for &fb_ops.fb_set_par 1646 * @info: fbdev registered by the helper 1647 * 1648 * This will let fbcon do the mode init and is called at initialization time by 1649 * the fbdev core when registering the driver, and later on through the hotplug 1650 * callback. 1651 */ 1652 int drm_fb_helper_set_par(struct fb_info *info) 1653 { 1654 struct drm_fb_helper *fb_helper = info->par; 1655 struct fb_var_screeninfo *var = &info->var; 1656 1657 if (oops_in_progress) 1658 return -EBUSY; 1659 1660 if (var->pixclock != 0) { 1661 DRM_ERROR("PIXEL CLOCK SET\n"); 1662 return -EINVAL; 1663 } 1664 1665 drm_fb_helper_restore_fbdev_mode_unlocked(fb_helper); 1666 1667 return 0; 1668 } 1669 EXPORT_SYMBOL(drm_fb_helper_set_par); 1670 1671 static void pan_set(struct drm_fb_helper *fb_helper, int x, int y) 1672 { 1673 int i; 1674 1675 for (i = 0; i < fb_helper->crtc_count; i++) { 1676 struct drm_mode_set *mode_set; 1677 1678 mode_set = &fb_helper->crtc_info[i].mode_set; 1679 1680 mode_set->x = x; 1681 mode_set->y = y; 1682 } 1683 } 1684 1685 static int pan_display_atomic(struct fb_var_screeninfo *var, 1686 struct fb_info *info) 1687 { 1688 struct drm_fb_helper *fb_helper = info->par; 1689 int ret; 1690 1691 pan_set(fb_helper, var->xoffset, var->yoffset); 1692 1693 ret = restore_fbdev_mode_atomic(fb_helper, true); 1694 if (!ret) { 1695 info->var.xoffset = var->xoffset; 1696 info->var.yoffset = var->yoffset; 1697 } else 1698 pan_set(fb_helper, info->var.xoffset, info->var.yoffset); 1699 1700 return ret; 1701 } 1702 1703 static int pan_display_legacy(struct fb_var_screeninfo *var, 1704 struct fb_info *info) 1705 { 1706 struct drm_fb_helper *fb_helper = info->par; 1707 struct drm_mode_set *modeset; 1708 int ret = 0; 1709 int i; 1710 1711 drm_modeset_lock_all(fb_helper->dev); 1712 for (i = 0; i < fb_helper->crtc_count; i++) { 1713 modeset = &fb_helper->crtc_info[i].mode_set; 1714 1715 modeset->x = var->xoffset; 1716 modeset->y = var->yoffset; 1717 1718 if (modeset->num_connectors) { 1719 ret = drm_mode_set_config_internal(modeset); 1720 if (!ret) { 1721 info->var.xoffset = var->xoffset; 1722 info->var.yoffset = var->yoffset; 1723 } 1724 } 1725 } 1726 drm_modeset_unlock_all(fb_helper->dev); 1727 1728 return ret; 1729 } 1730 1731 /** 1732 * drm_fb_helper_pan_display - implementation for &fb_ops.fb_pan_display 1733 * @var: updated screen information 1734 * @info: fbdev registered by the helper 1735 */ 1736 int drm_fb_helper_pan_display(struct fb_var_screeninfo *var, 1737 struct fb_info *info) 1738 { 1739 struct drm_fb_helper *fb_helper = info->par; 1740 struct drm_device *dev = fb_helper->dev; 1741 int ret; 1742 1743 if (oops_in_progress) 1744 return -EBUSY; 1745 1746 mutex_lock(&fb_helper->lock); 1747 if (!drm_fb_helper_is_bound(fb_helper)) { 1748 mutex_unlock(&fb_helper->lock); 1749 return -EBUSY; 1750 } 1751 1752 if (drm_drv_uses_atomic_modeset(dev)) 1753 ret = pan_display_atomic(var, info); 1754 else 1755 ret = pan_display_legacy(var, info); 1756 mutex_unlock(&fb_helper->lock); 1757 1758 return ret; 1759 } 1760 EXPORT_SYMBOL(drm_fb_helper_pan_display); 1761 1762 /* 1763 * Allocates the backing storage and sets up the fbdev info structure through 1764 * the ->fb_probe callback. 1765 */ 1766 static int drm_fb_helper_single_fb_probe(struct drm_fb_helper *fb_helper, 1767 int preferred_bpp) 1768 { 1769 int ret = 0; 1770 int crtc_count = 0; 1771 int i; 1772 struct drm_fb_helper_surface_size sizes; 1773 int gamma_size = 0; 1774 1775 memset(&sizes, 0, sizeof(struct drm_fb_helper_surface_size)); 1776 sizes.surface_depth = 24; 1777 sizes.surface_bpp = 32; 1778 sizes.fb_width = (u32)-1; 1779 sizes.fb_height = (u32)-1; 1780 1781 /* if driver picks 8 or 16 by default use that for both depth/bpp */ 1782 if (preferred_bpp != sizes.surface_bpp) 1783 sizes.surface_depth = sizes.surface_bpp = preferred_bpp; 1784 1785 /* first up get a count of crtcs now in use and new min/maxes width/heights */ 1786 drm_fb_helper_for_each_connector(fb_helper, i) { 1787 struct drm_fb_helper_connector *fb_helper_conn = fb_helper->connector_info[i]; 1788 struct drm_cmdline_mode *cmdline_mode; 1789 1790 cmdline_mode = &fb_helper_conn->connector->cmdline_mode; 1791 1792 if (cmdline_mode->bpp_specified) { 1793 switch (cmdline_mode->bpp) { 1794 case 8: 1795 sizes.surface_depth = sizes.surface_bpp = 8; 1796 break; 1797 case 15: 1798 sizes.surface_depth = 15; 1799 sizes.surface_bpp = 16; 1800 break; 1801 case 16: 1802 sizes.surface_depth = sizes.surface_bpp = 16; 1803 break; 1804 case 24: 1805 sizes.surface_depth = sizes.surface_bpp = 24; 1806 break; 1807 case 32: 1808 sizes.surface_depth = 24; 1809 sizes.surface_bpp = 32; 1810 break; 1811 } 1812 break; 1813 } 1814 } 1815 1816 crtc_count = 0; 1817 for (i = 0; i < fb_helper->crtc_count; i++) { 1818 struct drm_display_mode *desired_mode; 1819 struct drm_mode_set *mode_set; 1820 int x, y, j; 1821 /* in case of tile group, are we the last tile vert or horiz? 1822 * If no tile group you are always the last one both vertically 1823 * and horizontally 1824 */ 1825 bool lastv = true, lasth = true; 1826 1827 desired_mode = fb_helper->crtc_info[i].desired_mode; 1828 mode_set = &fb_helper->crtc_info[i].mode_set; 1829 1830 if (!desired_mode) 1831 continue; 1832 1833 crtc_count++; 1834 1835 x = fb_helper->crtc_info[i].x; 1836 y = fb_helper->crtc_info[i].y; 1837 1838 if (gamma_size == 0) 1839 gamma_size = fb_helper->crtc_info[i].mode_set.crtc->gamma_size; 1840 1841 sizes.surface_width = max_t(u32, desired_mode->hdisplay + x, sizes.surface_width); 1842 sizes.surface_height = max_t(u32, desired_mode->vdisplay + y, sizes.surface_height); 1843 1844 for (j = 0; j < mode_set->num_connectors; j++) { 1845 struct drm_connector *connector = mode_set->connectors[j]; 1846 1847 if (connector->has_tile) { 1848 lasth = (connector->tile_h_loc == (connector->num_h_tile - 1)); 1849 lastv = (connector->tile_v_loc == (connector->num_v_tile - 1)); 1850 /* cloning to multiple tiles is just crazy-talk, so: */ 1851 break; 1852 } 1853 } 1854 1855 if (lasth) 1856 sizes.fb_width = min_t(u32, desired_mode->hdisplay + x, sizes.fb_width); 1857 if (lastv) 1858 sizes.fb_height = min_t(u32, desired_mode->vdisplay + y, sizes.fb_height); 1859 } 1860 1861 if (crtc_count == 0 || sizes.fb_width == -1 || sizes.fb_height == -1) { 1862 DRM_INFO("Cannot find any crtc or sizes\n"); 1863 1864 /* First time: disable all crtc's.. */ 1865 if (!fb_helper->deferred_setup && !READ_ONCE(fb_helper->dev->master)) 1866 restore_fbdev_mode(fb_helper); 1867 return -EAGAIN; 1868 } 1869 1870 /* Handle our overallocation */ 1871 sizes.surface_height *= drm_fbdev_overalloc; 1872 sizes.surface_height /= 100; 1873 1874 /* push down into drivers */ 1875 ret = (*fb_helper->funcs->fb_probe)(fb_helper, &sizes); 1876 if (ret < 0) 1877 return ret; 1878 1879 strcpy(fb_helper->fb->comm, "[fbcon]"); 1880 return 0; 1881 } 1882 1883 /** 1884 * drm_fb_helper_fill_fix - initializes fixed fbdev information 1885 * @info: fbdev registered by the helper 1886 * @pitch: desired pitch 1887 * @depth: desired depth 1888 * 1889 * Helper to fill in the fixed fbdev information useful for a non-accelerated 1890 * fbdev emulations. Drivers which support acceleration methods which impose 1891 * additional constraints need to set up their own limits. 1892 * 1893 * Drivers should call this (or their equivalent setup code) from their 1894 * &drm_fb_helper_funcs.fb_probe callback. 1895 */ 1896 void drm_fb_helper_fill_fix(struct fb_info *info, uint32_t pitch, 1897 uint32_t depth) 1898 { 1899 info->fix.type = FB_TYPE_PACKED_PIXELS; 1900 info->fix.visual = depth == 8 ? FB_VISUAL_PSEUDOCOLOR : 1901 FB_VISUAL_TRUECOLOR; 1902 info->fix.mmio_start = 0; 1903 info->fix.mmio_len = 0; 1904 info->fix.type_aux = 0; 1905 info->fix.xpanstep = 1; /* doing it in hw */ 1906 info->fix.ypanstep = 1; /* doing it in hw */ 1907 info->fix.ywrapstep = 0; 1908 info->fix.accel = FB_ACCEL_NONE; 1909 1910 info->fix.line_length = pitch; 1911 } 1912 EXPORT_SYMBOL(drm_fb_helper_fill_fix); 1913 1914 /** 1915 * drm_fb_helper_fill_var - initalizes variable fbdev information 1916 * @info: fbdev instance to set up 1917 * @fb_helper: fb helper instance to use as template 1918 * @fb_width: desired fb width 1919 * @fb_height: desired fb height 1920 * 1921 * Sets up the variable fbdev metainformation from the given fb helper instance 1922 * and the drm framebuffer allocated in &drm_fb_helper.fb. 1923 * 1924 * Drivers should call this (or their equivalent setup code) from their 1925 * &drm_fb_helper_funcs.fb_probe callback after having allocated the fbdev 1926 * backing storage framebuffer. 1927 */ 1928 void drm_fb_helper_fill_var(struct fb_info *info, struct drm_fb_helper *fb_helper, 1929 uint32_t fb_width, uint32_t fb_height) 1930 { 1931 struct drm_framebuffer *fb = fb_helper->fb; 1932 1933 info->pseudo_palette = fb_helper->pseudo_palette; 1934 info->var.xres_virtual = fb->width; 1935 info->var.yres_virtual = fb->height; 1936 info->var.bits_per_pixel = fb->format->cpp[0] * 8; 1937 info->var.accel_flags = FB_ACCELF_TEXT; 1938 info->var.xoffset = 0; 1939 info->var.yoffset = 0; 1940 info->var.activate = FB_ACTIVATE_NOW; 1941 1942 switch (fb->format->depth) { 1943 case 8: 1944 info->var.red.offset = 0; 1945 info->var.green.offset = 0; 1946 info->var.blue.offset = 0; 1947 info->var.red.length = 8; /* 8bit DAC */ 1948 info->var.green.length = 8; 1949 info->var.blue.length = 8; 1950 info->var.transp.offset = 0; 1951 info->var.transp.length = 0; 1952 break; 1953 case 15: 1954 info->var.red.offset = 10; 1955 info->var.green.offset = 5; 1956 info->var.blue.offset = 0; 1957 info->var.red.length = 5; 1958 info->var.green.length = 5; 1959 info->var.blue.length = 5; 1960 info->var.transp.offset = 15; 1961 info->var.transp.length = 1; 1962 break; 1963 case 16: 1964 info->var.red.offset = 11; 1965 info->var.green.offset = 5; 1966 info->var.blue.offset = 0; 1967 info->var.red.length = 5; 1968 info->var.green.length = 6; 1969 info->var.blue.length = 5; 1970 info->var.transp.offset = 0; 1971 break; 1972 case 24: 1973 info->var.red.offset = 16; 1974 info->var.green.offset = 8; 1975 info->var.blue.offset = 0; 1976 info->var.red.length = 8; 1977 info->var.green.length = 8; 1978 info->var.blue.length = 8; 1979 info->var.transp.offset = 0; 1980 info->var.transp.length = 0; 1981 break; 1982 case 32: 1983 info->var.red.offset = 16; 1984 info->var.green.offset = 8; 1985 info->var.blue.offset = 0; 1986 info->var.red.length = 8; 1987 info->var.green.length = 8; 1988 info->var.blue.length = 8; 1989 info->var.transp.offset = 24; 1990 info->var.transp.length = 8; 1991 break; 1992 default: 1993 break; 1994 } 1995 1996 info->var.xres = fb_width; 1997 info->var.yres = fb_height; 1998 } 1999 EXPORT_SYMBOL(drm_fb_helper_fill_var); 2000 2001 static int drm_fb_helper_probe_connector_modes(struct drm_fb_helper *fb_helper, 2002 uint32_t maxX, 2003 uint32_t maxY) 2004 { 2005 struct drm_connector *connector; 2006 int i, count = 0; 2007 2008 drm_fb_helper_for_each_connector(fb_helper, i) { 2009 connector = fb_helper->connector_info[i]->connector; 2010 count += connector->funcs->fill_modes(connector, maxX, maxY); 2011 } 2012 2013 return count; 2014 } 2015 2016 struct drm_display_mode *drm_has_preferred_mode(struct drm_fb_helper_connector *fb_connector, int width, int height) 2017 { 2018 struct drm_display_mode *mode; 2019 2020 list_for_each_entry(mode, &fb_connector->connector->modes, head) { 2021 if (mode->hdisplay > width || 2022 mode->vdisplay > height) 2023 continue; 2024 if (mode->type & DRM_MODE_TYPE_PREFERRED) 2025 return mode; 2026 } 2027 return NULL; 2028 } 2029 EXPORT_SYMBOL(drm_has_preferred_mode); 2030 2031 static bool drm_has_cmdline_mode(struct drm_fb_helper_connector *fb_connector) 2032 { 2033 return fb_connector->connector->cmdline_mode.specified; 2034 } 2035 2036 struct drm_display_mode *drm_pick_cmdline_mode(struct drm_fb_helper_connector *fb_helper_conn) 2037 { 2038 struct drm_cmdline_mode *cmdline_mode; 2039 struct drm_display_mode *mode; 2040 bool prefer_non_interlace; 2041 2042 cmdline_mode = &fb_helper_conn->connector->cmdline_mode; 2043 if (cmdline_mode->specified == false) 2044 return NULL; 2045 2046 /* attempt to find a matching mode in the list of modes 2047 * we have gotten so far, if not add a CVT mode that conforms 2048 */ 2049 if (cmdline_mode->rb || cmdline_mode->margins) 2050 goto create_mode; 2051 2052 prefer_non_interlace = !cmdline_mode->interlace; 2053 again: 2054 list_for_each_entry(mode, &fb_helper_conn->connector->modes, head) { 2055 /* check width/height */ 2056 if (mode->hdisplay != cmdline_mode->xres || 2057 mode->vdisplay != cmdline_mode->yres) 2058 continue; 2059 2060 if (cmdline_mode->refresh_specified) { 2061 if (mode->vrefresh != cmdline_mode->refresh) 2062 continue; 2063 } 2064 2065 if (cmdline_mode->interlace) { 2066 if (!(mode->flags & DRM_MODE_FLAG_INTERLACE)) 2067 continue; 2068 } else if (prefer_non_interlace) { 2069 if (mode->flags & DRM_MODE_FLAG_INTERLACE) 2070 continue; 2071 } 2072 return mode; 2073 } 2074 2075 if (prefer_non_interlace) { 2076 prefer_non_interlace = false; 2077 goto again; 2078 } 2079 2080 create_mode: 2081 mode = drm_mode_create_from_cmdline_mode(fb_helper_conn->connector->dev, 2082 cmdline_mode); 2083 list_add(&mode->head, &fb_helper_conn->connector->modes); 2084 return mode; 2085 } 2086 EXPORT_SYMBOL(drm_pick_cmdline_mode); 2087 2088 static bool drm_connector_enabled(struct drm_connector *connector, bool strict) 2089 { 2090 bool enable; 2091 2092 if (connector->display_info.non_desktop) 2093 return false; 2094 2095 if (strict) 2096 enable = connector->status == connector_status_connected; 2097 else 2098 enable = connector->status != connector_status_disconnected; 2099 2100 return enable; 2101 } 2102 2103 static void drm_enable_connectors(struct drm_fb_helper *fb_helper, 2104 bool *enabled) 2105 { 2106 bool any_enabled = false; 2107 struct drm_connector *connector; 2108 int i = 0; 2109 2110 drm_fb_helper_for_each_connector(fb_helper, i) { 2111 connector = fb_helper->connector_info[i]->connector; 2112 enabled[i] = drm_connector_enabled(connector, true); 2113 DRM_DEBUG_KMS("connector %d enabled? %s\n", connector->base.id, 2114 connector->display_info.non_desktop ? "non desktop" : enabled[i] ? "yes" : "no"); 2115 2116 any_enabled |= enabled[i]; 2117 } 2118 2119 if (any_enabled) 2120 return; 2121 2122 drm_fb_helper_for_each_connector(fb_helper, i) { 2123 connector = fb_helper->connector_info[i]->connector; 2124 enabled[i] = drm_connector_enabled(connector, false); 2125 } 2126 } 2127 2128 static bool drm_target_cloned(struct drm_fb_helper *fb_helper, 2129 struct drm_display_mode **modes, 2130 struct drm_fb_offset *offsets, 2131 bool *enabled, int width, int height) 2132 { 2133 int count, i, j; 2134 bool can_clone = false; 2135 struct drm_fb_helper_connector *fb_helper_conn; 2136 struct drm_display_mode *dmt_mode, *mode; 2137 2138 /* only contemplate cloning in the single crtc case */ 2139 if (fb_helper->crtc_count > 1) 2140 return false; 2141 2142 count = 0; 2143 drm_fb_helper_for_each_connector(fb_helper, i) { 2144 if (enabled[i]) 2145 count++; 2146 } 2147 2148 /* only contemplate cloning if more than one connector is enabled */ 2149 if (count <= 1) 2150 return false; 2151 2152 /* check the command line or if nothing common pick 1024x768 */ 2153 can_clone = true; 2154 drm_fb_helper_for_each_connector(fb_helper, i) { 2155 if (!enabled[i]) 2156 continue; 2157 fb_helper_conn = fb_helper->connector_info[i]; 2158 modes[i] = drm_pick_cmdline_mode(fb_helper_conn); 2159 if (!modes[i]) { 2160 can_clone = false; 2161 break; 2162 } 2163 for (j = 0; j < i; j++) { 2164 if (!enabled[j]) 2165 continue; 2166 if (!drm_mode_match(modes[j], modes[i], 2167 DRM_MODE_MATCH_TIMINGS | 2168 DRM_MODE_MATCH_CLOCK | 2169 DRM_MODE_MATCH_FLAGS | 2170 DRM_MODE_MATCH_3D_FLAGS)) 2171 can_clone = false; 2172 } 2173 } 2174 2175 if (can_clone) { 2176 DRM_DEBUG_KMS("can clone using command line\n"); 2177 return true; 2178 } 2179 2180 /* try and find a 1024x768 mode on each connector */ 2181 can_clone = true; 2182 dmt_mode = drm_mode_find_dmt(fb_helper->dev, 1024, 768, 60, false); 2183 2184 drm_fb_helper_for_each_connector(fb_helper, i) { 2185 if (!enabled[i]) 2186 continue; 2187 2188 fb_helper_conn = fb_helper->connector_info[i]; 2189 list_for_each_entry(mode, &fb_helper_conn->connector->modes, head) { 2190 if (drm_mode_match(mode, dmt_mode, 2191 DRM_MODE_MATCH_TIMINGS | 2192 DRM_MODE_MATCH_CLOCK | 2193 DRM_MODE_MATCH_FLAGS | 2194 DRM_MODE_MATCH_3D_FLAGS)) 2195 modes[i] = mode; 2196 } 2197 if (!modes[i]) 2198 can_clone = false; 2199 } 2200 2201 if (can_clone) { 2202 DRM_DEBUG_KMS("can clone using 1024x768\n"); 2203 return true; 2204 } 2205 DRM_INFO("kms: can't enable cloning when we probably wanted to.\n"); 2206 return false; 2207 } 2208 2209 static int drm_get_tile_offsets(struct drm_fb_helper *fb_helper, 2210 struct drm_display_mode **modes, 2211 struct drm_fb_offset *offsets, 2212 int idx, 2213 int h_idx, int v_idx) 2214 { 2215 struct drm_fb_helper_connector *fb_helper_conn; 2216 int i; 2217 int hoffset = 0, voffset = 0; 2218 2219 drm_fb_helper_for_each_connector(fb_helper, i) { 2220 fb_helper_conn = fb_helper->connector_info[i]; 2221 if (!fb_helper_conn->connector->has_tile) 2222 continue; 2223 2224 if (!modes[i] && (h_idx || v_idx)) { 2225 DRM_DEBUG_KMS("no modes for connector tiled %d %d\n", i, 2226 fb_helper_conn->connector->base.id); 2227 continue; 2228 } 2229 if (fb_helper_conn->connector->tile_h_loc < h_idx) 2230 hoffset += modes[i]->hdisplay; 2231 2232 if (fb_helper_conn->connector->tile_v_loc < v_idx) 2233 voffset += modes[i]->vdisplay; 2234 } 2235 offsets[idx].x = hoffset; 2236 offsets[idx].y = voffset; 2237 DRM_DEBUG_KMS("returned %d %d for %d %d\n", hoffset, voffset, h_idx, v_idx); 2238 return 0; 2239 } 2240 2241 static bool drm_target_preferred(struct drm_fb_helper *fb_helper, 2242 struct drm_display_mode **modes, 2243 struct drm_fb_offset *offsets, 2244 bool *enabled, int width, int height) 2245 { 2246 struct drm_fb_helper_connector *fb_helper_conn; 2247 const u64 mask = BIT_ULL(fb_helper->connector_count) - 1; 2248 u64 conn_configured = 0; 2249 int tile_pass = 0; 2250 int i; 2251 2252 retry: 2253 drm_fb_helper_for_each_connector(fb_helper, i) { 2254 fb_helper_conn = fb_helper->connector_info[i]; 2255 2256 if (conn_configured & BIT_ULL(i)) 2257 continue; 2258 2259 if (enabled[i] == false) { 2260 conn_configured |= BIT_ULL(i); 2261 continue; 2262 } 2263 2264 /* first pass over all the untiled connectors */ 2265 if (tile_pass == 0 && fb_helper_conn->connector->has_tile) 2266 continue; 2267 2268 if (tile_pass == 1) { 2269 if (fb_helper_conn->connector->tile_h_loc != 0 || 2270 fb_helper_conn->connector->tile_v_loc != 0) 2271 continue; 2272 2273 } else { 2274 if (fb_helper_conn->connector->tile_h_loc != tile_pass - 1 && 2275 fb_helper_conn->connector->tile_v_loc != tile_pass - 1) 2276 /* if this tile_pass doesn't cover any of the tiles - keep going */ 2277 continue; 2278 2279 /* 2280 * find the tile offsets for this pass - need to find 2281 * all tiles left and above 2282 */ 2283 drm_get_tile_offsets(fb_helper, modes, offsets, 2284 i, fb_helper_conn->connector->tile_h_loc, fb_helper_conn->connector->tile_v_loc); 2285 } 2286 DRM_DEBUG_KMS("looking for cmdline mode on connector %d\n", 2287 fb_helper_conn->connector->base.id); 2288 2289 /* got for command line mode first */ 2290 modes[i] = drm_pick_cmdline_mode(fb_helper_conn); 2291 if (!modes[i]) { 2292 DRM_DEBUG_KMS("looking for preferred mode on connector %d %d\n", 2293 fb_helper_conn->connector->base.id, fb_helper_conn->connector->tile_group ? fb_helper_conn->connector->tile_group->id : 0); 2294 modes[i] = drm_has_preferred_mode(fb_helper_conn, width, height); 2295 } 2296 /* No preferred modes, pick one off the list */ 2297 if (!modes[i] && !list_empty(&fb_helper_conn->connector->modes)) { 2298 list_for_each_entry(modes[i], &fb_helper_conn->connector->modes, head) 2299 break; 2300 } 2301 DRM_DEBUG_KMS("found mode %s\n", modes[i] ? modes[i]->name : 2302 "none"); 2303 conn_configured |= BIT_ULL(i); 2304 } 2305 2306 if ((conn_configured & mask) != mask) { 2307 tile_pass++; 2308 goto retry; 2309 } 2310 return true; 2311 } 2312 2313 static bool connector_has_possible_crtc(struct drm_connector *connector, 2314 struct drm_crtc *crtc) 2315 { 2316 struct drm_encoder *encoder; 2317 int i; 2318 2319 drm_connector_for_each_possible_encoder(connector, encoder, i) { 2320 if (encoder->possible_crtcs & drm_crtc_mask(crtc)) 2321 return true; 2322 } 2323 2324 return false; 2325 } 2326 2327 static int drm_pick_crtcs(struct drm_fb_helper *fb_helper, 2328 struct drm_fb_helper_crtc **best_crtcs, 2329 struct drm_display_mode **modes, 2330 int n, int width, int height) 2331 { 2332 int c, o; 2333 struct drm_connector *connector; 2334 int my_score, best_score, score; 2335 struct drm_fb_helper_crtc **crtcs, *crtc; 2336 struct drm_fb_helper_connector *fb_helper_conn; 2337 2338 if (n == fb_helper->connector_count) 2339 return 0; 2340 2341 fb_helper_conn = fb_helper->connector_info[n]; 2342 connector = fb_helper_conn->connector; 2343 2344 best_crtcs[n] = NULL; 2345 best_score = drm_pick_crtcs(fb_helper, best_crtcs, modes, n+1, width, height); 2346 if (modes[n] == NULL) 2347 return best_score; 2348 2349 crtcs = kcalloc(fb_helper->connector_count, 2350 sizeof(struct drm_fb_helper_crtc *), GFP_KERNEL); 2351 if (!crtcs) 2352 return best_score; 2353 2354 my_score = 1; 2355 if (connector->status == connector_status_connected) 2356 my_score++; 2357 if (drm_has_cmdline_mode(fb_helper_conn)) 2358 my_score++; 2359 if (drm_has_preferred_mode(fb_helper_conn, width, height)) 2360 my_score++; 2361 2362 /* 2363 * select a crtc for this connector and then attempt to configure 2364 * remaining connectors 2365 */ 2366 for (c = 0; c < fb_helper->crtc_count; c++) { 2367 crtc = &fb_helper->crtc_info[c]; 2368 2369 if (!connector_has_possible_crtc(connector, 2370 crtc->mode_set.crtc)) 2371 continue; 2372 2373 for (o = 0; o < n; o++) 2374 if (best_crtcs[o] == crtc) 2375 break; 2376 2377 if (o < n) { 2378 /* ignore cloning unless only a single crtc */ 2379 if (fb_helper->crtc_count > 1) 2380 continue; 2381 2382 if (!drm_mode_equal(modes[o], modes[n])) 2383 continue; 2384 } 2385 2386 crtcs[n] = crtc; 2387 memcpy(crtcs, best_crtcs, n * sizeof(struct drm_fb_helper_crtc *)); 2388 score = my_score + drm_pick_crtcs(fb_helper, crtcs, modes, n + 1, 2389 width, height); 2390 if (score > best_score) { 2391 best_score = score; 2392 memcpy(best_crtcs, crtcs, 2393 fb_helper->connector_count * 2394 sizeof(struct drm_fb_helper_crtc *)); 2395 } 2396 } 2397 2398 kfree(crtcs); 2399 return best_score; 2400 } 2401 2402 /* 2403 * This function checks if rotation is necessary because of panel orientation 2404 * and if it is, if it is supported. 2405 * If rotation is necessary and supported, its gets set in fb_crtc.rotation. 2406 * If rotation is necessary but not supported, a DRM_MODE_ROTATE_* flag gets 2407 * or-ed into fb_helper->sw_rotations. In drm_setup_crtcs_fb() we check if only 2408 * one bit is set and then we set fb_info.fbcon_rotate_hint to make fbcon do 2409 * the unsupported rotation. 2410 */ 2411 static void drm_setup_crtc_rotation(struct drm_fb_helper *fb_helper, 2412 struct drm_fb_helper_crtc *fb_crtc, 2413 struct drm_connector *connector) 2414 { 2415 struct drm_plane *plane = fb_crtc->mode_set.crtc->primary; 2416 uint64_t valid_mask = 0; 2417 int i, rotation; 2418 2419 fb_crtc->rotation = DRM_MODE_ROTATE_0; 2420 2421 switch (connector->display_info.panel_orientation) { 2422 case DRM_MODE_PANEL_ORIENTATION_BOTTOM_UP: 2423 rotation = DRM_MODE_ROTATE_180; 2424 break; 2425 case DRM_MODE_PANEL_ORIENTATION_LEFT_UP: 2426 rotation = DRM_MODE_ROTATE_90; 2427 break; 2428 case DRM_MODE_PANEL_ORIENTATION_RIGHT_UP: 2429 rotation = DRM_MODE_ROTATE_270; 2430 break; 2431 default: 2432 rotation = DRM_MODE_ROTATE_0; 2433 } 2434 2435 /* 2436 * TODO: support 90 / 270 degree hardware rotation, 2437 * depending on the hardware this may require the framebuffer 2438 * to be in a specific tiling format. 2439 */ 2440 if (rotation != DRM_MODE_ROTATE_180 || !plane->rotation_property) { 2441 fb_helper->sw_rotations |= rotation; 2442 return; 2443 } 2444 2445 for (i = 0; i < plane->rotation_property->num_values; i++) 2446 valid_mask |= (1ULL << plane->rotation_property->values[i]); 2447 2448 if (!(rotation & valid_mask)) { 2449 fb_helper->sw_rotations |= rotation; 2450 return; 2451 } 2452 2453 fb_crtc->rotation = rotation; 2454 /* Rotating in hardware, fbcon should not rotate */ 2455 fb_helper->sw_rotations |= DRM_MODE_ROTATE_0; 2456 } 2457 2458 static void drm_setup_crtcs(struct drm_fb_helper *fb_helper, 2459 u32 width, u32 height) 2460 { 2461 struct drm_device *dev = fb_helper->dev; 2462 struct drm_fb_helper_crtc **crtcs; 2463 struct drm_display_mode **modes; 2464 struct drm_fb_offset *offsets; 2465 bool *enabled; 2466 int i; 2467 2468 DRM_DEBUG_KMS("\n"); 2469 /* prevent concurrent modification of connector_count by hotplug */ 2470 lockdep_assert_held(&fb_helper->lock); 2471 2472 crtcs = kcalloc(fb_helper->connector_count, 2473 sizeof(struct drm_fb_helper_crtc *), GFP_KERNEL); 2474 modes = kcalloc(fb_helper->connector_count, 2475 sizeof(struct drm_display_mode *), GFP_KERNEL); 2476 offsets = kcalloc(fb_helper->connector_count, 2477 sizeof(struct drm_fb_offset), GFP_KERNEL); 2478 enabled = kcalloc(fb_helper->connector_count, 2479 sizeof(bool), GFP_KERNEL); 2480 if (!crtcs || !modes || !enabled || !offsets) { 2481 DRM_ERROR("Memory allocation failed\n"); 2482 goto out; 2483 } 2484 2485 mutex_lock(&fb_helper->dev->mode_config.mutex); 2486 if (drm_fb_helper_probe_connector_modes(fb_helper, width, height) == 0) 2487 DRM_DEBUG_KMS("No connectors reported connected with modes\n"); 2488 drm_enable_connectors(fb_helper, enabled); 2489 2490 if (!(fb_helper->funcs->initial_config && 2491 fb_helper->funcs->initial_config(fb_helper, crtcs, modes, 2492 offsets, 2493 enabled, width, height))) { 2494 memset(modes, 0, fb_helper->connector_count*sizeof(modes[0])); 2495 memset(crtcs, 0, fb_helper->connector_count*sizeof(crtcs[0])); 2496 memset(offsets, 0, fb_helper->connector_count*sizeof(offsets[0])); 2497 2498 if (!drm_target_cloned(fb_helper, modes, offsets, 2499 enabled, width, height) && 2500 !drm_target_preferred(fb_helper, modes, offsets, 2501 enabled, width, height)) 2502 DRM_ERROR("Unable to find initial modes\n"); 2503 2504 DRM_DEBUG_KMS("picking CRTCs for %dx%d config\n", 2505 width, height); 2506 2507 drm_pick_crtcs(fb_helper, crtcs, modes, 0, width, height); 2508 } 2509 mutex_unlock(&fb_helper->dev->mode_config.mutex); 2510 2511 /* need to set the modesets up here for use later */ 2512 /* fill out the connector<->crtc mappings into the modesets */ 2513 for (i = 0; i < fb_helper->crtc_count; i++) 2514 drm_fb_helper_modeset_release(fb_helper, 2515 &fb_helper->crtc_info[i].mode_set); 2516 2517 fb_helper->sw_rotations = 0; 2518 drm_fb_helper_for_each_connector(fb_helper, i) { 2519 struct drm_display_mode *mode = modes[i]; 2520 struct drm_fb_helper_crtc *fb_crtc = crtcs[i]; 2521 struct drm_fb_offset *offset = &offsets[i]; 2522 2523 if (mode && fb_crtc) { 2524 struct drm_mode_set *modeset = &fb_crtc->mode_set; 2525 struct drm_connector *connector = 2526 fb_helper->connector_info[i]->connector; 2527 2528 DRM_DEBUG_KMS("desired mode %s set on crtc %d (%d,%d)\n", 2529 mode->name, fb_crtc->mode_set.crtc->base.id, offset->x, offset->y); 2530 2531 fb_crtc->desired_mode = mode; 2532 fb_crtc->x = offset->x; 2533 fb_crtc->y = offset->y; 2534 modeset->mode = drm_mode_duplicate(dev, 2535 fb_crtc->desired_mode); 2536 drm_connector_get(connector); 2537 drm_setup_crtc_rotation(fb_helper, fb_crtc, connector); 2538 modeset->connectors[modeset->num_connectors++] = connector; 2539 modeset->x = offset->x; 2540 modeset->y = offset->y; 2541 } 2542 } 2543 out: 2544 kfree(crtcs); 2545 kfree(modes); 2546 kfree(offsets); 2547 kfree(enabled); 2548 } 2549 2550 /* 2551 * This is a continuation of drm_setup_crtcs() that sets up anything related 2552 * to the framebuffer. During initialization, drm_setup_crtcs() is called before 2553 * the framebuffer has been allocated (fb_helper->fb and fb_helper->fbdev). 2554 * So, any setup that touches those fields needs to be done here instead of in 2555 * drm_setup_crtcs(). 2556 */ 2557 static void drm_setup_crtcs_fb(struct drm_fb_helper *fb_helper) 2558 { 2559 struct fb_info *info = fb_helper->fbdev; 2560 int i; 2561 2562 for (i = 0; i < fb_helper->crtc_count; i++) 2563 if (fb_helper->crtc_info[i].mode_set.num_connectors) 2564 fb_helper->crtc_info[i].mode_set.fb = fb_helper->fb; 2565 2566 mutex_lock(&fb_helper->dev->mode_config.mutex); 2567 drm_fb_helper_for_each_connector(fb_helper, i) { 2568 struct drm_connector *connector = 2569 fb_helper->connector_info[i]->connector; 2570 2571 /* use first connected connector for the physical dimensions */ 2572 if (connector->status == connector_status_connected) { 2573 info->var.width = connector->display_info.width_mm; 2574 info->var.height = connector->display_info.height_mm; 2575 break; 2576 } 2577 } 2578 mutex_unlock(&fb_helper->dev->mode_config.mutex); 2579 2580 switch (fb_helper->sw_rotations) { 2581 case DRM_MODE_ROTATE_0: 2582 info->fbcon_rotate_hint = FB_ROTATE_UR; 2583 break; 2584 case DRM_MODE_ROTATE_90: 2585 info->fbcon_rotate_hint = FB_ROTATE_CCW; 2586 break; 2587 case DRM_MODE_ROTATE_180: 2588 info->fbcon_rotate_hint = FB_ROTATE_UD; 2589 break; 2590 case DRM_MODE_ROTATE_270: 2591 info->fbcon_rotate_hint = FB_ROTATE_CW; 2592 break; 2593 default: 2594 /* 2595 * Multiple bits are set / multiple rotations requested 2596 * fbcon cannot handle separate rotation settings per 2597 * output, so fallback to unrotated. 2598 */ 2599 info->fbcon_rotate_hint = FB_ROTATE_UR; 2600 } 2601 } 2602 2603 /* Note: Drops fb_helper->lock before returning. */ 2604 static int 2605 __drm_fb_helper_initial_config_and_unlock(struct drm_fb_helper *fb_helper, 2606 int bpp_sel) 2607 { 2608 struct drm_device *dev = fb_helper->dev; 2609 struct fb_info *info; 2610 unsigned int width, height; 2611 int ret; 2612 2613 width = dev->mode_config.max_width; 2614 height = dev->mode_config.max_height; 2615 2616 drm_setup_crtcs(fb_helper, width, height); 2617 ret = drm_fb_helper_single_fb_probe(fb_helper, bpp_sel); 2618 if (ret < 0) { 2619 if (ret == -EAGAIN) { 2620 fb_helper->preferred_bpp = bpp_sel; 2621 fb_helper->deferred_setup = true; 2622 ret = 0; 2623 } 2624 mutex_unlock(&fb_helper->lock); 2625 2626 return ret; 2627 } 2628 drm_setup_crtcs_fb(fb_helper); 2629 2630 fb_helper->deferred_setup = false; 2631 2632 info = fb_helper->fbdev; 2633 info->var.pixclock = 0; 2634 2635 /* Need to drop locks to avoid recursive deadlock in 2636 * register_framebuffer. This is ok because the only thing left to do is 2637 * register the fbdev emulation instance in kernel_fb_helper_list. */ 2638 mutex_unlock(&fb_helper->lock); 2639 2640 ret = register_framebuffer(info); 2641 if (ret < 0) 2642 return ret; 2643 2644 dev_info(dev->dev, "fb%d: %s frame buffer device\n", 2645 info->node, info->fix.id); 2646 2647 mutex_lock(&kernel_fb_helper_lock); 2648 if (list_empty(&kernel_fb_helper_list)) 2649 register_sysrq_key('v', &sysrq_drm_fb_helper_restore_op); 2650 2651 list_add(&fb_helper->kernel_fb_list, &kernel_fb_helper_list); 2652 mutex_unlock(&kernel_fb_helper_lock); 2653 2654 return 0; 2655 } 2656 2657 /** 2658 * drm_fb_helper_initial_config - setup a sane initial connector configuration 2659 * @fb_helper: fb_helper device struct 2660 * @bpp_sel: bpp value to use for the framebuffer configuration 2661 * 2662 * Scans the CRTCs and connectors and tries to put together an initial setup. 2663 * At the moment, this is a cloned configuration across all heads with 2664 * a new framebuffer object as the backing store. 2665 * 2666 * Note that this also registers the fbdev and so allows userspace to call into 2667 * the driver through the fbdev interfaces. 2668 * 2669 * This function will call down into the &drm_fb_helper_funcs.fb_probe callback 2670 * to let the driver allocate and initialize the fbdev info structure and the 2671 * drm framebuffer used to back the fbdev. drm_fb_helper_fill_var() and 2672 * drm_fb_helper_fill_fix() are provided as helpers to setup simple default 2673 * values for the fbdev info structure. 2674 * 2675 * HANG DEBUGGING: 2676 * 2677 * When you have fbcon support built-in or already loaded, this function will do 2678 * a full modeset to setup the fbdev console. Due to locking misdesign in the 2679 * VT/fbdev subsystem that entire modeset sequence has to be done while holding 2680 * console_lock. Until console_unlock is called no dmesg lines will be sent out 2681 * to consoles, not even serial console. This means when your driver crashes, 2682 * you will see absolutely nothing else but a system stuck in this function, 2683 * with no further output. Any kind of printk() you place within your own driver 2684 * or in the drm core modeset code will also never show up. 2685 * 2686 * Standard debug practice is to run the fbcon setup without taking the 2687 * console_lock as a hack, to be able to see backtraces and crashes on the 2688 * serial line. This can be done by setting the fb.lockless_register_fb=1 kernel 2689 * cmdline option. 2690 * 2691 * The other option is to just disable fbdev emulation since very likely the 2692 * first modeset from userspace will crash in the same way, and is even easier 2693 * to debug. This can be done by setting the drm_kms_helper.fbdev_emulation=0 2694 * kernel cmdline option. 2695 * 2696 * RETURNS: 2697 * Zero if everything went ok, nonzero otherwise. 2698 */ 2699 int drm_fb_helper_initial_config(struct drm_fb_helper *fb_helper, int bpp_sel) 2700 { 2701 int ret; 2702 2703 if (!drm_fbdev_emulation) 2704 return 0; 2705 2706 mutex_lock(&fb_helper->lock); 2707 ret = __drm_fb_helper_initial_config_and_unlock(fb_helper, bpp_sel); 2708 2709 return ret; 2710 } 2711 EXPORT_SYMBOL(drm_fb_helper_initial_config); 2712 2713 /** 2714 * drm_fb_helper_hotplug_event - respond to a hotplug notification by 2715 * probing all the outputs attached to the fb 2716 * @fb_helper: driver-allocated fbdev helper, can be NULL 2717 * 2718 * Scan the connectors attached to the fb_helper and try to put together a 2719 * setup after notification of a change in output configuration. 2720 * 2721 * Called at runtime, takes the mode config locks to be able to check/change the 2722 * modeset configuration. Must be run from process context (which usually means 2723 * either the output polling work or a work item launched from the driver's 2724 * hotplug interrupt). 2725 * 2726 * Note that drivers may call this even before calling 2727 * drm_fb_helper_initial_config but only after drm_fb_helper_init. This allows 2728 * for a race-free fbcon setup and will make sure that the fbdev emulation will 2729 * not miss any hotplug events. 2730 * 2731 * RETURNS: 2732 * 0 on success and a non-zero error code otherwise. 2733 */ 2734 int drm_fb_helper_hotplug_event(struct drm_fb_helper *fb_helper) 2735 { 2736 int err = 0; 2737 2738 if (!drm_fbdev_emulation || !fb_helper) 2739 return 0; 2740 2741 mutex_lock(&fb_helper->lock); 2742 if (fb_helper->deferred_setup) { 2743 err = __drm_fb_helper_initial_config_and_unlock(fb_helper, 2744 fb_helper->preferred_bpp); 2745 return err; 2746 } 2747 2748 if (!fb_helper->fb || !drm_fb_helper_is_bound(fb_helper)) { 2749 fb_helper->delayed_hotplug = true; 2750 mutex_unlock(&fb_helper->lock); 2751 return err; 2752 } 2753 2754 DRM_DEBUG_KMS("\n"); 2755 2756 drm_setup_crtcs(fb_helper, fb_helper->fb->width, fb_helper->fb->height); 2757 drm_setup_crtcs_fb(fb_helper); 2758 mutex_unlock(&fb_helper->lock); 2759 2760 drm_fb_helper_set_par(fb_helper->fbdev); 2761 2762 return 0; 2763 } 2764 EXPORT_SYMBOL(drm_fb_helper_hotplug_event); 2765 2766 /** 2767 * drm_fb_helper_fbdev_setup() - Setup fbdev emulation 2768 * @dev: DRM device 2769 * @fb_helper: fbdev helper structure to set up 2770 * @funcs: fbdev helper functions 2771 * @preferred_bpp: Preferred bits per pixel for the device. 2772 * @dev->mode_config.preferred_depth is used if this is zero. 2773 * @max_conn_count: Maximum number of connectors. 2774 * @dev->mode_config.num_connector is used if this is zero. 2775 * 2776 * This function sets up fbdev emulation and registers fbdev for access by 2777 * userspace. If all connectors are disconnected, setup is deferred to the next 2778 * time drm_fb_helper_hotplug_event() is called. 2779 * The caller must to provide a &drm_fb_helper_funcs->fb_probe callback 2780 * function. 2781 * 2782 * See also: drm_fb_helper_initial_config() 2783 * 2784 * Returns: 2785 * Zero on success or negative error code on failure. 2786 */ 2787 int drm_fb_helper_fbdev_setup(struct drm_device *dev, 2788 struct drm_fb_helper *fb_helper, 2789 const struct drm_fb_helper_funcs *funcs, 2790 unsigned int preferred_bpp, 2791 unsigned int max_conn_count) 2792 { 2793 int ret; 2794 2795 if (!preferred_bpp) 2796 preferred_bpp = dev->mode_config.preferred_depth; 2797 if (!preferred_bpp) 2798 preferred_bpp = 32; 2799 2800 if (!max_conn_count) 2801 max_conn_count = dev->mode_config.num_connector; 2802 if (!max_conn_count) { 2803 DRM_DEV_ERROR(dev->dev, "No connectors\n"); 2804 return -EINVAL; 2805 } 2806 2807 drm_fb_helper_prepare(dev, fb_helper, funcs); 2808 2809 ret = drm_fb_helper_init(dev, fb_helper, max_conn_count); 2810 if (ret < 0) { 2811 DRM_DEV_ERROR(dev->dev, "Failed to initialize fbdev helper\n"); 2812 return ret; 2813 } 2814 2815 ret = drm_fb_helper_single_add_all_connectors(fb_helper); 2816 if (ret < 0) { 2817 DRM_DEV_ERROR(dev->dev, "Failed to add connectors\n"); 2818 goto err_drm_fb_helper_fini; 2819 } 2820 2821 if (!drm_drv_uses_atomic_modeset(dev)) 2822 drm_helper_disable_unused_functions(dev); 2823 2824 ret = drm_fb_helper_initial_config(fb_helper, preferred_bpp); 2825 if (ret < 0) { 2826 DRM_DEV_ERROR(dev->dev, "Failed to set fbdev configuration\n"); 2827 goto err_drm_fb_helper_fini; 2828 } 2829 2830 return 0; 2831 2832 err_drm_fb_helper_fini: 2833 drm_fb_helper_fini(fb_helper); 2834 2835 return ret; 2836 } 2837 EXPORT_SYMBOL(drm_fb_helper_fbdev_setup); 2838 2839 /** 2840 * drm_fb_helper_fbdev_teardown - Tear down fbdev emulation 2841 * @dev: DRM device 2842 * 2843 * This function unregisters fbdev if not already done and cleans up the 2844 * associated resources including the &drm_framebuffer. 2845 * The driver is responsible for freeing the &drm_fb_helper structure which is 2846 * stored in &drm_device->fb_helper. Do note that this pointer has been cleared 2847 * when this function returns. 2848 * 2849 * In order to support device removal/unplug while file handles are still open, 2850 * drm_fb_helper_unregister_fbi() should be called on device removal and 2851 * drm_fb_helper_fbdev_teardown() in the &drm_driver->release callback when 2852 * file handles are closed. 2853 */ 2854 void drm_fb_helper_fbdev_teardown(struct drm_device *dev) 2855 { 2856 struct drm_fb_helper *fb_helper = dev->fb_helper; 2857 struct fb_ops *fbops = NULL; 2858 2859 if (!fb_helper) 2860 return; 2861 2862 /* Unregister if it hasn't been done already */ 2863 if (fb_helper->fbdev && fb_helper->fbdev->dev) 2864 drm_fb_helper_unregister_fbi(fb_helper); 2865 2866 if (fb_helper->fbdev && fb_helper->fbdev->fbdefio) { 2867 fb_deferred_io_cleanup(fb_helper->fbdev); 2868 kfree(fb_helper->fbdev->fbdefio); 2869 fbops = fb_helper->fbdev->fbops; 2870 } 2871 2872 drm_fb_helper_fini(fb_helper); 2873 kfree(fbops); 2874 2875 if (fb_helper->fb) 2876 drm_framebuffer_remove(fb_helper->fb); 2877 } 2878 EXPORT_SYMBOL(drm_fb_helper_fbdev_teardown); 2879 2880 /** 2881 * drm_fb_helper_lastclose - DRM driver lastclose helper for fbdev emulation 2882 * @dev: DRM device 2883 * 2884 * This function can be used as the &drm_driver->lastclose callback for drivers 2885 * that only need to call drm_fb_helper_restore_fbdev_mode_unlocked(). 2886 */ 2887 void drm_fb_helper_lastclose(struct drm_device *dev) 2888 { 2889 drm_fb_helper_restore_fbdev_mode_unlocked(dev->fb_helper); 2890 } 2891 EXPORT_SYMBOL(drm_fb_helper_lastclose); 2892 2893 /** 2894 * drm_fb_helper_output_poll_changed - DRM mode config \.output_poll_changed 2895 * helper for fbdev emulation 2896 * @dev: DRM device 2897 * 2898 * This function can be used as the 2899 * &drm_mode_config_funcs.output_poll_changed callback for drivers that only 2900 * need to call drm_fb_helper_hotplug_event(). 2901 */ 2902 void drm_fb_helper_output_poll_changed(struct drm_device *dev) 2903 { 2904 drm_fb_helper_hotplug_event(dev->fb_helper); 2905 } 2906 EXPORT_SYMBOL(drm_fb_helper_output_poll_changed); 2907 2908 /* @user: 1=userspace, 0=fbcon */ 2909 static int drm_fbdev_fb_open(struct fb_info *info, int user) 2910 { 2911 struct drm_fb_helper *fb_helper = info->par; 2912 2913 if (!try_module_get(fb_helper->dev->driver->fops->owner)) 2914 return -ENODEV; 2915 2916 return 0; 2917 } 2918 2919 static int drm_fbdev_fb_release(struct fb_info *info, int user) 2920 { 2921 struct drm_fb_helper *fb_helper = info->par; 2922 2923 module_put(fb_helper->dev->driver->fops->owner); 2924 2925 return 0; 2926 } 2927 2928 /* 2929 * fb_ops.fb_destroy is called by the last put_fb_info() call at the end of 2930 * unregister_framebuffer() or fb_release(). 2931 */ 2932 static void drm_fbdev_fb_destroy(struct fb_info *info) 2933 { 2934 struct drm_fb_helper *fb_helper = info->par; 2935 struct fb_info *fbi = fb_helper->fbdev; 2936 struct fb_ops *fbops = NULL; 2937 void *shadow = NULL; 2938 2939 if (fbi->fbdefio) { 2940 fb_deferred_io_cleanup(fbi); 2941 shadow = fbi->screen_buffer; 2942 fbops = fbi->fbops; 2943 } 2944 2945 drm_fb_helper_fini(fb_helper); 2946 2947 if (shadow) { 2948 vfree(shadow); 2949 kfree(fbops); 2950 } 2951 2952 drm_client_framebuffer_delete(fb_helper->buffer); 2953 /* 2954 * FIXME: 2955 * Remove conditional when all CMA drivers have been moved over to using 2956 * drm_fbdev_generic_setup(). 2957 */ 2958 if (fb_helper->client.funcs) { 2959 drm_client_release(&fb_helper->client); 2960 kfree(fb_helper); 2961 } 2962 } 2963 2964 static int drm_fbdev_fb_mmap(struct fb_info *info, struct vm_area_struct *vma) 2965 { 2966 struct drm_fb_helper *fb_helper = info->par; 2967 2968 if (fb_helper->dev->driver->gem_prime_mmap) 2969 return fb_helper->dev->driver->gem_prime_mmap(fb_helper->buffer->gem, vma); 2970 else 2971 return -ENODEV; 2972 } 2973 2974 static struct fb_ops drm_fbdev_fb_ops = { 2975 .owner = THIS_MODULE, 2976 DRM_FB_HELPER_DEFAULT_OPS, 2977 .fb_open = drm_fbdev_fb_open, 2978 .fb_release = drm_fbdev_fb_release, 2979 .fb_destroy = drm_fbdev_fb_destroy, 2980 .fb_mmap = drm_fbdev_fb_mmap, 2981 .fb_read = drm_fb_helper_sys_read, 2982 .fb_write = drm_fb_helper_sys_write, 2983 .fb_fillrect = drm_fb_helper_sys_fillrect, 2984 .fb_copyarea = drm_fb_helper_sys_copyarea, 2985 .fb_imageblit = drm_fb_helper_sys_imageblit, 2986 }; 2987 2988 static struct fb_deferred_io drm_fbdev_defio = { 2989 .delay = HZ / 20, 2990 .deferred_io = drm_fb_helper_deferred_io, 2991 }; 2992 2993 /** 2994 * drm_fb_helper_generic_probe - Generic fbdev emulation probe helper 2995 * @fb_helper: fbdev helper structure 2996 * @sizes: describes fbdev size and scanout surface size 2997 * 2998 * This function uses the client API to crate a framebuffer backed by a dumb buffer. 2999 * 3000 * The _sys_ versions are used for &fb_ops.fb_read, fb_write, fb_fillrect, 3001 * fb_copyarea, fb_imageblit. 3002 * 3003 * Returns: 3004 * Zero on success or negative error code on failure. 3005 */ 3006 int drm_fb_helper_generic_probe(struct drm_fb_helper *fb_helper, 3007 struct drm_fb_helper_surface_size *sizes) 3008 { 3009 struct drm_client_dev *client = &fb_helper->client; 3010 struct drm_client_buffer *buffer; 3011 struct drm_framebuffer *fb; 3012 struct fb_info *fbi; 3013 u32 format; 3014 int ret; 3015 3016 DRM_DEBUG_KMS("surface width(%d), height(%d) and bpp(%d)\n", 3017 sizes->surface_width, sizes->surface_height, 3018 sizes->surface_bpp); 3019 3020 format = drm_mode_legacy_fb_format(sizes->surface_bpp, sizes->surface_depth); 3021 buffer = drm_client_framebuffer_create(client, sizes->surface_width, 3022 sizes->surface_height, format); 3023 if (IS_ERR(buffer)) 3024 return PTR_ERR(buffer); 3025 3026 fb_helper->buffer = buffer; 3027 fb_helper->fb = buffer->fb; 3028 fb = buffer->fb; 3029 3030 fbi = drm_fb_helper_alloc_fbi(fb_helper); 3031 if (IS_ERR(fbi)) { 3032 ret = PTR_ERR(fbi); 3033 goto err_free_buffer; 3034 } 3035 3036 fbi->par = fb_helper; 3037 fbi->fbops = &drm_fbdev_fb_ops; 3038 fbi->screen_size = fb->height * fb->pitches[0]; 3039 fbi->fix.smem_len = fbi->screen_size; 3040 fbi->screen_buffer = buffer->vaddr; 3041 strcpy(fbi->fix.id, "DRM emulated"); 3042 3043 drm_fb_helper_fill_fix(fbi, fb->pitches[0], fb->format->depth); 3044 drm_fb_helper_fill_var(fbi, fb_helper, sizes->fb_width, sizes->fb_height); 3045 3046 if (fb->funcs->dirty) { 3047 struct fb_ops *fbops; 3048 void *shadow; 3049 3050 /* 3051 * fb_deferred_io_cleanup() clears &fbops->fb_mmap so a per 3052 * instance version is necessary. 3053 */ 3054 fbops = kzalloc(sizeof(*fbops), GFP_KERNEL); 3055 shadow = vzalloc(fbi->screen_size); 3056 if (!fbops || !shadow) { 3057 kfree(fbops); 3058 vfree(shadow); 3059 ret = -ENOMEM; 3060 goto err_fb_info_destroy; 3061 } 3062 3063 *fbops = *fbi->fbops; 3064 fbi->fbops = fbops; 3065 fbi->screen_buffer = shadow; 3066 fbi->fbdefio = &drm_fbdev_defio; 3067 3068 fb_deferred_io_init(fbi); 3069 } 3070 3071 return 0; 3072 3073 err_fb_info_destroy: 3074 drm_fb_helper_fini(fb_helper); 3075 err_free_buffer: 3076 drm_client_framebuffer_delete(buffer); 3077 3078 return ret; 3079 } 3080 EXPORT_SYMBOL(drm_fb_helper_generic_probe); 3081 3082 static const struct drm_fb_helper_funcs drm_fb_helper_generic_funcs = { 3083 .fb_probe = drm_fb_helper_generic_probe, 3084 }; 3085 3086 static void drm_fbdev_client_unregister(struct drm_client_dev *client) 3087 { 3088 struct drm_fb_helper *fb_helper = drm_fb_helper_from_client(client); 3089 3090 if (fb_helper->fbdev) { 3091 drm_fb_helper_unregister_fbi(fb_helper); 3092 /* drm_fbdev_fb_destroy() takes care of cleanup */ 3093 return; 3094 } 3095 3096 /* Did drm_fb_helper_fbdev_setup() run? */ 3097 if (fb_helper->dev) 3098 drm_fb_helper_fini(fb_helper); 3099 3100 drm_client_release(client); 3101 kfree(fb_helper); 3102 } 3103 3104 static int drm_fbdev_client_restore(struct drm_client_dev *client) 3105 { 3106 struct drm_fb_helper *fb_helper = drm_fb_helper_from_client(client); 3107 3108 drm_fb_helper_restore_fbdev_mode_unlocked(fb_helper); 3109 3110 return 0; 3111 } 3112 3113 static int drm_fbdev_client_hotplug(struct drm_client_dev *client) 3114 { 3115 struct drm_fb_helper *fb_helper = drm_fb_helper_from_client(client); 3116 struct drm_device *dev = client->dev; 3117 int ret; 3118 3119 /* If drm_fb_helper_fbdev_setup() failed, we only try once */ 3120 if (!fb_helper->dev && fb_helper->funcs) 3121 return 0; 3122 3123 if (dev->fb_helper) 3124 return drm_fb_helper_hotplug_event(dev->fb_helper); 3125 3126 if (!dev->mode_config.num_connector) 3127 return 0; 3128 3129 ret = drm_fb_helper_fbdev_setup(dev, fb_helper, &drm_fb_helper_generic_funcs, 3130 fb_helper->preferred_bpp, 0); 3131 if (ret) { 3132 fb_helper->dev = NULL; 3133 fb_helper->fbdev = NULL; 3134 return ret; 3135 } 3136 3137 return 0; 3138 } 3139 3140 static const struct drm_client_funcs drm_fbdev_client_funcs = { 3141 .owner = THIS_MODULE, 3142 .unregister = drm_fbdev_client_unregister, 3143 .restore = drm_fbdev_client_restore, 3144 .hotplug = drm_fbdev_client_hotplug, 3145 }; 3146 3147 /** 3148 * drm_fb_helper_generic_fbdev_setup() - Setup generic fbdev emulation 3149 * @dev: DRM device 3150 * @preferred_bpp: Preferred bits per pixel for the device. 3151 * @dev->mode_config.preferred_depth is used if this is zero. 3152 * 3153 * This function sets up generic fbdev emulation for drivers that supports 3154 * dumb buffers with a virtual address and that can be mmap'ed. 3155 * 3156 * Restore, hotplug events and teardown are all taken care of. Drivers that do 3157 * suspend/resume need to call drm_fb_helper_set_suspend_unlocked() themselves. 3158 * Simple drivers might use drm_mode_config_helper_suspend(). 3159 * 3160 * Drivers that set the dirty callback on their framebuffer will get a shadow 3161 * fbdev buffer that is blitted onto the real buffer. This is done in order to 3162 * make deferred I/O work with all kinds of buffers. 3163 * 3164 * This function is safe to call even when there are no connectors present. 3165 * Setup will be retried on the next hotplug event. 3166 * 3167 * Returns: 3168 * Zero on success or negative error code on failure. 3169 */ 3170 int drm_fbdev_generic_setup(struct drm_device *dev, unsigned int preferred_bpp) 3171 { 3172 struct drm_fb_helper *fb_helper; 3173 int ret; 3174 3175 if (!drm_fbdev_emulation) 3176 return 0; 3177 3178 fb_helper = kzalloc(sizeof(*fb_helper), GFP_KERNEL); 3179 if (!fb_helper) 3180 return -ENOMEM; 3181 3182 ret = drm_client_init(dev, &fb_helper->client, "fbdev", &drm_fbdev_client_funcs); 3183 if (ret) { 3184 kfree(fb_helper); 3185 return ret; 3186 } 3187 3188 drm_client_add(&fb_helper->client); 3189 3190 fb_helper->preferred_bpp = preferred_bpp; 3191 3192 drm_fbdev_client_hotplug(&fb_helper->client); 3193 3194 return 0; 3195 } 3196 EXPORT_SYMBOL(drm_fbdev_generic_setup); 3197 3198 /* The Kconfig DRM_KMS_HELPER selects FRAMEBUFFER_CONSOLE (if !EXPERT) 3199 * but the module doesn't depend on any fb console symbols. At least 3200 * attempt to load fbcon to avoid leaving the system without a usable console. 3201 */ 3202 int __init drm_fb_helper_modinit(void) 3203 { 3204 #if defined(CONFIG_FRAMEBUFFER_CONSOLE_MODULE) && !defined(CONFIG_EXPERT) 3205 const char name[] = "fbcon"; 3206 struct module *fbcon; 3207 3208 mutex_lock(&module_mutex); 3209 fbcon = find_module(name); 3210 mutex_unlock(&module_mutex); 3211 3212 if (!fbcon) 3213 request_module_nowait(name); 3214 #endif 3215 return 0; 3216 } 3217 EXPORT_SYMBOL(drm_fb_helper_modinit); 3218