cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

rockchip_drm_fb.c (3453B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * Copyright (C) Fuzhou Rockchip Electronics Co.Ltd
      4 * Author:Mark Yao <mark.yao@rock-chips.com>
      5 */
      6
      7#include <linux/kernel.h>
      8
      9#include <drm/drm.h>
     10#include <drm/drm_atomic.h>
     11#include <drm/drm_damage_helper.h>
     12#include <drm/drm_fb_helper.h>
     13#include <drm/drm_fourcc.h>
     14#include <drm/drm_gem_framebuffer_helper.h>
     15#include <drm/drm_probe_helper.h>
     16
     17#include "rockchip_drm_drv.h"
     18#include "rockchip_drm_fb.h"
     19#include "rockchip_drm_gem.h"
     20
     21static const struct drm_framebuffer_funcs rockchip_drm_fb_funcs = {
     22	.destroy       = drm_gem_fb_destroy,
     23	.create_handle = drm_gem_fb_create_handle,
     24	.dirty	       = drm_atomic_helper_dirtyfb,
     25};
     26
     27static struct drm_framebuffer *
     28rockchip_fb_alloc(struct drm_device *dev, const struct drm_mode_fb_cmd2 *mode_cmd,
     29		  struct drm_gem_object **obj, unsigned int num_planes)
     30{
     31	struct drm_framebuffer *fb;
     32	int ret;
     33	int i;
     34
     35	fb = kzalloc(sizeof(*fb), GFP_KERNEL);
     36	if (!fb)
     37		return ERR_PTR(-ENOMEM);
     38
     39	drm_helper_mode_fill_fb_struct(dev, fb, mode_cmd);
     40
     41	for (i = 0; i < num_planes; i++)
     42		fb->obj[i] = obj[i];
     43
     44	ret = drm_framebuffer_init(dev, fb, &rockchip_drm_fb_funcs);
     45	if (ret) {
     46		DRM_DEV_ERROR(dev->dev,
     47			      "Failed to initialize framebuffer: %d\n",
     48			      ret);
     49		kfree(fb);
     50		return ERR_PTR(ret);
     51	}
     52
     53	return fb;
     54}
     55
     56static const struct drm_mode_config_helper_funcs rockchip_mode_config_helpers = {
     57	.atomic_commit_tail = drm_atomic_helper_commit_tail_rpm,
     58};
     59
     60static struct drm_framebuffer *
     61rockchip_fb_create(struct drm_device *dev, struct drm_file *file,
     62		   const struct drm_mode_fb_cmd2 *mode_cmd)
     63{
     64	struct drm_afbc_framebuffer *afbc_fb;
     65	const struct drm_format_info *info;
     66	int ret;
     67
     68	info = drm_get_format_info(dev, mode_cmd);
     69	if (!info)
     70		return ERR_PTR(-ENOMEM);
     71
     72	afbc_fb = kzalloc(sizeof(*afbc_fb), GFP_KERNEL);
     73	if (!afbc_fb)
     74		return ERR_PTR(-ENOMEM);
     75
     76	ret = drm_gem_fb_init_with_funcs(dev, &afbc_fb->base, file, mode_cmd,
     77					 &rockchip_drm_fb_funcs);
     78	if (ret) {
     79		kfree(afbc_fb);
     80		return ERR_PTR(ret);
     81	}
     82
     83	if (drm_is_afbc(mode_cmd->modifier[0])) {
     84		int ret, i;
     85
     86		ret = drm_gem_fb_afbc_init(dev, mode_cmd, afbc_fb);
     87		if (ret) {
     88			struct drm_gem_object **obj = afbc_fb->base.obj;
     89
     90			for (i = 0; i < info->num_planes; ++i)
     91				drm_gem_object_put(obj[i]);
     92
     93			kfree(afbc_fb);
     94			return ERR_PTR(ret);
     95		}
     96	}
     97
     98	return &afbc_fb->base;
     99}
    100
    101static const struct drm_mode_config_funcs rockchip_drm_mode_config_funcs = {
    102	.fb_create = rockchip_fb_create,
    103	.output_poll_changed = drm_fb_helper_output_poll_changed,
    104	.atomic_check = drm_atomic_helper_check,
    105	.atomic_commit = drm_atomic_helper_commit,
    106};
    107
    108struct drm_framebuffer *
    109rockchip_drm_framebuffer_init(struct drm_device *dev,
    110			      const struct drm_mode_fb_cmd2 *mode_cmd,
    111			      struct drm_gem_object *obj)
    112{
    113	struct drm_framebuffer *fb;
    114
    115	fb = rockchip_fb_alloc(dev, mode_cmd, &obj, 1);
    116	if (IS_ERR(fb))
    117		return ERR_CAST(fb);
    118
    119	return fb;
    120}
    121
    122void rockchip_drm_mode_config_init(struct drm_device *dev)
    123{
    124	dev->mode_config.min_width = 0;
    125	dev->mode_config.min_height = 0;
    126
    127	/*
    128	 * set max width and height as default value(4096x4096).
    129	 * this value would be used to check framebuffer size limitation
    130	 * at drm_mode_addfb().
    131	 */
    132	dev->mode_config.max_width = 4096;
    133	dev->mode_config.max_height = 4096;
    134
    135	dev->mode_config.funcs = &rockchip_drm_mode_config_funcs;
    136	dev->mode_config.helper_private = &rockchip_mode_config_helpers;
    137
    138	dev->mode_config.normalize_zpos = true;
    139}