Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/fb-helper: Move generic fbdev emulation into separate source file

Move the generic fbdev implementation into its own source and header
file. Adapt drivers. No functional changes, but some of the internal
helpers have been renamed to fit into the drm_fbdev_ naming scheme.

v3:
* rename drm_fbdev.{c,h} to drm_fbdev_generic.{c,h}
* rebase onto vmwgfx changes
* rebase onto xlnx changes
* fix include statements in amdgpu

Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
Reviewed-by: Javier Martinez Canillas <javierm@redhat.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20221103151446.2638-22-tzimmermann@suse.de

+571 -558
+3 -1
drivers/gpu/drm/Makefile
··· 117 117 drm_self_refresh_helper.o \ 118 118 drm_simple_kms_helper.o 119 119 drm_kms_helper-$(CONFIG_DRM_PANEL_BRIDGE) += bridge/panel.o 120 - drm_kms_helper-$(CONFIG_DRM_FBDEV_EMULATION) += drm_fb_helper.o 120 + drm_kms_helper-$(CONFIG_DRM_FBDEV_EMULATION) += \ 121 + drm_fbdev_generic.o \ 122 + drm_fb_helper.o 121 123 obj-$(CONFIG_DRM_KMS_HELPER) += drm_kms_helper.o 122 124 123 125 #
+1
drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
··· 25 25 #include <drm/amdgpu_drm.h> 26 26 #include <drm/drm_aperture.h> 27 27 #include <drm/drm_drv.h> 28 + #include <drm/drm_fbdev_generic.h> 28 29 #include <drm/drm_gem.h> 29 30 #include <drm/drm_vblank.h> 30 31 #include <drm/drm_managed.h>
+1 -1
drivers/gpu/drm/arm/display/komeda/komeda_drv.c
··· 9 9 #include <linux/platform_device.h> 10 10 #include <linux/component.h> 11 11 #include <linux/pm_runtime.h> 12 - #include <drm/drm_fb_helper.h> 12 + #include <drm/drm_fbdev_generic.h> 13 13 #include <drm/drm_module.h> 14 14 #include <drm/drm_of.h> 15 15 #include "komeda_dev.h"
+1 -1
drivers/gpu/drm/arm/hdlcd_drv.c
··· 26 26 #include <drm/drm_crtc.h> 27 27 #include <drm/drm_debugfs.h> 28 28 #include <drm/drm_drv.h> 29 - #include <drm/drm_fb_helper.h> 29 + #include <drm/drm_fbdev_generic.h> 30 30 #include <drm/drm_gem_dma_helper.h> 31 31 #include <drm/drm_gem_framebuffer_helper.h> 32 32 #include <drm/drm_modeset_helper.h>
+1 -1
drivers/gpu/drm/arm/malidp_drv.c
··· 19 19 #include <drm/drm_atomic_helper.h> 20 20 #include <drm/drm_crtc.h> 21 21 #include <drm/drm_drv.h> 22 - #include <drm/drm_fb_helper.h> 22 + #include <drm/drm_fbdev_generic.h> 23 23 #include <drm/drm_fourcc.h> 24 24 #include <drm/drm_gem_dma_helper.h> 25 25 #include <drm/drm_gem_framebuffer_helper.h>
+1 -1
drivers/gpu/drm/aspeed/aspeed_gfx_drv.c
··· 16 16 #include <drm/drm_atomic_helper.h> 17 17 #include <drm/drm_crtc_helper.h> 18 18 #include <drm/drm_device.h> 19 - #include <drm/drm_fb_helper.h> 19 + #include <drm/drm_fbdev_generic.h> 20 20 #include <drm/drm_gem_dma_helper.h> 21 21 #include <drm/drm_gem_framebuffer_helper.h> 22 22 #include <drm/drm_module.h>
+1
drivers/gpu/drm/ast/ast_drv.c
··· 33 33 #include <drm/drm_atomic_helper.h> 34 34 #include <drm/drm_crtc_helper.h> 35 35 #include <drm/drm_drv.h> 36 + #include <drm/drm_fbdev_generic.h> 36 37 #include <drm/drm_gem_shmem_helper.h> 37 38 #include <drm/drm_module.h> 38 39 #include <drm/drm_probe_helper.h>
+1 -1
drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c
··· 19 19 #include <drm/drm_atomic.h> 20 20 #include <drm/drm_atomic_helper.h> 21 21 #include <drm/drm_drv.h> 22 - #include <drm/drm_fb_helper.h> 22 + #include <drm/drm_fbdev_generic.h> 23 23 #include <drm/drm_gem_dma_helper.h> 24 24 #include <drm/drm_gem_framebuffer_helper.h> 25 25 #include <drm/drm_module.h>
+2 -496
drivers/gpu/drm/drm_fb_helper.c
··· 30 30 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 31 31 32 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 33 #include <linux/sysrq.h> 38 - #include <linux/vmalloc.h> 39 34 40 35 #include <drm/drm_atomic.h> 41 - #include <drm/drm_crtc.h> 42 - #include <drm/drm_crtc_helper.h> 43 36 #include <drm/drm_drv.h> 44 37 #include <drm/drm_fb_helper.h> 45 38 #include <drm/drm_fourcc.h> 46 39 #include <drm/drm_framebuffer.h> 40 + #include <drm/drm_modeset_helper_vtables.h> 47 41 #include <drm/drm_print.h> 48 42 #include <drm/drm_vblank.h> 49 43 50 - #include "drm_crtc_helper_internal.h" 51 44 #include "drm_internal.h" 52 45 53 46 static bool drm_fbdev_emulation = true; ··· 363 370 console_lock(); 364 371 fb_set_suspend(helper->info, 0); 365 372 console_unlock(); 366 - } 367 - 368 - static void drm_fb_helper_damage_blit_real(struct drm_fb_helper *fb_helper, 369 - struct drm_clip_rect *clip, 370 - struct iosys_map *dst) 371 - { 372 - struct drm_framebuffer *fb = fb_helper->fb; 373 - size_t offset = clip->y1 * fb->pitches[0]; 374 - size_t len = clip->x2 - clip->x1; 375 - unsigned int y; 376 - void *src; 377 - 378 - switch (drm_format_info_bpp(fb->format, 0)) { 379 - case 1: 380 - offset += clip->x1 / 8; 381 - len = DIV_ROUND_UP(len + clip->x1 % 8, 8); 382 - break; 383 - case 2: 384 - offset += clip->x1 / 4; 385 - len = DIV_ROUND_UP(len + clip->x1 % 4, 4); 386 - break; 387 - case 4: 388 - offset += clip->x1 / 2; 389 - len = DIV_ROUND_UP(len + clip->x1 % 2, 2); 390 - break; 391 - default: 392 - offset += clip->x1 * fb->format->cpp[0]; 393 - len *= fb->format->cpp[0]; 394 - break; 395 - } 396 - 397 - src = fb_helper->info->screen_buffer + offset; 398 - iosys_map_incr(dst, offset); /* go to first pixel within clip rect */ 399 - 400 - for (y = clip->y1; y < clip->y2; y++) { 401 - iosys_map_memcpy_to(dst, 0, src, len); 402 - iosys_map_incr(dst, fb->pitches[0]); 403 - src += fb->pitches[0]; 404 - } 405 - } 406 - 407 - static int drm_fb_helper_damage_blit(struct drm_fb_helper *fb_helper, 408 - struct drm_clip_rect *clip) 409 - { 410 - struct drm_client_buffer *buffer = fb_helper->buffer; 411 - struct iosys_map map, dst; 412 - int ret; 413 - 414 - /* 415 - * We have to pin the client buffer to its current location while 416 - * flushing the shadow buffer. In the general case, concurrent 417 - * modesetting operations could try to move the buffer and would 418 - * fail. The modeset has to be serialized by acquiring the reservation 419 - * object of the underlying BO here. 420 - * 421 - * For fbdev emulation, we only have to protect against fbdev modeset 422 - * operations. Nothing else will involve the client buffer's BO. So it 423 - * is sufficient to acquire struct drm_fb_helper.lock here. 424 - */ 425 - mutex_lock(&fb_helper->lock); 426 - 427 - ret = drm_client_buffer_vmap(buffer, &map); 428 - if (ret) 429 - goto out; 430 - 431 - dst = map; 432 - drm_fb_helper_damage_blit_real(fb_helper, clip, &dst); 433 - 434 - drm_client_buffer_vunmap(buffer); 435 - 436 - out: 437 - mutex_unlock(&fb_helper->lock); 438 - 439 - return ret; 440 373 } 441 374 442 375 static void drm_fb_helper_damage_work(struct work_struct *work) ··· 2245 2326 * 2246 2327 * This function can be used as the 2247 2328 * &drm_mode_config_funcs.output_poll_changed callback for drivers that only 2248 - * need to call drm_fb_helper_hotplug_event(). 2329 + * need to call drm_fbdev.hotplug_event(). 2249 2330 */ 2250 2331 void drm_fb_helper_output_poll_changed(struct drm_device *dev) 2251 2332 { 2252 2333 drm_fb_helper_hotplug_event(dev->fb_helper); 2253 2334 } 2254 2335 EXPORT_SYMBOL(drm_fb_helper_output_poll_changed); 2255 - 2256 - static bool drm_fbdev_use_shadow_fb(struct drm_fb_helper *fb_helper) 2257 - { 2258 - struct drm_device *dev = fb_helper->dev; 2259 - struct drm_framebuffer *fb = fb_helper->fb; 2260 - 2261 - return dev->mode_config.prefer_shadow_fbdev || 2262 - dev->mode_config.prefer_shadow || 2263 - fb->funcs->dirty; 2264 - } 2265 - 2266 - /* @user: 1=userspace, 0=fbcon */ 2267 - static int drm_fbdev_fb_open(struct fb_info *info, int user) 2268 - { 2269 - struct drm_fb_helper *fb_helper = info->par; 2270 - 2271 - /* No need to take a ref for fbcon because it unbinds on unregister */ 2272 - if (user && !try_module_get(fb_helper->dev->driver->fops->owner)) 2273 - return -ENODEV; 2274 - 2275 - return 0; 2276 - } 2277 - 2278 - static int drm_fbdev_fb_release(struct fb_info *info, int user) 2279 - { 2280 - struct drm_fb_helper *fb_helper = info->par; 2281 - 2282 - if (user) 2283 - module_put(fb_helper->dev->driver->fops->owner); 2284 - 2285 - return 0; 2286 - } 2287 - 2288 - static void drm_fbdev_cleanup(struct drm_fb_helper *fb_helper) 2289 - { 2290 - struct fb_info *fbi = fb_helper->info; 2291 - void *shadow = NULL; 2292 - 2293 - if (!fb_helper->dev) 2294 - return; 2295 - 2296 - if (fbi) { 2297 - if (fbi->fbdefio) 2298 - fb_deferred_io_cleanup(fbi); 2299 - if (drm_fbdev_use_shadow_fb(fb_helper)) 2300 - shadow = fbi->screen_buffer; 2301 - } 2302 - 2303 - drm_fb_helper_fini(fb_helper); 2304 - 2305 - if (shadow) 2306 - vfree(shadow); 2307 - else if (fb_helper->buffer) 2308 - drm_client_buffer_vunmap(fb_helper->buffer); 2309 - 2310 - drm_client_framebuffer_delete(fb_helper->buffer); 2311 - } 2312 - 2313 - static void drm_fbdev_release(struct drm_fb_helper *fb_helper) 2314 - { 2315 - drm_fbdev_cleanup(fb_helper); 2316 - drm_client_release(&fb_helper->client); 2317 - kfree(fb_helper); 2318 - } 2319 - 2320 - /* 2321 - * fb_ops.fb_destroy is called by the last put_fb_info() call at the end of 2322 - * unregister_framebuffer() or fb_release(). 2323 - */ 2324 - static void drm_fbdev_fb_destroy(struct fb_info *info) 2325 - { 2326 - drm_fbdev_release(info->par); 2327 - } 2328 - 2329 - static int drm_fbdev_fb_mmap(struct fb_info *info, struct vm_area_struct *vma) 2330 - { 2331 - struct drm_fb_helper *fb_helper = info->par; 2332 - 2333 - if (drm_fbdev_use_shadow_fb(fb_helper)) 2334 - return fb_deferred_io_mmap(info, vma); 2335 - else if (fb_helper->dev->driver->gem_prime_mmap) 2336 - return fb_helper->dev->driver->gem_prime_mmap(fb_helper->buffer->gem, vma); 2337 - else 2338 - return -ENODEV; 2339 - } 2340 - 2341 - static bool drm_fbdev_use_iomem(struct fb_info *info) 2342 - { 2343 - struct drm_fb_helper *fb_helper = info->par; 2344 - struct drm_client_buffer *buffer = fb_helper->buffer; 2345 - 2346 - return !drm_fbdev_use_shadow_fb(fb_helper) && buffer->map.is_iomem; 2347 - } 2348 - 2349 - static ssize_t drm_fbdev_fb_read(struct fb_info *info, char __user *buf, 2350 - size_t count, loff_t *ppos) 2351 - { 2352 - ssize_t ret; 2353 - 2354 - if (drm_fbdev_use_iomem(info)) 2355 - ret = drm_fb_helper_cfb_read(info, buf, count, ppos); 2356 - else 2357 - ret = drm_fb_helper_sys_read(info, buf, count, ppos); 2358 - 2359 - return ret; 2360 - } 2361 - 2362 - static ssize_t drm_fbdev_fb_write(struct fb_info *info, const char __user *buf, 2363 - size_t count, loff_t *ppos) 2364 - { 2365 - ssize_t ret; 2366 - 2367 - if (drm_fbdev_use_iomem(info)) 2368 - ret = drm_fb_helper_cfb_write(info, buf, count, ppos); 2369 - else 2370 - ret = drm_fb_helper_sys_write(info, buf, count, ppos); 2371 - 2372 - return ret; 2373 - } 2374 - 2375 - static void drm_fbdev_fb_fillrect(struct fb_info *info, 2376 - const struct fb_fillrect *rect) 2377 - { 2378 - if (drm_fbdev_use_iomem(info)) 2379 - drm_fb_helper_cfb_fillrect(info, rect); 2380 - else 2381 - drm_fb_helper_sys_fillrect(info, rect); 2382 - } 2383 - 2384 - static void drm_fbdev_fb_copyarea(struct fb_info *info, 2385 - const struct fb_copyarea *area) 2386 - { 2387 - if (drm_fbdev_use_iomem(info)) 2388 - drm_fb_helper_cfb_copyarea(info, area); 2389 - else 2390 - drm_fb_helper_sys_copyarea(info, area); 2391 - } 2392 - 2393 - static void drm_fbdev_fb_imageblit(struct fb_info *info, 2394 - const struct fb_image *image) 2395 - { 2396 - if (drm_fbdev_use_iomem(info)) 2397 - drm_fb_helper_cfb_imageblit(info, image); 2398 - else 2399 - drm_fb_helper_sys_imageblit(info, image); 2400 - } 2401 - 2402 - static const struct fb_ops drm_fbdev_fb_ops = { 2403 - .owner = THIS_MODULE, 2404 - DRM_FB_HELPER_DEFAULT_OPS, 2405 - .fb_open = drm_fbdev_fb_open, 2406 - .fb_release = drm_fbdev_fb_release, 2407 - .fb_destroy = drm_fbdev_fb_destroy, 2408 - .fb_mmap = drm_fbdev_fb_mmap, 2409 - .fb_read = drm_fbdev_fb_read, 2410 - .fb_write = drm_fbdev_fb_write, 2411 - .fb_fillrect = drm_fbdev_fb_fillrect, 2412 - .fb_copyarea = drm_fbdev_fb_copyarea, 2413 - .fb_imageblit = drm_fbdev_fb_imageblit, 2414 - }; 2415 - 2416 - static struct fb_deferred_io drm_fbdev_defio = { 2417 - .delay = HZ / 20, 2418 - .deferred_io = drm_fb_helper_deferred_io, 2419 - }; 2420 - 2421 - /* 2422 - * This function uses the client API to create a framebuffer backed by a dumb buffer. 2423 - * 2424 - * The _sys_ versions are used for &fb_ops.fb_read, fb_write, fb_fillrect, 2425 - * fb_copyarea, fb_imageblit. 2426 - */ 2427 - static int drm_fb_helper_generic_probe(struct drm_fb_helper *fb_helper, 2428 - struct drm_fb_helper_surface_size *sizes) 2429 - { 2430 - struct drm_client_dev *client = &fb_helper->client; 2431 - struct drm_device *dev = fb_helper->dev; 2432 - struct drm_client_buffer *buffer; 2433 - struct drm_framebuffer *fb; 2434 - struct fb_info *fbi; 2435 - u32 format; 2436 - struct iosys_map map; 2437 - int ret; 2438 - 2439 - drm_dbg_kms(dev, "surface width(%d), height(%d) and bpp(%d)\n", 2440 - sizes->surface_width, sizes->surface_height, 2441 - sizes->surface_bpp); 2442 - 2443 - format = drm_mode_legacy_fb_format(sizes->surface_bpp, sizes->surface_depth); 2444 - buffer = drm_client_framebuffer_create(client, sizes->surface_width, 2445 - sizes->surface_height, format); 2446 - if (IS_ERR(buffer)) 2447 - return PTR_ERR(buffer); 2448 - 2449 - fb_helper->buffer = buffer; 2450 - fb_helper->fb = buffer->fb; 2451 - fb = buffer->fb; 2452 - 2453 - fbi = drm_fb_helper_alloc_info(fb_helper); 2454 - if (IS_ERR(fbi)) 2455 - return PTR_ERR(fbi); 2456 - 2457 - fbi->fbops = &drm_fbdev_fb_ops; 2458 - fbi->screen_size = sizes->surface_height * fb->pitches[0]; 2459 - fbi->fix.smem_len = fbi->screen_size; 2460 - fbi->flags = FBINFO_DEFAULT; 2461 - 2462 - drm_fb_helper_fill_info(fbi, fb_helper, sizes); 2463 - 2464 - if (drm_fbdev_use_shadow_fb(fb_helper)) { 2465 - fbi->screen_buffer = vzalloc(fbi->screen_size); 2466 - if (!fbi->screen_buffer) 2467 - return -ENOMEM; 2468 - fbi->flags |= FBINFO_VIRTFB | FBINFO_READS_FAST; 2469 - 2470 - fbi->fbdefio = &drm_fbdev_defio; 2471 - fb_deferred_io_init(fbi); 2472 - } else { 2473 - /* buffer is mapped for HW framebuffer */ 2474 - ret = drm_client_buffer_vmap(fb_helper->buffer, &map); 2475 - if (ret) 2476 - return ret; 2477 - if (map.is_iomem) { 2478 - fbi->screen_base = map.vaddr_iomem; 2479 - } else { 2480 - fbi->screen_buffer = map.vaddr; 2481 - fbi->flags |= FBINFO_VIRTFB; 2482 - } 2483 - 2484 - /* 2485 - * Shamelessly leak the physical address to user-space. As 2486 - * page_to_phys() is undefined for I/O memory, warn in this 2487 - * case. 2488 - */ 2489 - #if IS_ENABLED(CONFIG_DRM_FBDEV_LEAK_PHYS_SMEM) 2490 - if (fb_helper->hint_leak_smem_start && fbi->fix.smem_start == 0 && 2491 - !drm_WARN_ON_ONCE(dev, map.is_iomem)) 2492 - fbi->fix.smem_start = 2493 - page_to_phys(virt_to_page(fbi->screen_buffer)); 2494 - #endif 2495 - } 2496 - 2497 - return 0; 2498 - } 2499 - 2500 - static int drm_fbdev_fb_dirty(struct drm_fb_helper *helper, struct drm_clip_rect *clip) 2501 - { 2502 - struct drm_device *dev = helper->dev; 2503 - int ret; 2504 - 2505 - if (!drm_fbdev_use_shadow_fb(helper)) 2506 - return 0; 2507 - 2508 - /* Call damage handlers only if necessary */ 2509 - if (!(clip->x1 < clip->x2 && clip->y1 < clip->y2)) 2510 - return 0; 2511 - 2512 - if (helper->buffer) { 2513 - ret = drm_fb_helper_damage_blit(helper, clip); 2514 - if (drm_WARN_ONCE(dev, ret, "Damage blitter failed: ret=%d\n", ret)) 2515 - return ret; 2516 - } 2517 - 2518 - if (helper->fb->funcs->dirty) { 2519 - ret = helper->fb->funcs->dirty(helper->fb, NULL, 0, 0, clip, 1); 2520 - if (drm_WARN_ONCE(dev, ret, "Dirty helper failed: ret=%d\n", ret)) 2521 - return ret; 2522 - } 2523 - 2524 - return 0; 2525 - } 2526 - 2527 - static const struct drm_fb_helper_funcs drm_fb_helper_generic_funcs = { 2528 - .fb_probe = drm_fb_helper_generic_probe, 2529 - .fb_dirty = drm_fbdev_fb_dirty, 2530 - }; 2531 - 2532 - static void drm_fbdev_client_unregister(struct drm_client_dev *client) 2533 - { 2534 - struct drm_fb_helper *fb_helper = drm_fb_helper_from_client(client); 2535 - 2536 - if (fb_helper->info) 2537 - /* drm_fbdev_fb_destroy() takes care of cleanup */ 2538 - drm_fb_helper_unregister_info(fb_helper); 2539 - else 2540 - drm_fbdev_release(fb_helper); 2541 - } 2542 - 2543 - static int drm_fbdev_client_restore(struct drm_client_dev *client) 2544 - { 2545 - drm_fb_helper_lastclose(client->dev); 2546 - 2547 - return 0; 2548 - } 2549 - 2550 - static int drm_fbdev_client_hotplug(struct drm_client_dev *client) 2551 - { 2552 - struct drm_fb_helper *fb_helper = drm_fb_helper_from_client(client); 2553 - struct drm_device *dev = client->dev; 2554 - int ret; 2555 - 2556 - /* Setup is not retried if it has failed */ 2557 - if (!fb_helper->dev && fb_helper->funcs) 2558 - return 0; 2559 - 2560 - if (dev->fb_helper) 2561 - return drm_fb_helper_hotplug_event(dev->fb_helper); 2562 - 2563 - if (!dev->mode_config.num_connector) { 2564 - drm_dbg_kms(dev, "No connectors found, will not create framebuffer!\n"); 2565 - return 0; 2566 - } 2567 - 2568 - drm_fb_helper_prepare(dev, fb_helper, &drm_fb_helper_generic_funcs); 2569 - 2570 - ret = drm_fb_helper_init(dev, fb_helper); 2571 - if (ret) 2572 - goto err; 2573 - 2574 - if (!drm_drv_uses_atomic_modeset(dev)) 2575 - drm_helper_disable_unused_functions(dev); 2576 - 2577 - ret = drm_fb_helper_initial_config(fb_helper, fb_helper->preferred_bpp); 2578 - if (ret) 2579 - goto err_cleanup; 2580 - 2581 - return 0; 2582 - 2583 - err_cleanup: 2584 - drm_fbdev_cleanup(fb_helper); 2585 - err: 2586 - fb_helper->dev = NULL; 2587 - fb_helper->info = NULL; 2588 - 2589 - drm_err(dev, "fbdev: Failed to setup generic emulation (ret=%d)\n", ret); 2590 - 2591 - return ret; 2592 - } 2593 - 2594 - static const struct drm_client_funcs drm_fbdev_client_funcs = { 2595 - .owner = THIS_MODULE, 2596 - .unregister = drm_fbdev_client_unregister, 2597 - .restore = drm_fbdev_client_restore, 2598 - .hotplug = drm_fbdev_client_hotplug, 2599 - }; 2600 - 2601 - /** 2602 - * drm_fbdev_generic_setup() - Setup generic fbdev emulation 2603 - * @dev: DRM device 2604 - * @preferred_bpp: Preferred bits per pixel for the device. 2605 - * @dev->mode_config.preferred_depth is used if this is zero. 2606 - * 2607 - * This function sets up generic fbdev emulation for drivers that supports 2608 - * dumb buffers with a virtual address and that can be mmap'ed. 2609 - * drm_fbdev_generic_setup() shall be called after the DRM driver registered 2610 - * the new DRM device with drm_dev_register(). 2611 - * 2612 - * Restore, hotplug events and teardown are all taken care of. Drivers that do 2613 - * suspend/resume need to call drm_fb_helper_set_suspend_unlocked() themselves. 2614 - * Simple drivers might use drm_mode_config_helper_suspend(). 2615 - * 2616 - * Drivers that set the dirty callback on their framebuffer will get a shadow 2617 - * fbdev buffer that is blitted onto the real buffer. This is done in order to 2618 - * make deferred I/O work with all kinds of buffers. A shadow buffer can be 2619 - * requested explicitly by setting struct drm_mode_config.prefer_shadow or 2620 - * struct drm_mode_config.prefer_shadow_fbdev to true beforehand. This is 2621 - * required to use generic fbdev emulation with SHMEM helpers. 2622 - * 2623 - * This function is safe to call even when there are no connectors present. 2624 - * Setup will be retried on the next hotplug event. 2625 - * 2626 - * The fbdev is destroyed by drm_dev_unregister(). 2627 - */ 2628 - void drm_fbdev_generic_setup(struct drm_device *dev, 2629 - unsigned int preferred_bpp) 2630 - { 2631 - struct drm_fb_helper *fb_helper; 2632 - int ret; 2633 - 2634 - drm_WARN(dev, !dev->registered, "Device has not been registered.\n"); 2635 - drm_WARN(dev, dev->fb_helper, "fb_helper is already set!\n"); 2636 - 2637 - fb_helper = kzalloc(sizeof(*fb_helper), GFP_KERNEL); 2638 - if (!fb_helper) { 2639 - drm_err(dev, "Failed to allocate fb_helper\n"); 2640 - return; 2641 - } 2642 - 2643 - ret = drm_client_init(dev, &fb_helper->client, "fbdev", &drm_fbdev_client_funcs); 2644 - if (ret) { 2645 - kfree(fb_helper); 2646 - drm_err(dev, "Failed to register client: %d\n", ret); 2647 - return; 2648 - } 2649 - 2650 - /* 2651 - * FIXME: This mixes up depth with bpp, which results in a glorious 2652 - * mess, resulting in some drivers picking wrong fbdev defaults and 2653 - * others wrong preferred_depth defaults. 2654 - */ 2655 - if (!preferred_bpp) 2656 - preferred_bpp = dev->mode_config.preferred_depth; 2657 - if (!preferred_bpp) 2658 - preferred_bpp = 32; 2659 - fb_helper->preferred_bpp = preferred_bpp; 2660 - 2661 - ret = drm_fbdev_client_hotplug(&fb_helper->client); 2662 - if (ret) 2663 - drm_dbg_kms(dev, "client hotplug ret=%d\n", ret); 2664 - 2665 - drm_client_register(&fb_helper->client); 2666 - } 2667 - EXPORT_SYMBOL(drm_fbdev_generic_setup);
+493
drivers/gpu/drm/drm_fbdev_generic.c
··· 1 + // SPDX-License-Identifier: MIT 2 + 3 + #include <linux/moduleparam.h> 4 + 5 + #include <drm/drm_crtc_helper.h> 6 + #include <drm/drm_drv.h> 7 + #include <drm/drm_fb_helper.h> 8 + #include <drm/drm_framebuffer.h> 9 + #include <drm/drm_print.h> 10 + 11 + #include <drm/drm_fbdev_generic.h> 12 + 13 + static bool drm_fbdev_use_shadow_fb(struct drm_fb_helper *fb_helper) 14 + { 15 + struct drm_device *dev = fb_helper->dev; 16 + struct drm_framebuffer *fb = fb_helper->fb; 17 + 18 + return dev->mode_config.prefer_shadow_fbdev || 19 + dev->mode_config.prefer_shadow || 20 + fb->funcs->dirty; 21 + } 22 + 23 + /* @user: 1=userspace, 0=fbcon */ 24 + static int drm_fbdev_fb_open(struct fb_info *info, int user) 25 + { 26 + struct drm_fb_helper *fb_helper = info->par; 27 + 28 + /* No need to take a ref for fbcon because it unbinds on unregister */ 29 + if (user && !try_module_get(fb_helper->dev->driver->fops->owner)) 30 + return -ENODEV; 31 + 32 + return 0; 33 + } 34 + 35 + static int drm_fbdev_fb_release(struct fb_info *info, int user) 36 + { 37 + struct drm_fb_helper *fb_helper = info->par; 38 + 39 + if (user) 40 + module_put(fb_helper->dev->driver->fops->owner); 41 + 42 + return 0; 43 + } 44 + 45 + static void drm_fbdev_cleanup(struct drm_fb_helper *fb_helper) 46 + { 47 + struct fb_info *fbi = fb_helper->info; 48 + void *shadow = NULL; 49 + 50 + if (!fb_helper->dev) 51 + return; 52 + 53 + if (fbi) { 54 + if (fbi->fbdefio) 55 + fb_deferred_io_cleanup(fbi); 56 + if (drm_fbdev_use_shadow_fb(fb_helper)) 57 + shadow = fbi->screen_buffer; 58 + } 59 + 60 + drm_fb_helper_fini(fb_helper); 61 + 62 + if (shadow) 63 + vfree(shadow); 64 + else if (fb_helper->buffer) 65 + drm_client_buffer_vunmap(fb_helper->buffer); 66 + 67 + drm_client_framebuffer_delete(fb_helper->buffer); 68 + } 69 + 70 + static void drm_fbdev_release(struct drm_fb_helper *fb_helper) 71 + { 72 + drm_fbdev_cleanup(fb_helper); 73 + drm_client_release(&fb_helper->client); 74 + kfree(fb_helper); 75 + } 76 + 77 + /* 78 + * fb_ops.fb_destroy is called by the last put_fb_info() call at the end of 79 + * unregister_framebuffer() or fb_release(). 80 + */ 81 + static void drm_fbdev_fb_destroy(struct fb_info *info) 82 + { 83 + drm_fbdev_release(info->par); 84 + } 85 + 86 + static int drm_fbdev_fb_mmap(struct fb_info *info, struct vm_area_struct *vma) 87 + { 88 + struct drm_fb_helper *fb_helper = info->par; 89 + 90 + if (drm_fbdev_use_shadow_fb(fb_helper)) 91 + return fb_deferred_io_mmap(info, vma); 92 + else if (fb_helper->dev->driver->gem_prime_mmap) 93 + return fb_helper->dev->driver->gem_prime_mmap(fb_helper->buffer->gem, vma); 94 + else 95 + return -ENODEV; 96 + } 97 + 98 + static bool drm_fbdev_use_iomem(struct fb_info *info) 99 + { 100 + struct drm_fb_helper *fb_helper = info->par; 101 + struct drm_client_buffer *buffer = fb_helper->buffer; 102 + 103 + return !drm_fbdev_use_shadow_fb(fb_helper) && buffer->map.is_iomem; 104 + } 105 + 106 + static ssize_t drm_fbdev_fb_read(struct fb_info *info, char __user *buf, 107 + size_t count, loff_t *ppos) 108 + { 109 + ssize_t ret; 110 + 111 + if (drm_fbdev_use_iomem(info)) 112 + ret = drm_fb_helper_cfb_read(info, buf, count, ppos); 113 + else 114 + ret = drm_fb_helper_sys_read(info, buf, count, ppos); 115 + 116 + return ret; 117 + } 118 + 119 + static ssize_t drm_fbdev_fb_write(struct fb_info *info, const char __user *buf, 120 + size_t count, loff_t *ppos) 121 + { 122 + ssize_t ret; 123 + 124 + if (drm_fbdev_use_iomem(info)) 125 + ret = drm_fb_helper_cfb_write(info, buf, count, ppos); 126 + else 127 + ret = drm_fb_helper_sys_write(info, buf, count, ppos); 128 + 129 + return ret; 130 + } 131 + 132 + static void drm_fbdev_fb_fillrect(struct fb_info *info, 133 + const struct fb_fillrect *rect) 134 + { 135 + if (drm_fbdev_use_iomem(info)) 136 + drm_fb_helper_cfb_fillrect(info, rect); 137 + else 138 + drm_fb_helper_sys_fillrect(info, rect); 139 + } 140 + 141 + static void drm_fbdev_fb_copyarea(struct fb_info *info, 142 + const struct fb_copyarea *area) 143 + { 144 + if (drm_fbdev_use_iomem(info)) 145 + drm_fb_helper_cfb_copyarea(info, area); 146 + else 147 + drm_fb_helper_sys_copyarea(info, area); 148 + } 149 + 150 + static void drm_fbdev_fb_imageblit(struct fb_info *info, 151 + const struct fb_image *image) 152 + { 153 + if (drm_fbdev_use_iomem(info)) 154 + drm_fb_helper_cfb_imageblit(info, image); 155 + else 156 + drm_fb_helper_sys_imageblit(info, image); 157 + } 158 + 159 + static const struct fb_ops drm_fbdev_fb_ops = { 160 + .owner = THIS_MODULE, 161 + DRM_FB_HELPER_DEFAULT_OPS, 162 + .fb_open = drm_fbdev_fb_open, 163 + .fb_release = drm_fbdev_fb_release, 164 + .fb_destroy = drm_fbdev_fb_destroy, 165 + .fb_mmap = drm_fbdev_fb_mmap, 166 + .fb_read = drm_fbdev_fb_read, 167 + .fb_write = drm_fbdev_fb_write, 168 + .fb_fillrect = drm_fbdev_fb_fillrect, 169 + .fb_copyarea = drm_fbdev_fb_copyarea, 170 + .fb_imageblit = drm_fbdev_fb_imageblit, 171 + }; 172 + 173 + static struct fb_deferred_io drm_fbdev_defio = { 174 + .delay = HZ / 20, 175 + .deferred_io = drm_fb_helper_deferred_io, 176 + }; 177 + 178 + /* 179 + * This function uses the client API to create a framebuffer backed by a dumb buffer. 180 + */ 181 + static int drm_fbdev_fb_probe(struct drm_fb_helper *fb_helper, 182 + struct drm_fb_helper_surface_size *sizes) 183 + { 184 + struct drm_client_dev *client = &fb_helper->client; 185 + struct drm_device *dev = fb_helper->dev; 186 + struct drm_client_buffer *buffer; 187 + struct drm_framebuffer *fb; 188 + struct fb_info *fbi; 189 + u32 format; 190 + struct iosys_map map; 191 + int ret; 192 + 193 + drm_dbg_kms(dev, "surface width(%d), height(%d) and bpp(%d)\n", 194 + sizes->surface_width, sizes->surface_height, 195 + sizes->surface_bpp); 196 + 197 + format = drm_mode_legacy_fb_format(sizes->surface_bpp, sizes->surface_depth); 198 + buffer = drm_client_framebuffer_create(client, sizes->surface_width, 199 + sizes->surface_height, format); 200 + if (IS_ERR(buffer)) 201 + return PTR_ERR(buffer); 202 + 203 + fb_helper->buffer = buffer; 204 + fb_helper->fb = buffer->fb; 205 + fb = buffer->fb; 206 + 207 + fbi = drm_fb_helper_alloc_info(fb_helper); 208 + if (IS_ERR(fbi)) 209 + return PTR_ERR(fbi); 210 + 211 + fbi->fbops = &drm_fbdev_fb_ops; 212 + fbi->screen_size = sizes->surface_height * fb->pitches[0]; 213 + fbi->fix.smem_len = fbi->screen_size; 214 + fbi->flags = FBINFO_DEFAULT; 215 + 216 + drm_fb_helper_fill_info(fbi, fb_helper, sizes); 217 + 218 + if (drm_fbdev_use_shadow_fb(fb_helper)) { 219 + fbi->screen_buffer = vzalloc(fbi->screen_size); 220 + if (!fbi->screen_buffer) 221 + return -ENOMEM; 222 + fbi->flags |= FBINFO_VIRTFB | FBINFO_READS_FAST; 223 + 224 + fbi->fbdefio = &drm_fbdev_defio; 225 + fb_deferred_io_init(fbi); 226 + } else { 227 + /* buffer is mapped for HW framebuffer */ 228 + ret = drm_client_buffer_vmap(fb_helper->buffer, &map); 229 + if (ret) 230 + return ret; 231 + if (map.is_iomem) { 232 + fbi->screen_base = map.vaddr_iomem; 233 + } else { 234 + fbi->screen_buffer = map.vaddr; 235 + fbi->flags |= FBINFO_VIRTFB; 236 + } 237 + 238 + /* 239 + * Shamelessly leak the physical address to user-space. As 240 + * page_to_phys() is undefined for I/O memory, warn in this 241 + * case. 242 + */ 243 + #if IS_ENABLED(CONFIG_DRM_FBDEV_LEAK_PHYS_SMEM) 244 + if (fb_helper->hint_leak_smem_start && fbi->fix.smem_start == 0 && 245 + !drm_WARN_ON_ONCE(dev, map.is_iomem)) 246 + fbi->fix.smem_start = 247 + page_to_phys(virt_to_page(fbi->screen_buffer)); 248 + #endif 249 + } 250 + 251 + return 0; 252 + } 253 + 254 + static void drm_fbdev_damage_blit_real(struct drm_fb_helper *fb_helper, 255 + struct drm_clip_rect *clip, 256 + struct iosys_map *dst) 257 + { 258 + struct drm_framebuffer *fb = fb_helper->fb; 259 + size_t offset = clip->y1 * fb->pitches[0]; 260 + size_t len = clip->x2 - clip->x1; 261 + unsigned int y; 262 + void *src; 263 + 264 + switch (drm_format_info_bpp(fb->format, 0)) { 265 + case 1: 266 + offset += clip->x1 / 8; 267 + len = DIV_ROUND_UP(len + clip->x1 % 8, 8); 268 + break; 269 + case 2: 270 + offset += clip->x1 / 4; 271 + len = DIV_ROUND_UP(len + clip->x1 % 4, 4); 272 + break; 273 + case 4: 274 + offset += clip->x1 / 2; 275 + len = DIV_ROUND_UP(len + clip->x1 % 2, 2); 276 + break; 277 + default: 278 + offset += clip->x1 * fb->format->cpp[0]; 279 + len *= fb->format->cpp[0]; 280 + break; 281 + } 282 + 283 + src = fb_helper->info->screen_buffer + offset; 284 + iosys_map_incr(dst, offset); /* go to first pixel within clip rect */ 285 + 286 + for (y = clip->y1; y < clip->y2; y++) { 287 + iosys_map_memcpy_to(dst, 0, src, len); 288 + iosys_map_incr(dst, fb->pitches[0]); 289 + src += fb->pitches[0]; 290 + } 291 + } 292 + 293 + static int drm_fbdev_damage_blit(struct drm_fb_helper *fb_helper, 294 + struct drm_clip_rect *clip) 295 + { 296 + struct drm_client_buffer *buffer = fb_helper->buffer; 297 + struct iosys_map map, dst; 298 + int ret; 299 + 300 + /* 301 + * We have to pin the client buffer to its current location while 302 + * flushing the shadow buffer. In the general case, concurrent 303 + * modesetting operations could try to move the buffer and would 304 + * fail. The modeset has to be serialized by acquiring the reservation 305 + * object of the underlying BO here. 306 + * 307 + * For fbdev emulation, we only have to protect against fbdev modeset 308 + * operations. Nothing else will involve the client buffer's BO. So it 309 + * is sufficient to acquire struct drm_fb_helper.lock here. 310 + */ 311 + mutex_lock(&fb_helper->lock); 312 + 313 + ret = drm_client_buffer_vmap(buffer, &map); 314 + if (ret) 315 + goto out; 316 + 317 + dst = map; 318 + drm_fbdev_damage_blit_real(fb_helper, clip, &dst); 319 + 320 + drm_client_buffer_vunmap(buffer); 321 + 322 + out: 323 + mutex_unlock(&fb_helper->lock); 324 + 325 + return ret; 326 + } 327 + 328 + static int drm_fbdev_fb_dirty(struct drm_fb_helper *helper, struct drm_clip_rect *clip) 329 + { 330 + struct drm_device *dev = helper->dev; 331 + int ret; 332 + 333 + if (!drm_fbdev_use_shadow_fb(helper)) 334 + return 0; 335 + 336 + /* Call damage handlers only if necessary */ 337 + if (!(clip->x1 < clip->x2 && clip->y1 < clip->y2)) 338 + return 0; 339 + 340 + if (helper->buffer) { 341 + ret = drm_fbdev_damage_blit(helper, clip); 342 + if (drm_WARN_ONCE(dev, ret, "Damage blitter failed: ret=%d\n", ret)) 343 + return ret; 344 + } 345 + 346 + if (helper->fb->funcs->dirty) { 347 + ret = helper->fb->funcs->dirty(helper->fb, NULL, 0, 0, clip, 1); 348 + if (drm_WARN_ONCE(dev, ret, "Dirty helper failed: ret=%d\n", ret)) 349 + return ret; 350 + } 351 + 352 + return 0; 353 + } 354 + 355 + static const struct drm_fb_helper_funcs drm_fb_helper_generic_funcs = { 356 + .fb_probe = drm_fbdev_fb_probe, 357 + .fb_dirty = drm_fbdev_fb_dirty, 358 + }; 359 + 360 + static void drm_fbdev_client_unregister(struct drm_client_dev *client) 361 + { 362 + struct drm_fb_helper *fb_helper = drm_fb_helper_from_client(client); 363 + 364 + if (fb_helper->info) 365 + /* drm_fbdev_fb_destroy() takes care of cleanup */ 366 + drm_fb_helper_unregister_info(fb_helper); 367 + else 368 + drm_fbdev_release(fb_helper); 369 + } 370 + 371 + static int drm_fbdev_client_restore(struct drm_client_dev *client) 372 + { 373 + drm_fb_helper_lastclose(client->dev); 374 + 375 + return 0; 376 + } 377 + 378 + static int drm_fbdev_client_hotplug(struct drm_client_dev *client) 379 + { 380 + struct drm_fb_helper *fb_helper = drm_fb_helper_from_client(client); 381 + struct drm_device *dev = client->dev; 382 + int ret; 383 + 384 + /* Setup is not retried if it has failed */ 385 + if (!fb_helper->dev && fb_helper->funcs) 386 + return 0; 387 + 388 + if (dev->fb_helper) 389 + return drm_fb_helper_hotplug_event(dev->fb_helper); 390 + 391 + if (!dev->mode_config.num_connector) { 392 + drm_dbg_kms(dev, "No connectors found, will not create framebuffer!\n"); 393 + return 0; 394 + } 395 + 396 + drm_fb_helper_prepare(dev, fb_helper, &drm_fb_helper_generic_funcs); 397 + 398 + ret = drm_fb_helper_init(dev, fb_helper); 399 + if (ret) 400 + goto err; 401 + 402 + if (!drm_drv_uses_atomic_modeset(dev)) 403 + drm_helper_disable_unused_functions(dev); 404 + 405 + ret = drm_fb_helper_initial_config(fb_helper, fb_helper->preferred_bpp); 406 + if (ret) 407 + goto err_cleanup; 408 + 409 + return 0; 410 + 411 + err_cleanup: 412 + drm_fbdev_cleanup(fb_helper); 413 + err: 414 + fb_helper->dev = NULL; 415 + fb_helper->info = NULL; 416 + 417 + drm_err(dev, "fbdev: Failed to setup generic emulation (ret=%d)\n", ret); 418 + 419 + return ret; 420 + } 421 + 422 + static const struct drm_client_funcs drm_fbdev_client_funcs = { 423 + .owner = THIS_MODULE, 424 + .unregister = drm_fbdev_client_unregister, 425 + .restore = drm_fbdev_client_restore, 426 + .hotplug = drm_fbdev_client_hotplug, 427 + }; 428 + 429 + /** 430 + * drm_fbdev_generic_setup() - Setup generic fbdev emulation 431 + * @dev: DRM device 432 + * @preferred_bpp: Preferred bits per pixel for the device. 433 + * @dev->mode_config.preferred_depth is used if this is zero. 434 + * 435 + * This function sets up generic fbdev emulation for drivers that supports 436 + * dumb buffers with a virtual address and that can be mmap'ed. 437 + * drm_fbdev_generic_setup() shall be called after the DRM driver registered 438 + * the new DRM device with drm_dev_register(). 439 + * 440 + * Restore, hotplug events and teardown are all taken care of. Drivers that do 441 + * suspend/resume need to call drm_fb_helper_set_suspend_unlocked() themselves. 442 + * Simple drivers might use drm_mode_config_helper_suspend(). 443 + * 444 + * Drivers that set the dirty callback on their framebuffer will get a shadow 445 + * fbdev buffer that is blitted onto the real buffer. This is done in order to 446 + * make deferred I/O work with all kinds of buffers. A shadow buffer can be 447 + * requested explicitly by setting struct drm_mode_config.prefer_shadow or 448 + * struct drm_mode_config.prefer_shadow_fbdev to true beforehand. This is 449 + * required to use generic fbdev emulation with SHMEM helpers. 450 + * 451 + * This function is safe to call even when there are no connectors present. 452 + * Setup will be retried on the next hotplug event. 453 + * 454 + * The fbdev is destroyed by drm_dev_unregister(). 455 + */ 456 + void drm_fbdev_generic_setup(struct drm_device *dev, 457 + unsigned int preferred_bpp) 458 + { 459 + struct drm_fb_helper *fb_helper; 460 + int ret; 461 + 462 + drm_WARN(dev, !dev->registered, "Device has not been registered.\n"); 463 + drm_WARN(dev, dev->fb_helper, "fb_helper is already set!\n"); 464 + 465 + fb_helper = kzalloc(sizeof(*fb_helper), GFP_KERNEL); 466 + if (!fb_helper) 467 + return; 468 + 469 + ret = drm_client_init(dev, &fb_helper->client, "fbdev", &drm_fbdev_client_funcs); 470 + if (ret) { 471 + kfree(fb_helper); 472 + drm_err(dev, "Failed to register client: %d\n", ret); 473 + return; 474 + } 475 + 476 + /* 477 + * FIXME: This mixes up depth with bpp, which results in a glorious 478 + * mess, resulting in some drivers picking wrong fbdev defaults and 479 + * others wrong preferred_depth defaults. 480 + */ 481 + if (!preferred_bpp) 482 + preferred_bpp = dev->mode_config.preferred_depth; 483 + if (!preferred_bpp) 484 + preferred_bpp = 32; 485 + fb_helper->preferred_bpp = preferred_bpp; 486 + 487 + ret = drm_fbdev_client_hotplug(&fb_helper->client); 488 + if (ret) 489 + drm_dbg_kms(dev, "client hotplug ret=%d\n", ret); 490 + 491 + drm_client_register(&fb_helper->client); 492 + } 493 + EXPORT_SYMBOL(drm_fbdev_generic_setup);
+1 -1
drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c
··· 20 20 21 21 #include <drm/drm_atomic_helper.h> 22 22 #include <drm/drm_drv.h> 23 - #include <drm/drm_fb_helper.h> 23 + #include <drm/drm_fbdev_generic.h> 24 24 #include <drm/drm_gem_dma_helper.h> 25 25 #include <drm/drm_modeset_helper.h> 26 26 #include <drm/drm_module.h>
+1 -1
drivers/gpu/drm/gud/gud_drv.c
··· 18 18 #include <drm/drm_damage_helper.h> 19 19 #include <drm/drm_debugfs.h> 20 20 #include <drm/drm_drv.h> 21 - #include <drm/drm_fb_helper.h> 21 + #include <drm/drm_fbdev_generic.h> 22 22 #include <drm/drm_fourcc.h> 23 23 #include <drm/drm_gem_atomic_helper.h> 24 24 #include <drm/drm_gem_framebuffer_helper.h>
+1
drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c
··· 17 17 #include <drm/drm_aperture.h> 18 18 #include <drm/drm_atomic_helper.h> 19 19 #include <drm/drm_drv.h> 20 + #include <drm/drm_fbdev_generic.h> 20 21 #include <drm/drm_gem_framebuffer_helper.h> 21 22 #include <drm/drm_gem_vram_helper.h> 22 23 #include <drm/drm_managed.h>
+1 -1
drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.c
··· 19 19 20 20 #include <drm/drm_atomic_helper.h> 21 21 #include <drm/drm_drv.h> 22 - #include <drm/drm_fb_helper.h> 22 + #include <drm/drm_fbdev_generic.h> 23 23 #include <drm/drm_gem_dma_helper.h> 24 24 #include <drm/drm_gem_framebuffer_helper.h> 25 25 #include <drm/drm_module.h>
+1 -1
drivers/gpu/drm/hyperv/hyperv_drm_drv.c
··· 11 11 #include <drm/drm_aperture.h> 12 12 #include <drm/drm_atomic_helper.h> 13 13 #include <drm/drm_drv.h> 14 - #include <drm/drm_fb_helper.h> 14 + #include <drm/drm_fbdev_generic.h> 15 15 #include <drm/drm_gem_shmem_helper.h> 16 16 #include <drm/drm_simple_kms_helper.h> 17 17
+1 -1
drivers/gpu/drm/imx/dcss/dcss-kms.c
··· 7 7 #include <drm/drm_atomic_helper.h> 8 8 #include <drm/drm_bridge_connector.h> 9 9 #include <drm/drm_drv.h> 10 - #include <drm/drm_fb_helper.h> 10 + #include <drm/drm_fbdev_generic.h> 11 11 #include <drm/drm_gem_dma_helper.h> 12 12 #include <drm/drm_gem_framebuffer_helper.h> 13 13 #include <drm/drm_of.h>
+1 -1
drivers/gpu/drm/imx/imx-drm-core.c
··· 16 16 #include <drm/drm_atomic.h> 17 17 #include <drm/drm_atomic_helper.h> 18 18 #include <drm/drm_drv.h> 19 - #include <drm/drm_fb_helper.h> 19 + #include <drm/drm_fbdev_generic.h> 20 20 #include <drm/drm_gem_dma_helper.h> 21 21 #include <drm/drm_gem_framebuffer_helper.h> 22 22 #include <drm/drm_managed.h>
+1 -1
drivers/gpu/drm/ingenic/ingenic-drm-drv.c
··· 32 32 #include <drm/drm_encoder.h> 33 33 #include <drm/drm_gem_dma_helper.h> 34 34 #include <drm/drm_fb_dma_helper.h> 35 - #include <drm/drm_fb_helper.h> 35 + #include <drm/drm_fbdev_generic.h> 36 36 #include <drm/drm_fourcc.h> 37 37 #include <drm/drm_framebuffer.h> 38 38 #include <drm/drm_gem_atomic_helper.h>
+1 -1
drivers/gpu/drm/kmb/kmb_drv.c
··· 15 15 16 16 #include <drm/drm_atomic_helper.h> 17 17 #include <drm/drm_drv.h> 18 - #include <drm/drm_fb_helper.h> 18 + #include <drm/drm_fbdev_generic.h> 19 19 #include <drm/drm_gem_dma_helper.h> 20 20 #include <drm/drm_gem_framebuffer_helper.h> 21 21 #include <drm/drm_module.h>
+1 -1
drivers/gpu/drm/logicvc/logicvc_drm.c
··· 17 17 18 18 #include <drm/drm_atomic_helper.h> 19 19 #include <drm/drm_drv.h> 20 - #include <drm/drm_fb_helper.h> 20 + #include <drm/drm_fbdev_generic.h> 21 21 #include <drm/drm_gem_dma_helper.h> 22 22 #include <drm/drm_print.h> 23 23
+1 -1
drivers/gpu/drm/mcde/mcde_drv.c
··· 69 69 #include <drm/drm_bridge.h> 70 70 #include <drm/drm_drv.h> 71 71 #include <drm/drm_fb_dma_helper.h> 72 - #include <drm/drm_fb_helper.h> 72 + #include <drm/drm_fbdev_generic.h> 73 73 #include <drm/drm_gem.h> 74 74 #include <drm/drm_gem_dma_helper.h> 75 75 #include <drm/drm_gem_framebuffer_helper.h>
+1 -1
drivers/gpu/drm/mediatek/mtk_drm_drv.c
··· 17 17 #include <drm/drm_atomic.h> 18 18 #include <drm/drm_atomic_helper.h> 19 19 #include <drm/drm_drv.h> 20 - #include <drm/drm_fb_helper.h> 20 + #include <drm/drm_fbdev_generic.h> 21 21 #include <drm/drm_fourcc.h> 22 22 #include <drm/drm_gem.h> 23 23 #include <drm/drm_gem_dma_helper.h>
+1 -1
drivers/gpu/drm/meson/meson_drv.c
··· 18 18 #include <drm/drm_aperture.h> 19 19 #include <drm/drm_atomic_helper.h> 20 20 #include <drm/drm_drv.h> 21 - #include <drm/drm_fb_helper.h> 21 + #include <drm/drm_fbdev_generic.h> 22 22 #include <drm/drm_gem_dma_helper.h> 23 23 #include <drm/drm_gem_framebuffer_helper.h> 24 24 #include <drm/drm_modeset_helper_vtables.h>
+1
drivers/gpu/drm/mgag200/mgag200_drv.c
··· 11 11 12 12 #include <drm/drm_aperture.h> 13 13 #include <drm/drm_drv.h> 14 + #include <drm/drm_fbdev_generic.h> 14 15 #include <drm/drm_file.h> 15 16 #include <drm/drm_ioctl.h> 16 17 #include <drm/drm_managed.h>
+1 -1
drivers/gpu/drm/mxsfb/lcdif_drv.c
··· 16 16 #include <drm/drm_atomic_helper.h> 17 17 #include <drm/drm_bridge.h> 18 18 #include <drm/drm_drv.h> 19 - #include <drm/drm_fb_helper.h> 19 + #include <drm/drm_fbdev_generic.h> 20 20 #include <drm/drm_gem_dma_helper.h> 21 21 #include <drm/drm_gem_framebuffer_helper.h> 22 22 #include <drm/drm_mode_config.h>
+1 -1
drivers/gpu/drm/mxsfb/mxsfb_drv.c
··· 20 20 #include <drm/drm_bridge.h> 21 21 #include <drm/drm_connector.h> 22 22 #include <drm/drm_drv.h> 23 - #include <drm/drm_fb_helper.h> 23 + #include <drm/drm_fbdev_generic.h> 24 24 #include <drm/drm_fourcc.h> 25 25 #include <drm/drm_gem_dma_helper.h> 26 26 #include <drm/drm_gem_framebuffer_helper.h>
+1 -1
drivers/gpu/drm/panel/panel-ilitek-ili9341.c
··· 31 31 32 32 #include <drm/drm_atomic_helper.h> 33 33 #include <drm/drm_drv.h> 34 - #include <drm/drm_fb_helper.h> 34 + #include <drm/drm_fbdev_generic.h> 35 35 #include <drm/drm_gem_atomic_helper.h> 36 36 #include <drm/drm_gem_dma_helper.h> 37 37 #include <drm/drm_gem_framebuffer_helper.h>
+1 -1
drivers/gpu/drm/pl111/pl111_drv.c
··· 48 48 #include <drm/drm_atomic_helper.h> 49 49 #include <drm/drm_bridge.h> 50 50 #include <drm/drm_drv.h> 51 - #include <drm/drm_fb_helper.h> 51 + #include <drm/drm_fbdev_generic.h> 52 52 #include <drm/drm_fourcc.h> 53 53 #include <drm/drm_gem_dma_helper.h> 54 54 #include <drm/drm_gem_framebuffer_helper.h>
+1
drivers/gpu/drm/qxl/qxl_drv.c
··· 37 37 #include <drm/drm_aperture.h> 38 38 #include <drm/drm_atomic_helper.h> 39 39 #include <drm/drm_drv.h> 40 + #include <drm/drm_fbdev_generic.h> 40 41 #include <drm/drm_file.h> 41 42 #include <drm/drm_gem_ttm_helper.h> 42 43 #include <drm/drm_module.h>
+1 -1
drivers/gpu/drm/rcar-du/rcar_du_drv.c
··· 20 20 21 21 #include <drm/drm_atomic_helper.h> 22 22 #include <drm/drm_drv.h> 23 - #include <drm/drm_fb_helper.h> 23 + #include <drm/drm_fbdev_generic.h> 24 24 #include <drm/drm_gem_dma_helper.h> 25 25 #include <drm/drm_managed.h> 26 26 #include <drm/drm_probe_helper.h>
+1 -1
drivers/gpu/drm/rockchip/rockchip_drm_drv.c
··· 17 17 18 18 #include <drm/drm_aperture.h> 19 19 #include <drm/drm_drv.h> 20 - #include <drm/drm_fb_helper.h> 20 + #include <drm/drm_fbdev_generic.h> 21 21 #include <drm/drm_gem_dma_helper.h> 22 22 #include <drm/drm_of.h> 23 23 #include <drm/drm_probe_helper.h>
+1 -1
drivers/gpu/drm/solomon/ssd130x.c
··· 23 23 #include <drm/drm_crtc_helper.h> 24 24 #include <drm/drm_damage_helper.h> 25 25 #include <drm/drm_edid.h> 26 - #include <drm/drm_fb_helper.h> 26 + #include <drm/drm_fbdev_generic.h> 27 27 #include <drm/drm_format_helper.h> 28 28 #include <drm/drm_framebuffer.h> 29 29 #include <drm/drm_gem_atomic_helper.h>
+1 -1
drivers/gpu/drm/sti/sti_drv.c
··· 14 14 #include <drm/drm_atomic_helper.h> 15 15 #include <drm/drm_debugfs.h> 16 16 #include <drm/drm_drv.h> 17 - #include <drm/drm_fb_helper.h> 17 + #include <drm/drm_fbdev_generic.h> 18 18 #include <drm/drm_gem_dma_helper.h> 19 19 #include <drm/drm_gem_framebuffer_helper.h> 20 20 #include <drm/drm_of.h>
+1 -1
drivers/gpu/drm/stm/drv.c
··· 18 18 #include <drm/drm_atomic.h> 19 19 #include <drm/drm_atomic_helper.h> 20 20 #include <drm/drm_drv.h> 21 - #include <drm/drm_fb_helper.h> 21 + #include <drm/drm_fbdev_generic.h> 22 22 #include <drm/drm_gem_dma_helper.h> 23 23 #include <drm/drm_gem_framebuffer_helper.h> 24 24 #include <drm/drm_module.h>
+1 -1
drivers/gpu/drm/sun4i/sun4i_drv.c
··· 17 17 #include <drm/drm_aperture.h> 18 18 #include <drm/drm_atomic_helper.h> 19 19 #include <drm/drm_drv.h> 20 - #include <drm/drm_fb_helper.h> 20 + #include <drm/drm_fbdev_generic.h> 21 21 #include <drm/drm_gem_dma_helper.h> 22 22 #include <drm/drm_module.h> 23 23 #include <drm/drm_of.h>
+1 -1
drivers/gpu/drm/tidss/tidss_drv.c
··· 14 14 #include <drm/drm_crtc.h> 15 15 #include <drm/drm_crtc_helper.h> 16 16 #include <drm/drm_drv.h> 17 - #include <drm/drm_fb_helper.h> 17 + #include <drm/drm_fbdev_generic.h> 18 18 #include <drm/drm_gem_dma_helper.h> 19 19 #include <drm/drm_managed.h> 20 20 #include <drm/drm_module.h>
+1 -1
drivers/gpu/drm/tilcdc/tilcdc_drv.c
··· 16 16 #include <drm/drm_atomic_helper.h> 17 17 #include <drm/drm_debugfs.h> 18 18 #include <drm/drm_drv.h> 19 - #include <drm/drm_fb_helper.h> 19 + #include <drm/drm_fbdev_generic.h> 20 20 #include <drm/drm_fourcc.h> 21 21 #include <drm/drm_gem_dma_helper.h> 22 22 #include <drm/drm_gem_framebuffer_helper.h>
+1 -1
drivers/gpu/drm/tiny/arcpgu.c
··· 12 12 #include <drm/drm_drv.h> 13 13 #include <drm/drm_edid.h> 14 14 #include <drm/drm_fb_dma_helper.h> 15 - #include <drm/drm_fb_helper.h> 15 + #include <drm/drm_fbdev_generic.h> 16 16 #include <drm/drm_fourcc.h> 17 17 #include <drm/drm_framebuffer.h> 18 18 #include <drm/drm_gem_dma_helper.h>
+1 -1
drivers/gpu/drm/tiny/bochs.c
··· 7 7 #include <drm/drm_atomic_helper.h> 8 8 #include <drm/drm_drv.h> 9 9 #include <drm/drm_edid.h> 10 - #include <drm/drm_fb_helper.h> 10 + #include <drm/drm_fbdev_generic.h> 11 11 #include <drm/drm_fourcc.h> 12 12 #include <drm/drm_framebuffer.h> 13 13 #include <drm/drm_gem_framebuffer_helper.h>
+1 -1
drivers/gpu/drm/tiny/cirrus.c
··· 30 30 #include <drm/drm_damage_helper.h> 31 31 #include <drm/drm_drv.h> 32 32 #include <drm/drm_edid.h> 33 - #include <drm/drm_fb_helper.h> 33 + #include <drm/drm_fbdev_generic.h> 34 34 #include <drm/drm_file.h> 35 35 #include <drm/drm_format_helper.h> 36 36 #include <drm/drm_fourcc.h>
+1 -1
drivers/gpu/drm/tiny/gm12u320.c
··· 12 12 #include <drm/drm_damage_helper.h> 13 13 #include <drm/drm_drv.h> 14 14 #include <drm/drm_edid.h> 15 - #include <drm/drm_fb_helper.h> 15 + #include <drm/drm_fbdev_generic.h> 16 16 #include <drm/drm_file.h> 17 17 #include <drm/drm_format_helper.h> 18 18 #include <drm/drm_fourcc.h>
+1 -1
drivers/gpu/drm/tiny/hx8357d.c
··· 18 18 19 19 #include <drm/drm_atomic_helper.h> 20 20 #include <drm/drm_drv.h> 21 - #include <drm/drm_fb_helper.h> 21 + #include <drm/drm_fbdev_generic.h> 22 22 #include <drm/drm_gem_atomic_helper.h> 23 23 #include <drm/drm_gem_dma_helper.h> 24 24 #include <drm/drm_managed.h>
+1 -1
drivers/gpu/drm/tiny/ili9163.c
··· 9 9 10 10 #include <drm/drm_atomic_helper.h> 11 11 #include <drm/drm_drv.h> 12 - #include <drm/drm_fb_helper.h> 12 + #include <drm/drm_fbdev_generic.h> 13 13 #include <drm/drm_gem_atomic_helper.h> 14 14 #include <drm/drm_gem_dma_helper.h> 15 15 #include <drm/drm_mipi_dbi.h>
+1 -1
drivers/gpu/drm/tiny/ili9225.c
··· 20 20 #include <drm/drm_damage_helper.h> 21 21 #include <drm/drm_drv.h> 22 22 #include <drm/drm_fb_dma_helper.h> 23 - #include <drm/drm_fb_helper.h> 23 + #include <drm/drm_fbdev_generic.h> 24 24 #include <drm/drm_fourcc.h> 25 25 #include <drm/drm_framebuffer.h> 26 26 #include <drm/drm_gem_atomic_helper.h>
+1 -1
drivers/gpu/drm/tiny/ili9341.c
··· 17 17 18 18 #include <drm/drm_atomic_helper.h> 19 19 #include <drm/drm_drv.h> 20 - #include <drm/drm_fb_helper.h> 20 + #include <drm/drm_fbdev_generic.h> 21 21 #include <drm/drm_gem_atomic_helper.h> 22 22 #include <drm/drm_gem_dma_helper.h> 23 23 #include <drm/drm_managed.h>
+1 -1
drivers/gpu/drm/tiny/ili9486.c
··· 16 16 17 17 #include <drm/drm_atomic_helper.h> 18 18 #include <drm/drm_drv.h> 19 - #include <drm/drm_fb_helper.h> 19 + #include <drm/drm_fbdev_generic.h> 20 20 #include <drm/drm_gem_atomic_helper.h> 21 21 #include <drm/drm_gem_dma_helper.h> 22 22 #include <drm/drm_managed.h>
+1 -1
drivers/gpu/drm/tiny/mi0283qt.c
··· 15 15 16 16 #include <drm/drm_atomic_helper.h> 17 17 #include <drm/drm_drv.h> 18 - #include <drm/drm_fb_helper.h> 18 + #include <drm/drm_fbdev_generic.h> 19 19 #include <drm/drm_gem_atomic_helper.h> 20 20 #include <drm/drm_gem_dma_helper.h> 21 21 #include <drm/drm_managed.h>
+1 -1
drivers/gpu/drm/tiny/ofdrm.c
··· 11 11 #include <drm/drm_damage_helper.h> 12 12 #include <drm/drm_device.h> 13 13 #include <drm/drm_drv.h> 14 - #include <drm/drm_fb_helper.h> 14 + #include <drm/drm_fbdev_generic.h> 15 15 #include <drm/drm_format_helper.h> 16 16 #include <drm/drm_framebuffer.h> 17 17 #include <drm/drm_gem_atomic_helper.h>
+1 -1
drivers/gpu/drm/tiny/panel-mipi-dbi.c
··· 16 16 17 17 #include <drm/drm_atomic_helper.h> 18 18 #include <drm/drm_drv.h> 19 - #include <drm/drm_fb_helper.h> 19 + #include <drm/drm_fbdev_generic.h> 20 20 #include <drm/drm_gem_atomic_helper.h> 21 21 #include <drm/drm_gem_dma_helper.h> 22 22 #include <drm/drm_managed.h>
+1 -1
drivers/gpu/drm/tiny/repaper.c
··· 26 26 #include <drm/drm_damage_helper.h> 27 27 #include <drm/drm_drv.h> 28 28 #include <drm/drm_fb_dma_helper.h> 29 - #include <drm/drm_fb_helper.h> 29 + #include <drm/drm_fbdev_generic.h> 30 30 #include <drm/drm_format_helper.h> 31 31 #include <drm/drm_framebuffer.h> 32 32 #include <drm/drm_gem_atomic_helper.h>
+1 -1
drivers/gpu/drm/tiny/simpledrm.c
··· 15 15 #include <drm/drm_damage_helper.h> 16 16 #include <drm/drm_device.h> 17 17 #include <drm/drm_drv.h> 18 - #include <drm/drm_fb_helper.h> 18 + #include <drm/drm_fbdev_generic.h> 19 19 #include <drm/drm_format_helper.h> 20 20 #include <drm/drm_gem_atomic_helper.h> 21 21 #include <drm/drm_gem_framebuffer_helper.h>
+1 -1
drivers/gpu/drm/tiny/st7586.c
··· 16 16 #include <drm/drm_damage_helper.h> 17 17 #include <drm/drm_drv.h> 18 18 #include <drm/drm_fb_dma_helper.h> 19 - #include <drm/drm_fb_helper.h> 19 + #include <drm/drm_fbdev_generic.h> 20 20 #include <drm/drm_format_helper.h> 21 21 #include <drm/drm_framebuffer.h> 22 22 #include <drm/drm_gem_atomic_helper.h>
+1 -1
drivers/gpu/drm/tiny/st7735r.c
··· 18 18 19 19 #include <drm/drm_atomic_helper.h> 20 20 #include <drm/drm_drv.h> 21 - #include <drm/drm_fb_helper.h> 21 + #include <drm/drm_fbdev_generic.h> 22 22 #include <drm/drm_gem_atomic_helper.h> 23 23 #include <drm/drm_gem_dma_helper.h> 24 24 #include <drm/drm_managed.h>
+1 -1
drivers/gpu/drm/tve200/tve200_drv.c
··· 40 40 #include <drm/drm_atomic_helper.h> 41 41 #include <drm/drm_bridge.h> 42 42 #include <drm/drm_drv.h> 43 - #include <drm/drm_fb_helper.h> 43 + #include <drm/drm_fbdev_generic.h> 44 44 #include <drm/drm_gem_dma_helper.h> 45 45 #include <drm/drm_gem_framebuffer_helper.h> 46 46 #include <drm/drm_module.h>
+1 -1
drivers/gpu/drm/udl/udl_drv.c
··· 7 7 8 8 #include <drm/drm_crtc_helper.h> 9 9 #include <drm/drm_drv.h> 10 - #include <drm/drm_fb_helper.h> 10 + #include <drm/drm_fbdev_generic.h> 11 11 #include <drm/drm_file.h> 12 12 #include <drm/drm_gem_shmem_helper.h> 13 13 #include <drm/drm_managed.h>
+1 -1
drivers/gpu/drm/vboxvideo/vbox_drv.c
··· 14 14 #include <drm/drm_aperture.h> 15 15 #include <drm/drm_crtc_helper.h> 16 16 #include <drm/drm_drv.h> 17 - #include <drm/drm_fb_helper.h> 17 + #include <drm/drm_fbdev_generic.h> 18 18 #include <drm/drm_file.h> 19 19 #include <drm/drm_ioctl.h> 20 20 #include <drm/drm_managed.h>
+1 -1
drivers/gpu/drm/vc4/vc4_drv.c
··· 33 33 #include <drm/drm_aperture.h> 34 34 #include <drm/drm_atomic_helper.h> 35 35 #include <drm/drm_drv.h> 36 - #include <drm/drm_fb_helper.h> 36 + #include <drm/drm_fbdev_generic.h> 37 37 #include <drm/drm_vblank.h> 38 38 39 39 #include <soc/bcm2835/raspberrypi-firmware.h>
+1
drivers/gpu/drm/virtio/virtgpu_drv.c
··· 35 35 #include <drm/drm_aperture.h> 36 36 #include <drm/drm_atomic_helper.h> 37 37 #include <drm/drm_drv.h> 38 + #include <drm/drm_fbdev_generic.h> 38 39 #include <drm/drm_file.h> 39 40 40 41 #include "virtgpu_drv.h"
+1 -1
drivers/gpu/drm/vkms/vkms_drv.c
··· 17 17 #include <drm/drm_atomic.h> 18 18 #include <drm/drm_atomic_helper.h> 19 19 #include <drm/drm_drv.h> 20 - #include <drm/drm_fb_helper.h> 20 + #include <drm/drm_fbdev_generic.h> 21 21 #include <drm/drm_file.h> 22 22 #include <drm/drm_gem_framebuffer_helper.h> 23 23 #include <drm/drm_ioctl.h>
+1 -1
drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
··· 35 35 36 36 #include <drm/drm_aperture.h> 37 37 #include <drm/drm_drv.h> 38 - #include <drm/drm_fb_helper.h> 38 + #include <drm/drm_fbdev_generic.h> 39 39 #include <drm/drm_gem_ttm_helper.h> 40 40 #include <drm/drm_ioctl.h> 41 41 #include <drm/drm_module.h>
+1 -1
drivers/gpu/drm/xlnx/zynqmp_kms.c
··· 19 19 #include <drm/drm_device.h> 20 20 #include <drm/drm_drv.h> 21 21 #include <drm/drm_encoder.h> 22 - #include <drm/drm_fb_helper.h> 22 + #include <drm/drm_fbdev_generic.h> 23 23 #include <drm/drm_fourcc.h> 24 24 #include <drm/drm_framebuffer.h> 25 25 #include <drm/drm_gem_dma_helper.h>
-9
include/drm/drm_fb_helper.h
··· 287 287 288 288 void drm_fb_helper_lastclose(struct drm_device *dev); 289 289 void drm_fb_helper_output_poll_changed(struct drm_device *dev); 290 - 291 - void drm_fbdev_generic_setup(struct drm_device *dev, 292 - unsigned int preferred_bpp); 293 290 #else 294 291 static inline void drm_fb_helper_prepare(struct drm_device *dev, 295 292 struct drm_fb_helper *helper, ··· 471 474 static inline void drm_fb_helper_output_poll_changed(struct drm_device *dev) 472 475 { 473 476 } 474 - 475 - static inline void 476 - drm_fbdev_generic_setup(struct drm_device *dev, unsigned int preferred_bpp) 477 - { 478 - } 479 - 480 477 #endif 481 478 482 479 #endif
+15
include/drm/drm_fbdev_generic.h
··· 1 + /* SPDX-License-Identifier: MIT */ 2 + 3 + #ifndef DRM_FBDEV_GENERIC_H 4 + #define DRM_FBDEV_GENERIC_H 5 + 6 + struct drm_device; 7 + 8 + #ifdef CONFIG_DRM_FBDEV_EMULATION 9 + void drm_fbdev_generic_setup(struct drm_device *dev, unsigned int preferred_bpp); 10 + #else 11 + static inline void drm_fbdev_generic_setup(struct drm_device *dev, unsigned int preferred_bpp) 12 + { } 13 + #endif 14 + 15 + #endif