1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (C) Fuzhou Rockchip Electronics Co.Ltd
4 * Author:Mark Yao <mark.yao@rock-chips.com>
7 #include <linux/kernel.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>
17 #include "rockchip_drm_drv.h"
18 #include "rockchip_drm_fb.h"
19 #include "rockchip_drm_gem.h"
21 static 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
,
27 static struct drm_framebuffer
*
28 rockchip_fb_alloc(struct drm_device
*dev
, const struct drm_mode_fb_cmd2
*mode_cmd
,
29 struct drm_gem_object
**obj
, unsigned int num_planes
)
31 struct drm_framebuffer
*fb
;
35 fb
= kzalloc(sizeof(*fb
), GFP_KERNEL
);
37 return ERR_PTR(-ENOMEM
);
39 drm_helper_mode_fill_fb_struct(dev
, fb
, mode_cmd
);
41 for (i
= 0; i
< num_planes
; i
++)
44 ret
= drm_framebuffer_init(dev
, fb
, &rockchip_drm_fb_funcs
);
46 DRM_DEV_ERROR(dev
->dev
,
47 "Failed to initialize framebuffer: %d\n",
56 static const struct drm_mode_config_helper_funcs rockchip_mode_config_helpers
= {
57 .atomic_commit_tail
= drm_atomic_helper_commit_tail_rpm
,
60 static struct drm_framebuffer
*
61 rockchip_fb_create(struct drm_device
*dev
, struct drm_file
*file
,
62 const struct drm_mode_fb_cmd2
*mode_cmd
)
64 struct drm_afbc_framebuffer
*afbc_fb
;
65 const struct drm_format_info
*info
;
68 info
= drm_get_format_info(dev
, mode_cmd
);
70 return ERR_PTR(-ENOMEM
);
72 afbc_fb
= kzalloc(sizeof(*afbc_fb
), GFP_KERNEL
);
74 return ERR_PTR(-ENOMEM
);
76 ret
= drm_gem_fb_init_with_funcs(dev
, &afbc_fb
->base
, file
, mode_cmd
,
77 &rockchip_drm_fb_funcs
);
83 if (drm_is_afbc(mode_cmd
->modifier
[0])) {
86 ret
= drm_gem_fb_afbc_init(dev
, mode_cmd
, afbc_fb
);
88 struct drm_gem_object
**obj
= afbc_fb
->base
.obj
;
90 for (i
= 0; i
< info
->num_planes
; ++i
)
91 drm_gem_object_put(obj
[i
]);
98 return &afbc_fb
->base
;
101 static 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
,
108 struct drm_framebuffer
*
109 rockchip_drm_framebuffer_init(struct drm_device
*dev
,
110 const struct drm_mode_fb_cmd2
*mode_cmd
,
111 struct drm_gem_object
*obj
)
113 struct drm_framebuffer
*fb
;
115 fb
= rockchip_fb_alloc(dev
, mode_cmd
, &obj
, 1);
122 void rockchip_drm_mode_config_init(struct drm_device
*dev
)
124 dev
->mode_config
.min_width
= 0;
125 dev
->mode_config
.min_height
= 0;
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().
132 dev
->mode_config
.max_width
= 4096;
133 dev
->mode_config
.max_height
= 4096;
135 dev
->mode_config
.funcs
= &rockchip_drm_mode_config_funcs
;
136 dev
->mode_config
.helper_private
= &rockchip_mode_config_helpers
;