2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; either version 2 of the License, or
5 * (at your option) any later version.
9 #include <drm/drm_gem_framebuffer_helper.h>
11 /* ---------------------------------------------------------------------- */
13 static int bochsfb_mmap(struct fb_info *info,
14 struct vm_area_struct *vma)
16 struct drm_fb_helper *fb_helper = info->par;
17 struct bochs_bo *bo = gem_to_bochs_bo(fb_helper->fb->obj[0]);
19 return ttm_fbdev_mmap(vma, &bo->bo);
22 static struct fb_ops bochsfb_ops = {
24 DRM_FB_HELPER_DEFAULT_OPS,
25 .fb_fillrect = drm_fb_helper_cfb_fillrect,
26 .fb_copyarea = drm_fb_helper_cfb_copyarea,
27 .fb_imageblit = drm_fb_helper_cfb_imageblit,
28 .fb_mmap = bochsfb_mmap,
31 static int bochsfb_create_object(struct bochs_device *bochs,
32 const struct drm_mode_fb_cmd2 *mode_cmd,
33 struct drm_gem_object **gobj_p)
35 struct drm_device *dev = bochs->dev;
36 struct drm_gem_object *gobj;
40 size = mode_cmd->pitches[0] * mode_cmd->height;
41 ret = bochs_gem_create(dev, size, true, &gobj);
49 static int bochsfb_create(struct drm_fb_helper *helper,
50 struct drm_fb_helper_surface_size *sizes)
52 struct bochs_device *bochs =
53 container_of(helper, struct bochs_device, fb.helper);
55 struct drm_framebuffer *fb;
56 struct drm_mode_fb_cmd2 mode_cmd;
57 struct drm_gem_object *gobj = NULL;
58 struct bochs_bo *bo = NULL;
61 if (sizes->surface_bpp != 32)
64 mode_cmd.width = sizes->surface_width;
65 mode_cmd.height = sizes->surface_height;
66 mode_cmd.pitches[0] = sizes->surface_width * 4;
67 mode_cmd.pixel_format = DRM_FORMAT_HOST_XRGB8888;
68 size = mode_cmd.pitches[0] * mode_cmd.height;
70 /* alloc, pin & map bo */
71 ret = bochsfb_create_object(bochs, &mode_cmd, &gobj);
73 DRM_ERROR("failed to create fbcon backing object %d\n", ret);
77 bo = gem_to_bochs_bo(gobj);
79 ret = ttm_bo_reserve(&bo->bo, true, false, NULL);
83 ret = bochs_bo_pin(bo, TTM_PL_FLAG_VRAM, NULL);
85 DRM_ERROR("failed to pin fbcon\n");
86 ttm_bo_unreserve(&bo->bo);
90 ret = ttm_bo_kmap(&bo->bo, 0, bo->bo.num_pages,
93 DRM_ERROR("failed to kmap fbcon\n");
94 ttm_bo_unreserve(&bo->bo);
98 ttm_bo_unreserve(&bo->bo);
101 info = drm_fb_helper_alloc_fbi(helper);
103 DRM_ERROR("Failed to allocate fbi: %ld\n", PTR_ERR(info));
104 return PTR_ERR(info);
107 info->par = &bochs->fb.helper;
109 fb = drm_gem_fbdev_fb_create(bochs->dev, sizes, 0, gobj, NULL);
111 DRM_ERROR("Failed to create framebuffer: %ld\n", PTR_ERR(fb));
116 bochs->fb.helper.fb = fb;
118 strcpy(info->fix.id, "bochsdrmfb");
120 info->fbops = &bochsfb_ops;
122 drm_fb_helper_fill_fix(info, fb->pitches[0], fb->format->depth);
123 drm_fb_helper_fill_var(info, &bochs->fb.helper, sizes->fb_width,
126 info->screen_base = bo->kmap.virtual;
127 info->screen_size = size;
129 drm_vma_offset_remove(&bo->bo.bdev->vma_manager, &bo->bo.vma_node);
130 info->fix.smem_start = 0;
131 info->fix.smem_len = size;
135 static const struct drm_fb_helper_funcs bochs_fb_helper_funcs = {
136 .fb_probe = bochsfb_create,
139 static struct drm_framebuffer *
140 bochs_gem_fb_create(struct drm_device *dev, struct drm_file *file,
141 const struct drm_mode_fb_cmd2 *mode_cmd)
143 if (mode_cmd->pixel_format != DRM_FORMAT_XRGB8888 &&
144 mode_cmd->pixel_format != DRM_FORMAT_BGRX8888)
145 return ERR_PTR(-EINVAL);
147 return drm_gem_fb_create(dev, file, mode_cmd);
150 const struct drm_mode_config_funcs bochs_mode_funcs = {
151 .fb_create = bochs_gem_fb_create,
154 int bochs_fbdev_init(struct bochs_device *bochs)
156 return drm_fb_helper_fbdev_setup(bochs->dev, &bochs->fb.helper,
157 &bochs_fb_helper_funcs, 32, 1);
160 void bochs_fbdev_fini(struct bochs_device *bochs)
162 drm_fb_helper_fbdev_teardown(bochs->dev);