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.

at v5.2-rc3 149 lines 3.7 kB view raw
1// SPDX-License-Identifier: MIT 2/* 3 * Copyright (C) 2013-2017 Oracle Corporation 4 * This file is based on ast_fb.c 5 * Copyright 2012 Red Hat Inc. 6 * Authors: Dave Airlie <airlied@redhat.com> 7 * Michael Thayer <michael.thayer@oracle.com, 8 */ 9#include <linux/delay.h> 10#include <linux/errno.h> 11#include <linux/fb.h> 12#include <linux/init.h> 13#include <linux/kernel.h> 14#include <linux/mm.h> 15#include <linux/module.h> 16#include <linux/pci.h> 17#include <linux/string.h> 18#include <linux/sysrq.h> 19#include <linux/tty.h> 20 21#include <drm/drm_crtc.h> 22#include <drm/drm_crtc_helper.h> 23#include <drm/drm_fb_helper.h> 24#include <drm/drm_fourcc.h> 25 26#include "vbox_drv.h" 27#include "vboxvideo.h" 28 29#ifdef CONFIG_DRM_KMS_FB_HELPER 30static struct fb_deferred_io vbox_defio = { 31 .delay = HZ / 30, 32 .deferred_io = drm_fb_helper_deferred_io, 33}; 34#endif 35 36static struct fb_ops vboxfb_ops = { 37 .owner = THIS_MODULE, 38 DRM_FB_HELPER_DEFAULT_OPS, 39 .fb_fillrect = drm_fb_helper_sys_fillrect, 40 .fb_copyarea = drm_fb_helper_sys_copyarea, 41 .fb_imageblit = drm_fb_helper_sys_imageblit, 42}; 43 44int vboxfb_create(struct drm_fb_helper *helper, 45 struct drm_fb_helper_surface_size *sizes) 46{ 47 struct vbox_private *vbox = 48 container_of(helper, struct vbox_private, fb_helper); 49 struct pci_dev *pdev = vbox->ddev.pdev; 50 struct drm_mode_fb_cmd2 mode_cmd; 51 struct drm_framebuffer *fb; 52 struct fb_info *info; 53 struct drm_gem_object *gobj; 54 struct vbox_bo *bo; 55 int size, ret; 56 u64 gpu_addr; 57 u32 pitch; 58 59 mode_cmd.width = sizes->surface_width; 60 mode_cmd.height = sizes->surface_height; 61 pitch = mode_cmd.width * ((sizes->surface_bpp + 7) / 8); 62 mode_cmd.pixel_format = drm_mode_legacy_fb_format(sizes->surface_bpp, 63 sizes->surface_depth); 64 mode_cmd.pitches[0] = pitch; 65 66 size = pitch * mode_cmd.height; 67 68 ret = vbox_gem_create(vbox, size, true, &gobj); 69 if (ret) { 70 DRM_ERROR("failed to create fbcon backing object %d\n", ret); 71 return ret; 72 } 73 74 ret = vbox_framebuffer_init(vbox, &vbox->afb, &mode_cmd, gobj); 75 if (ret) 76 return ret; 77 78 bo = gem_to_vbox_bo(gobj); 79 80 ret = vbox_bo_pin(bo, TTM_PL_FLAG_VRAM); 81 if (ret) 82 return ret; 83 84 info = drm_fb_helper_alloc_fbi(helper); 85 if (IS_ERR(info)) 86 return PTR_ERR(info); 87 88 info->screen_size = size; 89 info->screen_base = (char __iomem *)vbox_bo_kmap(bo); 90 if (IS_ERR(info->screen_base)) 91 return PTR_ERR(info->screen_base); 92 93 fb = &vbox->afb.base; 94 helper->fb = fb; 95 96 info->fbops = &vboxfb_ops; 97 98 /* 99 * This seems to be done for safety checking that the framebuffer 100 * is not registered twice by different drivers. 101 */ 102 info->apertures->ranges[0].base = pci_resource_start(pdev, 0); 103 info->apertures->ranges[0].size = pci_resource_len(pdev, 0); 104 105 drm_fb_helper_fill_info(info, helper, sizes); 106 107 gpu_addr = vbox_bo_gpu_offset(bo); 108 info->fix.smem_start = info->apertures->ranges[0].base + gpu_addr; 109 info->fix.smem_len = vbox->available_vram_size - gpu_addr; 110 111#ifdef CONFIG_DRM_KMS_FB_HELPER 112 info->fbdefio = &vbox_defio; 113 fb_deferred_io_init(info); 114#endif 115 116 info->pixmap.flags = FB_PIXMAP_SYSTEM; 117 118 DRM_DEBUG_KMS("allocated %dx%d\n", fb->width, fb->height); 119 120 return 0; 121} 122 123void vbox_fbdev_fini(struct vbox_private *vbox) 124{ 125 struct vbox_framebuffer *afb = &vbox->afb; 126 127#ifdef CONFIG_DRM_KMS_FB_HELPER 128 if (vbox->fb_helper.fbdev && vbox->fb_helper.fbdev->fbdefio) 129 fb_deferred_io_cleanup(vbox->fb_helper.fbdev); 130#endif 131 132 drm_fb_helper_unregister_fbi(&vbox->fb_helper); 133 134 if (afb->obj) { 135 struct vbox_bo *bo = gem_to_vbox_bo(afb->obj); 136 137 vbox_bo_kunmap(bo); 138 139 if (bo->pin_count) 140 vbox_bo_unpin(bo); 141 142 drm_gem_object_put_unlocked(afb->obj); 143 afb->obj = NULL; 144 } 145 drm_fb_helper_fini(&vbox->fb_helper); 146 147 drm_framebuffer_unregister_private(&afb->base); 148 drm_framebuffer_cleanup(&afb->base); 149}