root/drivers/gpu/drm/hisilicon/hibmc/hibmc_ttm.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. hibmc_mm_init
  2. hibmc_mm_fini
  3. hibmc_gem_create
  4. hibmc_dumb_create
  5. hibmc_user_framebuffer_destroy
  6. hibmc_framebuffer_init
  7. hibmc_user_framebuffer_create

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /* Hisilicon Hibmc SoC drm driver
   3  *
   4  * Based on the bochs drm driver.
   5  *
   6  * Copyright (c) 2016 Huawei Limited.
   7  *
   8  * Author:
   9  *      Rongrong Zou <zourongrong@huawei.com>
  10  *      Rongrong Zou <zourongrong@gmail.com>
  11  *      Jianhua Li <lijianhua@huawei.com>
  12  */
  13 
  14 #include <linux/pci.h>
  15 
  16 #include <drm/drm_atomic_helper.h>
  17 #include <drm/drm_gem.h>
  18 #include <drm/drm_gem_vram_helper.h>
  19 #include <drm/drm_print.h>
  20 #include <drm/drm_vram_mm_helper.h>
  21 
  22 #include "hibmc_drm_drv.h"
  23 
  24 int hibmc_mm_init(struct hibmc_drm_private *hibmc)
  25 {
  26         struct drm_vram_mm *vmm;
  27         int ret;
  28         struct drm_device *dev = hibmc->dev;
  29 
  30         vmm = drm_vram_helper_alloc_mm(dev,
  31                                        pci_resource_start(dev->pdev, 0),
  32                                        hibmc->fb_size, &drm_gem_vram_mm_funcs);
  33         if (IS_ERR(vmm)) {
  34                 ret = PTR_ERR(vmm);
  35                 DRM_ERROR("Error initializing VRAM MM; %d\n", ret);
  36                 return ret;
  37         }
  38 
  39         return 0;
  40 }
  41 
  42 void hibmc_mm_fini(struct hibmc_drm_private *hibmc)
  43 {
  44         if (!hibmc->dev->vram_mm)
  45                 return;
  46 
  47         drm_vram_helper_release_mm(hibmc->dev);
  48 }
  49 
  50 int hibmc_gem_create(struct drm_device *dev, u32 size, bool iskernel,
  51                      struct drm_gem_object **obj)
  52 {
  53         struct drm_gem_vram_object *gbo;
  54         int ret;
  55 
  56         *obj = NULL;
  57 
  58         size = roundup(size, PAGE_SIZE);
  59         if (size == 0)
  60                 return -EINVAL;
  61 
  62         gbo = drm_gem_vram_create(dev, &dev->vram_mm->bdev, size, 0, false);
  63         if (IS_ERR(gbo)) {
  64                 ret = PTR_ERR(gbo);
  65                 if (ret != -ERESTARTSYS)
  66                         DRM_ERROR("failed to allocate GEM object: %d\n", ret);
  67                 return ret;
  68         }
  69         *obj = &gbo->bo.base;
  70         return 0;
  71 }
  72 
  73 int hibmc_dumb_create(struct drm_file *file, struct drm_device *dev,
  74                       struct drm_mode_create_dumb *args)
  75 {
  76         struct drm_gem_object *gobj;
  77         u32 handle;
  78         int ret;
  79 
  80         args->pitch = ALIGN(args->width * DIV_ROUND_UP(args->bpp, 8), 16);
  81         args->size = args->pitch * args->height;
  82 
  83         ret = hibmc_gem_create(dev, args->size, false,
  84                                &gobj);
  85         if (ret) {
  86                 DRM_ERROR("failed to create GEM object: %d\n", ret);
  87                 return ret;
  88         }
  89 
  90         ret = drm_gem_handle_create(file, gobj, &handle);
  91         drm_gem_object_put_unlocked(gobj);
  92         if (ret) {
  93                 DRM_ERROR("failed to unreference GEM object: %d\n", ret);
  94                 return ret;
  95         }
  96 
  97         args->handle = handle;
  98         return 0;
  99 }
 100 
 101 static void hibmc_user_framebuffer_destroy(struct drm_framebuffer *fb)
 102 {
 103         struct hibmc_framebuffer *hibmc_fb = to_hibmc_framebuffer(fb);
 104 
 105         drm_gem_object_put_unlocked(hibmc_fb->obj);
 106         drm_framebuffer_cleanup(fb);
 107         kfree(hibmc_fb);
 108 }
 109 
 110 static const struct drm_framebuffer_funcs hibmc_fb_funcs = {
 111         .destroy = hibmc_user_framebuffer_destroy,
 112 };
 113 
 114 struct hibmc_framebuffer *
 115 hibmc_framebuffer_init(struct drm_device *dev,
 116                        const struct drm_mode_fb_cmd2 *mode_cmd,
 117                        struct drm_gem_object *obj)
 118 {
 119         struct hibmc_framebuffer *hibmc_fb;
 120         int ret;
 121 
 122         hibmc_fb = kzalloc(sizeof(*hibmc_fb), GFP_KERNEL);
 123         if (!hibmc_fb) {
 124                 DRM_ERROR("failed to allocate hibmc_fb\n");
 125                 return ERR_PTR(-ENOMEM);
 126         }
 127 
 128         drm_helper_mode_fill_fb_struct(dev, &hibmc_fb->fb, mode_cmd);
 129         hibmc_fb->obj = obj;
 130         ret = drm_framebuffer_init(dev, &hibmc_fb->fb, &hibmc_fb_funcs);
 131         if (ret) {
 132                 DRM_ERROR("drm_framebuffer_init failed: %d\n", ret);
 133                 kfree(hibmc_fb);
 134                 return ERR_PTR(ret);
 135         }
 136 
 137         return hibmc_fb;
 138 }
 139 
 140 static struct drm_framebuffer *
 141 hibmc_user_framebuffer_create(struct drm_device *dev,
 142                               struct drm_file *filp,
 143                               const struct drm_mode_fb_cmd2 *mode_cmd)
 144 {
 145         struct drm_gem_object *obj;
 146         struct hibmc_framebuffer *hibmc_fb;
 147 
 148         DRM_DEBUG_DRIVER("%dx%d, format %c%c%c%c\n",
 149                          mode_cmd->width, mode_cmd->height,
 150                          (mode_cmd->pixel_format) & 0xff,
 151                          (mode_cmd->pixel_format >> 8)  & 0xff,
 152                          (mode_cmd->pixel_format >> 16) & 0xff,
 153                          (mode_cmd->pixel_format >> 24) & 0xff);
 154 
 155         obj = drm_gem_object_lookup(filp, mode_cmd->handles[0]);
 156         if (!obj)
 157                 return ERR_PTR(-ENOENT);
 158 
 159         hibmc_fb = hibmc_framebuffer_init(dev, mode_cmd, obj);
 160         if (IS_ERR(hibmc_fb)) {
 161                 drm_gem_object_put_unlocked(obj);
 162                 return ERR_PTR((long)hibmc_fb);
 163         }
 164         return &hibmc_fb->fb;
 165 }
 166 
 167 const struct drm_mode_config_funcs hibmc_mode_funcs = {
 168         .atomic_check = drm_atomic_helper_check,
 169         .atomic_commit = drm_atomic_helper_commit,
 170         .fb_create = hibmc_user_framebuffer_create,
 171 };

/* [<][>][^][v][top][bottom][index][help] */