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