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

Configure Feed

Select the types of activity you want to include in your feed.

drm/fbdev-ttm: Support struct drm_driver.fbdev_probe

Rework fbdev probing to support fbdev_probe in struct drm_driver
and reimplement the old fb_probe callback on top of it. Provide an
initializer macro for struct drm_driver that sets the callback
according to the kernel configuration.

This change allows the common fbdev client to run on top of TTM-
based DRM drivers.

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

+90 -65
+77 -65
drivers/gpu/drm/drm_fbdev_ttm.c
··· 71 71 static int drm_fbdev_ttm_helper_fb_probe(struct drm_fb_helper *fb_helper, 72 72 struct drm_fb_helper_surface_size *sizes) 73 73 { 74 - struct drm_client_dev *client = &fb_helper->client; 75 - struct drm_device *dev = fb_helper->dev; 76 - struct drm_client_buffer *buffer; 77 - struct fb_info *info; 78 - size_t screen_size; 79 - void *screen_buffer; 80 - u32 format; 81 - int ret; 82 - 83 - drm_dbg_kms(dev, "surface width(%d), height(%d) and bpp(%d)\n", 84 - sizes->surface_width, sizes->surface_height, 85 - sizes->surface_bpp); 86 - 87 - format = drm_driver_legacy_fb_format(dev, sizes->surface_bpp, 88 - sizes->surface_depth); 89 - buffer = drm_client_framebuffer_create(client, sizes->surface_width, 90 - sizes->surface_height, format); 91 - if (IS_ERR(buffer)) 92 - return PTR_ERR(buffer); 93 - 94 - fb_helper->buffer = buffer; 95 - fb_helper->fb = buffer->fb; 96 - 97 - screen_size = buffer->gem->size; 98 - screen_buffer = vzalloc(screen_size); 99 - if (!screen_buffer) { 100 - ret = -ENOMEM; 101 - goto err_drm_client_framebuffer_delete; 102 - } 103 - 104 - info = drm_fb_helper_alloc_info(fb_helper); 105 - if (IS_ERR(info)) { 106 - ret = PTR_ERR(info); 107 - goto err_vfree; 108 - } 109 - 110 - drm_fb_helper_fill_info(info, fb_helper, sizes); 111 - 112 - info->fbops = &drm_fbdev_ttm_fb_ops; 113 - 114 - /* screen */ 115 - info->flags |= FBINFO_VIRTFB | FBINFO_READS_FAST; 116 - info->screen_buffer = screen_buffer; 117 - info->fix.smem_len = screen_size; 118 - 119 - /* deferred I/O */ 120 - fb_helper->fbdefio.delay = HZ / 20; 121 - fb_helper->fbdefio.deferred_io = drm_fb_helper_deferred_io; 122 - 123 - info->fbdefio = &fb_helper->fbdefio; 124 - ret = fb_deferred_io_init(info); 125 - if (ret) 126 - goto err_drm_fb_helper_release_info; 127 - 128 - return 0; 129 - 130 - err_drm_fb_helper_release_info: 131 - drm_fb_helper_release_info(fb_helper); 132 - err_vfree: 133 - vfree(screen_buffer); 134 - err_drm_client_framebuffer_delete: 135 - fb_helper->fb = NULL; 136 - fb_helper->buffer = NULL; 137 - drm_client_framebuffer_delete(buffer); 138 - return ret; 74 + return drm_fbdev_ttm_driver_fbdev_probe(fb_helper, sizes); 139 75 } 140 76 141 77 static void drm_fbdev_ttm_damage_blit_real(struct drm_fb_helper *fb_helper, ··· 175 239 .fb_probe = drm_fbdev_ttm_helper_fb_probe, 176 240 .fb_dirty = drm_fbdev_ttm_helper_fb_dirty, 177 241 }; 242 + 243 + /* 244 + * struct drm_driver 245 + */ 246 + 247 + int drm_fbdev_ttm_driver_fbdev_probe(struct drm_fb_helper *fb_helper, 248 + struct drm_fb_helper_surface_size *sizes) 249 + { 250 + struct drm_client_dev *client = &fb_helper->client; 251 + struct drm_device *dev = fb_helper->dev; 252 + struct drm_client_buffer *buffer; 253 + struct fb_info *info; 254 + size_t screen_size; 255 + void *screen_buffer; 256 + u32 format; 257 + int ret; 258 + 259 + drm_dbg_kms(dev, "surface width(%d), height(%d) and bpp(%d)\n", 260 + sizes->surface_width, sizes->surface_height, 261 + sizes->surface_bpp); 262 + 263 + format = drm_driver_legacy_fb_format(dev, sizes->surface_bpp, 264 + sizes->surface_depth); 265 + buffer = drm_client_framebuffer_create(client, sizes->surface_width, 266 + sizes->surface_height, format); 267 + if (IS_ERR(buffer)) 268 + return PTR_ERR(buffer); 269 + 270 + fb_helper->funcs = &drm_fbdev_ttm_helper_funcs; 271 + fb_helper->buffer = buffer; 272 + fb_helper->fb = buffer->fb; 273 + 274 + screen_size = buffer->gem->size; 275 + screen_buffer = vzalloc(screen_size); 276 + if (!screen_buffer) { 277 + ret = -ENOMEM; 278 + goto err_drm_client_framebuffer_delete; 279 + } 280 + 281 + info = drm_fb_helper_alloc_info(fb_helper); 282 + if (IS_ERR(info)) { 283 + ret = PTR_ERR(info); 284 + goto err_vfree; 285 + } 286 + 287 + drm_fb_helper_fill_info(info, fb_helper, sizes); 288 + 289 + info->fbops = &drm_fbdev_ttm_fb_ops; 290 + 291 + /* screen */ 292 + info->flags |= FBINFO_VIRTFB | FBINFO_READS_FAST; 293 + info->screen_buffer = screen_buffer; 294 + info->fix.smem_len = screen_size; 295 + 296 + /* deferred I/O */ 297 + fb_helper->fbdefio.delay = HZ / 20; 298 + fb_helper->fbdefio.deferred_io = drm_fb_helper_deferred_io; 299 + 300 + info->fbdefio = &fb_helper->fbdefio; 301 + ret = fb_deferred_io_init(info); 302 + if (ret) 303 + goto err_drm_fb_helper_release_info; 304 + 305 + return 0; 306 + 307 + err_drm_fb_helper_release_info: 308 + drm_fb_helper_release_info(fb_helper); 309 + err_vfree: 310 + vfree(screen_buffer); 311 + err_drm_client_framebuffer_delete: 312 + fb_helper->fb = NULL; 313 + fb_helper->buffer = NULL; 314 + drm_client_framebuffer_delete(buffer); 315 + return ret; 316 + } 317 + EXPORT_SYMBOL(drm_fbdev_ttm_driver_fbdev_probe); 178 318 179 319 static void drm_fbdev_ttm_client_unregister(struct drm_client_dev *client) 180 320 {
+13
include/drm/drm_fbdev_ttm.h
··· 3 3 #ifndef DRM_FBDEV_TTM_H 4 4 #define DRM_FBDEV_TTM_H 5 5 6 + #include <linux/stddef.h> 7 + 6 8 struct drm_device; 9 + struct drm_fb_helper; 10 + struct drm_fb_helper_surface_size; 7 11 8 12 #ifdef CONFIG_DRM_FBDEV_EMULATION 13 + int drm_fbdev_ttm_driver_fbdev_probe(struct drm_fb_helper *fb_helper, 14 + struct drm_fb_helper_surface_size *sizes); 15 + 16 + #define DRM_FBDEV_TTM_DRIVER_OPS \ 17 + .fbdev_probe = drm_fbdev_ttm_driver_fbdev_probe 18 + 9 19 void drm_fbdev_ttm_setup(struct drm_device *dev, unsigned int preferred_bpp); 10 20 #else 21 + #define DRM_FBDEV_TTM_DRIVER_OPS \ 22 + .fbdev_probe = NULL 23 + 11 24 static inline void drm_fbdev_ttm_setup(struct drm_device *dev, unsigned int preferred_bpp) 12 25 { } 13 26 #endif