Skip to content
This repository was archived by the owner on Nov 8, 2023. It is now read-only.

Commit 0ec7636

Browse files
Thomas ZimmermannCarlos Llamas
authored andcommitted
UPSTREAM: drm/fbdev-ttm: Support struct drm_driver.fbdev_probe
[ Upstream commit c7c1b9e ] Rework fbdev probing to support fbdev_probe in struct drm_driver and reimplement the old fb_probe callback on top of it. Provide an initializer macro for struct drm_driver that sets the callback according to the kernel configuration. This change allows the common fbdev client to run on top of TTM- based DRM drivers. Change-Id: I61a1939a5260a5aaf97226dc90e97bd055a37159 Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Acked-by: Javier Martinez Canillas <javierm@redhat.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240924071734.98201-65-tzimmermann@suse.de Stable-dep-of: 6b481ab ("drm/nouveau: select FW caching") Signed-off-by: Sasha Levin <sashal@kernel.org> (cherry picked from commit dad0617) Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
1 parent 9df628f commit 0ec7636

File tree

2 files changed

+90
-65
lines changed

2 files changed

+90
-65
lines changed

drivers/gpu/drm/drm_fbdev_ttm.c

Lines changed: 77 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -71,71 +71,7 @@ static const struct fb_ops drm_fbdev_ttm_fb_ops = {
7171
static int drm_fbdev_ttm_helper_fb_probe(struct drm_fb_helper *fb_helper,
7272
struct drm_fb_helper_surface_size *sizes)
7373
{
74-
struct drm_client_dev *client = &fb_helper->client;
75-
struct drm_device *dev = fb_helper->dev;
76-
struct drm_client_buffer *buffer;
77-
struct fb_info *info;
78-
size_t screen_size;
79-
void *screen_buffer;
80-
u32 format;
81-
int ret;
82-
83-
drm_dbg_kms(dev, "surface width(%d), height(%d) and bpp(%d)\n",
84-
sizes->surface_width, sizes->surface_height,
85-
sizes->surface_bpp);
86-
87-
format = drm_driver_legacy_fb_format(dev, sizes->surface_bpp,
88-
sizes->surface_depth);
89-
buffer = drm_client_framebuffer_create(client, sizes->surface_width,
90-
sizes->surface_height, format);
91-
if (IS_ERR(buffer))
92-
return PTR_ERR(buffer);
93-
94-
fb_helper->buffer = buffer;
95-
fb_helper->fb = buffer->fb;
96-
97-
screen_size = buffer->gem->size;
98-
screen_buffer = vzalloc(screen_size);
99-
if (!screen_buffer) {
100-
ret = -ENOMEM;
101-
goto err_drm_client_framebuffer_delete;
102-
}
103-
104-
info = drm_fb_helper_alloc_info(fb_helper);
105-
if (IS_ERR(info)) {
106-
ret = PTR_ERR(info);
107-
goto err_vfree;
108-
}
109-
110-
drm_fb_helper_fill_info(info, fb_helper, sizes);
111-
112-
info->fbops = &drm_fbdev_ttm_fb_ops;
113-
114-
/* screen */
115-
info->flags |= FBINFO_VIRTFB | FBINFO_READS_FAST;
116-
info->screen_buffer = screen_buffer;
117-
info->fix.smem_len = screen_size;
118-
119-
/* deferred I/O */
120-
fb_helper->fbdefio.delay = HZ / 20;
121-
fb_helper->fbdefio.deferred_io = drm_fb_helper_deferred_io;
122-
123-
info->fbdefio = &fb_helper->fbdefio;
124-
ret = fb_deferred_io_init(info);
125-
if (ret)
126-
goto err_drm_fb_helper_release_info;
127-
128-
return 0;
129-
130-
err_drm_fb_helper_release_info:
131-
drm_fb_helper_release_info(fb_helper);
132-
err_vfree:
133-
vfree(screen_buffer);
134-
err_drm_client_framebuffer_delete:
135-
fb_helper->fb = NULL;
136-
fb_helper->buffer = NULL;
137-
drm_client_framebuffer_delete(buffer);
138-
return ret;
74+
return drm_fbdev_ttm_driver_fbdev_probe(fb_helper, sizes);
13975
}
14076

14177
static void drm_fbdev_ttm_damage_blit_real(struct drm_fb_helper *fb_helper,
@@ -240,6 +176,82 @@ static const struct drm_fb_helper_funcs drm_fbdev_ttm_helper_funcs = {
240176
.fb_dirty = drm_fbdev_ttm_helper_fb_dirty,
241177
};
242178

179+
/*
180+
* struct drm_driver
181+
*/
182+
183+
int drm_fbdev_ttm_driver_fbdev_probe(struct drm_fb_helper *fb_helper,
184+
struct drm_fb_helper_surface_size *sizes)
185+
{
186+
struct drm_client_dev *client = &fb_helper->client;
187+
struct drm_device *dev = fb_helper->dev;
188+
struct drm_client_buffer *buffer;
189+
struct fb_info *info;
190+
size_t screen_size;
191+
void *screen_buffer;
192+
u32 format;
193+
int ret;
194+
195+
drm_dbg_kms(dev, "surface width(%d), height(%d) and bpp(%d)\n",
196+
sizes->surface_width, sizes->surface_height,
197+
sizes->surface_bpp);
198+
199+
format = drm_driver_legacy_fb_format(dev, sizes->surface_bpp,
200+
sizes->surface_depth);
201+
buffer = drm_client_framebuffer_create(client, sizes->surface_width,
202+
sizes->surface_height, format);
203+
if (IS_ERR(buffer))
204+
return PTR_ERR(buffer);
205+
206+
fb_helper->funcs = &drm_fbdev_ttm_helper_funcs;
207+
fb_helper->buffer = buffer;
208+
fb_helper->fb = buffer->fb;
209+
210+
screen_size = buffer->gem->size;
211+
screen_buffer = vzalloc(screen_size);
212+
if (!screen_buffer) {
213+
ret = -ENOMEM;
214+
goto err_drm_client_framebuffer_delete;
215+
}
216+
217+
info = drm_fb_helper_alloc_info(fb_helper);
218+
if (IS_ERR(info)) {
219+
ret = PTR_ERR(info);
220+
goto err_vfree;
221+
}
222+
223+
drm_fb_helper_fill_info(info, fb_helper, sizes);
224+
225+
info->fbops = &drm_fbdev_ttm_fb_ops;
226+
227+
/* screen */
228+
info->flags |= FBINFO_VIRTFB | FBINFO_READS_FAST;
229+
info->screen_buffer = screen_buffer;
230+
info->fix.smem_len = screen_size;
231+
232+
/* deferred I/O */
233+
fb_helper->fbdefio.delay = HZ / 20;
234+
fb_helper->fbdefio.deferred_io = drm_fb_helper_deferred_io;
235+
236+
info->fbdefio = &fb_helper->fbdefio;
237+
ret = fb_deferred_io_init(info);
238+
if (ret)
239+
goto err_drm_fb_helper_release_info;
240+
241+
return 0;
242+
243+
err_drm_fb_helper_release_info:
244+
drm_fb_helper_release_info(fb_helper);
245+
err_vfree:
246+
vfree(screen_buffer);
247+
err_drm_client_framebuffer_delete:
248+
fb_helper->fb = NULL;
249+
fb_helper->buffer = NULL;
250+
drm_client_framebuffer_delete(buffer);
251+
return ret;
252+
}
253+
EXPORT_SYMBOL(drm_fbdev_ttm_driver_fbdev_probe);
254+
243255
static void drm_fbdev_ttm_client_unregister(struct drm_client_dev *client)
244256
{
245257
struct drm_fb_helper *fb_helper = drm_fb_helper_from_client(client);

include/drm/drm_fbdev_ttm.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,24 @@
33
#ifndef DRM_FBDEV_TTM_H
44
#define DRM_FBDEV_TTM_H
55

6+
#include <linux/stddef.h>
7+
68
struct drm_device;
9+
struct drm_fb_helper;
10+
struct drm_fb_helper_surface_size;
711

812
#ifdef CONFIG_DRM_FBDEV_EMULATION
13+
int drm_fbdev_ttm_driver_fbdev_probe(struct drm_fb_helper *fb_helper,
14+
struct drm_fb_helper_surface_size *sizes);
15+
16+
#define DRM_FBDEV_TTM_DRIVER_OPS \
17+
.fbdev_probe = drm_fbdev_ttm_driver_fbdev_probe
18+
919
void drm_fbdev_ttm_setup(struct drm_device *dev, unsigned int preferred_bpp);
1020
#else
21+
#define DRM_FBDEV_TTM_DRIVER_OPS \
22+
.fbdev_probe = NULL
23+
1124
static inline void drm_fbdev_ttm_setup(struct drm_device *dev, unsigned int preferred_bpp)
1225
{ }
1326
#endif

0 commit comments

Comments
 (0)