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.3-rc3 119 lines 2.7 kB view raw
1// SPDX-License-Identifier: GPL-2.0-only 2/* 3 * Copyright (c) 2015 MediaTek Inc. 4 */ 5 6#include <drm/drmP.h> 7#include <drm/drm_modeset_helper.h> 8#include <drm/drm_fb_helper.h> 9#include <drm/drm_gem.h> 10#include <drm/drm_gem_framebuffer_helper.h> 11#include <linux/dma-buf.h> 12#include <linux/reservation.h> 13 14#include "mtk_drm_drv.h" 15#include "mtk_drm_fb.h" 16#include "mtk_drm_gem.h" 17 18static const struct drm_framebuffer_funcs mtk_drm_fb_funcs = { 19 .create_handle = drm_gem_fb_create_handle, 20 .destroy = drm_gem_fb_destroy, 21}; 22 23static struct drm_framebuffer *mtk_drm_framebuffer_init(struct drm_device *dev, 24 const struct drm_mode_fb_cmd2 *mode, 25 struct drm_gem_object *obj) 26{ 27 const struct drm_format_info *info = drm_get_format_info(dev, mode); 28 struct drm_framebuffer *fb; 29 int ret; 30 31 if (info->num_planes != 1) 32 return ERR_PTR(-EINVAL); 33 34 fb = kzalloc(sizeof(*fb), GFP_KERNEL); 35 if (!fb) 36 return ERR_PTR(-ENOMEM); 37 38 drm_helper_mode_fill_fb_struct(dev, fb, mode); 39 40 fb->obj[0] = obj; 41 42 ret = drm_framebuffer_init(dev, fb, &mtk_drm_fb_funcs); 43 if (ret) { 44 DRM_ERROR("failed to initialize framebuffer\n"); 45 kfree(fb); 46 return ERR_PTR(ret); 47 } 48 49 return fb; 50} 51 52/* 53 * Wait for any exclusive fence in fb's gem object's reservation object. 54 * 55 * Returns -ERESTARTSYS if interrupted, else 0. 56 */ 57int mtk_fb_wait(struct drm_framebuffer *fb) 58{ 59 struct drm_gem_object *gem; 60 struct reservation_object *resv; 61 long ret; 62 63 if (!fb) 64 return 0; 65 66 gem = fb->obj[0]; 67 if (!gem || !gem->dma_buf || !gem->dma_buf->resv) 68 return 0; 69 70 resv = gem->dma_buf->resv; 71 ret = reservation_object_wait_timeout_rcu(resv, false, true, 72 MAX_SCHEDULE_TIMEOUT); 73 /* MAX_SCHEDULE_TIMEOUT on success, -ERESTARTSYS if interrupted */ 74 if (WARN_ON(ret < 0)) 75 return ret; 76 77 return 0; 78} 79 80struct drm_framebuffer *mtk_drm_mode_fb_create(struct drm_device *dev, 81 struct drm_file *file, 82 const struct drm_mode_fb_cmd2 *cmd) 83{ 84 const struct drm_format_info *info = drm_get_format_info(dev, cmd); 85 struct drm_framebuffer *fb; 86 struct drm_gem_object *gem; 87 unsigned int width = cmd->width; 88 unsigned int height = cmd->height; 89 unsigned int size, bpp; 90 int ret; 91 92 if (info->num_planes != 1) 93 return ERR_PTR(-EINVAL); 94 95 gem = drm_gem_object_lookup(file, cmd->handles[0]); 96 if (!gem) 97 return ERR_PTR(-ENOENT); 98 99 bpp = info->cpp[0]; 100 size = (height - 1) * cmd->pitches[0] + width * bpp; 101 size += cmd->offsets[0]; 102 103 if (gem->size < size) { 104 ret = -EINVAL; 105 goto unreference; 106 } 107 108 fb = mtk_drm_framebuffer_init(dev, cmd, gem); 109 if (IS_ERR(fb)) { 110 ret = PTR_ERR(fb); 111 goto unreference; 112 } 113 114 return fb; 115 116unreference: 117 drm_gem_object_put_unlocked(gem); 118 return ERR_PTR(ret); 119}