Skip to content

Commit b5f636e

Browse files
committed
drm/mipi-dbi: Prepare framebuffer copy operation in pipe-update helpers
Move the vmap/vunmap blocks from the inner fb_dirty helpers into the MIPI DBI update helpers. The function calls can result in waiting and/or processing overhead. Reduce the penalties by executing the functions once in the outer-most function of the pipe update. This change also prepares for MIPI DBI for shadow-plane helpers. With shadow-plane helpers, transfer source buffers are mapped into kernel address space automatically. v2: * keep each driver's existing buffer-mapping patter (Noralf) * zero-initialize iosys_map arrays (Noralf) Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Reviewed-by: Noralf Trønnes <noralf@tronnes.org> Tested-by: Javier Martinez Canillas <javierm@redhat.com> Tested-by: Noralf Trønnes <noralf@tronnes.org> # drm/tiny/mi0283qt Link: https://patchwork.freedesktop.org/patch/msgid/20221202125644.7917-6-tzimmermann@suse.de
1 parent 63aa5ec commit b5f636e

File tree

4 files changed

+75
-47
lines changed

4 files changed

+75
-47
lines changed

drivers/gpu/drm/drm_mipi_dbi.c

Lines changed: 33 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -192,48 +192,41 @@ EXPORT_SYMBOL(mipi_dbi_command_stackbuf);
192192
/**
193193
* mipi_dbi_buf_copy - Copy a framebuffer, transforming it if necessary
194194
* @dst: The destination buffer
195+
* @src: The source buffer
195196
* @fb: The source framebuffer
196197
* @clip: Clipping rectangle of the area to be copied
197198
* @swap: When true, swap MSB/LSB of 16-bit values
198199
*
199200
* Returns:
200201
* Zero on success, negative error code on failure.
201202
*/
202-
int mipi_dbi_buf_copy(void *dst, struct drm_framebuffer *fb,
203+
int mipi_dbi_buf_copy(void *dst, struct iosys_map *src, struct drm_framebuffer *fb,
203204
struct drm_rect *clip, bool swap)
204205
{
205206
struct drm_gem_object *gem = drm_gem_fb_get_obj(fb, 0);
206-
struct iosys_map map[DRM_FORMAT_MAX_PLANES];
207-
struct iosys_map data[DRM_FORMAT_MAX_PLANES];
208207
struct iosys_map dst_map = IOSYS_MAP_INIT_VADDR(dst);
209208
int ret;
210209

211210
ret = drm_gem_fb_begin_cpu_access(fb, DMA_FROM_DEVICE);
212211
if (ret)
213212
return ret;
214213

215-
ret = drm_gem_fb_vmap(fb, map, data);
216-
if (ret)
217-
goto out_drm_gem_fb_end_cpu_access;
218-
219214
switch (fb->format->format) {
220215
case DRM_FORMAT_RGB565:
221216
if (swap)
222-
drm_fb_swab(&dst_map, NULL, data, fb, clip, !gem->import_attach);
217+
drm_fb_swab(&dst_map, NULL, src, fb, clip, !gem->import_attach);
223218
else
224-
drm_fb_memcpy(&dst_map, NULL, data, fb, clip);
219+
drm_fb_memcpy(&dst_map, NULL, src, fb, clip);
225220
break;
226221
case DRM_FORMAT_XRGB8888:
227-
drm_fb_xrgb8888_to_rgb565(&dst_map, NULL, data, fb, clip, swap);
222+
drm_fb_xrgb8888_to_rgb565(&dst_map, NULL, src, fb, clip, swap);
228223
break;
229224
default:
230225
drm_err_once(fb->dev, "Format is not supported: %p4cc\n",
231226
&fb->format->format);
232227
ret = -EINVAL;
233228
}
234229

235-
drm_gem_fb_vunmap(fb, map);
236-
out_drm_gem_fb_end_cpu_access:
237230
drm_gem_fb_end_cpu_access(fb, DMA_FROM_DEVICE);
238231

239232
return ret;
@@ -257,10 +250,9 @@ static void mipi_dbi_set_window_address(struct mipi_dbi_dev *dbidev,
257250
ys & 0xff, (ye >> 8) & 0xff, ye & 0xff);
258251
}
259252

260-
static void mipi_dbi_fb_dirty(struct drm_framebuffer *fb, struct drm_rect *rect)
253+
static void mipi_dbi_fb_dirty(struct iosys_map *src, struct drm_framebuffer *fb,
254+
struct drm_rect *rect)
261255
{
262-
struct iosys_map map[DRM_FORMAT_MAX_PLANES];
263-
struct iosys_map data[DRM_FORMAT_MAX_PLANES];
264256
struct mipi_dbi_dev *dbidev = drm_to_mipi_dbi_dev(fb->dev);
265257
unsigned int height = rect->y2 - rect->y1;
266258
unsigned int width = rect->x2 - rect->x1;
@@ -270,28 +262,21 @@ static void mipi_dbi_fb_dirty(struct drm_framebuffer *fb, struct drm_rect *rect)
270262
bool full;
271263
void *tr;
272264

273-
if (WARN_ON(!fb))
274-
return;
275-
276265
if (!drm_dev_enter(fb->dev, &idx))
277266
return;
278267

279-
ret = drm_gem_fb_vmap(fb, map, data);
280-
if (ret)
281-
goto err_drm_dev_exit;
282-
283268
full = width == fb->width && height == fb->height;
284269

285270
DRM_DEBUG_KMS("Flushing [FB:%d] " DRM_RECT_FMT "\n", fb->base.id, DRM_RECT_ARG(rect));
286271

287272
if (!dbi->dc || !full || swap ||
288273
fb->format->format == DRM_FORMAT_XRGB8888) {
289274
tr = dbidev->tx_buf;
290-
ret = mipi_dbi_buf_copy(dbidev->tx_buf, fb, rect, swap);
275+
ret = mipi_dbi_buf_copy(tr, src, fb, rect, swap);
291276
if (ret)
292277
goto err_msg;
293278
} else {
294-
tr = data[0].vaddr; /* TODO: Use mapping abstraction properly */
279+
tr = src->vaddr; /* TODO: Use mapping abstraction properly */
295280
}
296281

297282
mipi_dbi_set_window_address(dbidev, rect->x1, rect->x2 - 1, rect->y1,
@@ -303,9 +288,6 @@ static void mipi_dbi_fb_dirty(struct drm_framebuffer *fb, struct drm_rect *rect)
303288
if (ret)
304289
drm_err_once(fb->dev, "Failed to update display %d\n", ret);
305290

306-
drm_gem_fb_vunmap(fb, map);
307-
308-
err_drm_dev_exit:
309291
drm_dev_exit(idx);
310292
}
311293

@@ -338,14 +320,27 @@ EXPORT_SYMBOL(mipi_dbi_pipe_mode_valid);
338320
void mipi_dbi_pipe_update(struct drm_simple_display_pipe *pipe,
339321
struct drm_plane_state *old_state)
340322
{
323+
struct iosys_map map[DRM_FORMAT_MAX_PLANES] = { };
324+
struct iosys_map data[DRM_FORMAT_MAX_PLANES] = { };
341325
struct drm_plane_state *state = pipe->plane.state;
326+
struct drm_framebuffer *fb = state->fb;
342327
struct drm_rect rect;
328+
int ret;
343329

344330
if (!pipe->crtc.state->active)
345331
return;
346332

333+
if (WARN_ON(!fb))
334+
return;
335+
336+
ret = drm_gem_fb_vmap(fb, map, data);
337+
if (ret)
338+
return;
339+
347340
if (drm_atomic_helper_damage_merged(old_state, state, &rect))
348-
mipi_dbi_fb_dirty(state->fb, &rect);
341+
mipi_dbi_fb_dirty(&data[0], fb, &rect);
342+
343+
drm_gem_fb_vunmap(fb, map);
349344
}
350345
EXPORT_SYMBOL(mipi_dbi_pipe_update);
351346

@@ -373,14 +368,22 @@ void mipi_dbi_enable_flush(struct mipi_dbi_dev *dbidev,
373368
.y1 = 0,
374369
.y2 = fb->height,
375370
};
376-
int idx;
371+
struct iosys_map map[DRM_FORMAT_MAX_PLANES] = { };
372+
struct iosys_map data[DRM_FORMAT_MAX_PLANES] = { };
373+
int idx, ret;
377374

378375
if (!drm_dev_enter(&dbidev->drm, &idx))
379376
return;
380377

381-
mipi_dbi_fb_dirty(fb, &rect);
378+
ret = drm_gem_fb_vmap(fb, map, data);
379+
if (ret)
380+
goto err_drm_dev_exit;
381+
382+
mipi_dbi_fb_dirty(&data[0], fb, &rect);
382383
backlight_enable(dbidev->backlight);
383384

385+
drm_gem_fb_vunmap(fb, map);
386+
err_drm_dev_exit:
384387
drm_dev_exit(idx);
385388
}
386389
EXPORT_SYMBOL(mipi_dbi_enable_flush);

drivers/gpu/drm/tiny/ili9225.c

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include <drm/drm_framebuffer.h>
2626
#include <drm/drm_gem_atomic_helper.h>
2727
#include <drm/drm_gem_dma_helper.h>
28+
#include <drm/drm_gem_framebuffer_helper.h>
2829
#include <drm/drm_managed.h>
2930
#include <drm/drm_mipi_dbi.h>
3031
#include <drm/drm_rect.h>
@@ -76,9 +77,9 @@ static inline int ili9225_command(struct mipi_dbi *dbi, u8 cmd, u16 data)
7677
return mipi_dbi_command_buf(dbi, cmd, par, 2);
7778
}
7879

79-
static void ili9225_fb_dirty(struct drm_framebuffer *fb, struct drm_rect *rect)
80+
static void ili9225_fb_dirty(struct iosys_map *src, struct drm_framebuffer *fb,
81+
struct drm_rect *rect)
8082
{
81-
struct drm_gem_dma_object *dma_obj = drm_fb_dma_get_gem_obj(fb, 0);
8283
struct mipi_dbi_dev *dbidev = drm_to_mipi_dbi_dev(fb->dev);
8384
unsigned int height = rect->y2 - rect->y1;
8485
unsigned int width = rect->x2 - rect->x1;
@@ -100,11 +101,11 @@ static void ili9225_fb_dirty(struct drm_framebuffer *fb, struct drm_rect *rect)
100101
if (!dbi->dc || !full || swap ||
101102
fb->format->format == DRM_FORMAT_XRGB8888) {
102103
tr = dbidev->tx_buf;
103-
ret = mipi_dbi_buf_copy(dbidev->tx_buf, fb, rect, swap);
104+
ret = mipi_dbi_buf_copy(tr, src, fb, rect, swap);
104105
if (ret)
105106
goto err_msg;
106107
} else {
107-
tr = dma_obj->vaddr;
108+
tr = src->vaddr; /* TODO: Use mapping abstraction properly */
108109
}
109110

110111
switch (dbidev->rotation) {
@@ -163,13 +164,19 @@ static void ili9225_pipe_update(struct drm_simple_display_pipe *pipe,
163164
struct drm_plane_state *old_state)
164165
{
165166
struct drm_plane_state *state = pipe->plane.state;
167+
struct drm_framebuffer *fb = state->fb;
168+
struct drm_gem_dma_object *dma_obj;
169+
struct iosys_map src;
166170
struct drm_rect rect;
167171

168172
if (!pipe->crtc.state->active)
169173
return;
170174

175+
dma_obj = drm_fb_dma_get_gem_obj(fb, 0);
176+
iosys_map_set_vaddr(&src, dma_obj->vaddr);
177+
171178
if (drm_atomic_helper_damage_merged(old_state, state, &rect))
172-
ili9225_fb_dirty(state->fb, &rect);
179+
ili9225_fb_dirty(&src, fb, &rect);
173180
}
174181

175182
static void ili9225_pipe_enable(struct drm_simple_display_pipe *pipe,
@@ -186,6 +193,8 @@ static void ili9225_pipe_enable(struct drm_simple_display_pipe *pipe,
186193
.y1 = 0,
187194
.y2 = fb->height,
188195
};
196+
struct drm_gem_dma_object *dma_obj;
197+
struct iosys_map src;
189198
int ret, idx;
190199
u8 am_id;
191200

@@ -276,7 +285,11 @@ static void ili9225_pipe_enable(struct drm_simple_display_pipe *pipe,
276285

277286
ili9225_command(dbi, ILI9225_DISPLAY_CONTROL_1, 0x1017);
278287

279-
ili9225_fb_dirty(fb, &rect);
288+
dma_obj = drm_fb_dma_get_gem_obj(fb, 0);
289+
iosys_map_set_vaddr(&src, dma_obj->vaddr);
290+
291+
ili9225_fb_dirty(&src, fb, &rect);
292+
280293
out_exit:
281294
drm_dev_exit(idx);
282295
}

drivers/gpu/drm/tiny/st7586.c

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -92,25 +92,24 @@ static void st7586_xrgb8888_to_gray332(u8 *dst, void *vaddr,
9292
kfree(buf);
9393
}
9494

95-
static int st7586_buf_copy(void *dst, struct drm_framebuffer *fb,
95+
static int st7586_buf_copy(void *dst, struct iosys_map *src, struct drm_framebuffer *fb,
9696
struct drm_rect *clip)
9797
{
98-
struct drm_gem_dma_object *dma_obj = drm_fb_dma_get_gem_obj(fb, 0);
99-
void *src = dma_obj->vaddr;
100-
int ret = 0;
98+
int ret;
10199

102100
ret = drm_gem_fb_begin_cpu_access(fb, DMA_FROM_DEVICE);
103101
if (ret)
104102
return ret;
105103

106-
st7586_xrgb8888_to_gray332(dst, src, fb, clip);
104+
st7586_xrgb8888_to_gray332(dst, src->vaddr, fb, clip);
107105

108106
drm_gem_fb_end_cpu_access(fb, DMA_FROM_DEVICE);
109107

110108
return 0;
111109
}
112110

113-
static void st7586_fb_dirty(struct drm_framebuffer *fb, struct drm_rect *rect)
111+
static void st7586_fb_dirty(struct iosys_map *src, struct drm_framebuffer *fb,
112+
struct drm_rect *rect)
114113
{
115114
struct mipi_dbi_dev *dbidev = drm_to_mipi_dbi_dev(fb->dev);
116115
struct mipi_dbi *dbi = &dbidev->dbi;
@@ -125,7 +124,7 @@ static void st7586_fb_dirty(struct drm_framebuffer *fb, struct drm_rect *rect)
125124

126125
DRM_DEBUG_KMS("Flushing [FB:%d] " DRM_RECT_FMT "\n", fb->base.id, DRM_RECT_ARG(rect));
127126

128-
ret = st7586_buf_copy(dbidev->tx_buf, fb, rect);
127+
ret = st7586_buf_copy(dbidev->tx_buf, src, fb, rect);
129128
if (ret)
130129
goto err_msg;
131130

@@ -154,13 +153,19 @@ static void st7586_pipe_update(struct drm_simple_display_pipe *pipe,
154153
struct drm_plane_state *old_state)
155154
{
156155
struct drm_plane_state *state = pipe->plane.state;
156+
struct drm_framebuffer *fb = state->fb;
157+
struct drm_gem_dma_object *dma_obj;
158+
struct iosys_map src;
157159
struct drm_rect rect;
158160

159161
if (!pipe->crtc.state->active)
160162
return;
161163

164+
dma_obj = drm_fb_dma_get_gem_obj(fb, 0);
165+
iosys_map_set_vaddr(&src, dma_obj->vaddr);
166+
162167
if (drm_atomic_helper_damage_merged(old_state, state, &rect))
163-
st7586_fb_dirty(state->fb, &rect);
168+
st7586_fb_dirty(&src, fb, &rect);
164169
}
165170

166171
static void st7586_pipe_enable(struct drm_simple_display_pipe *pipe,
@@ -176,6 +181,8 @@ static void st7586_pipe_enable(struct drm_simple_display_pipe *pipe,
176181
.y1 = 0,
177182
.y2 = fb->height,
178183
};
184+
struct drm_gem_dma_object *dma_obj;
185+
struct iosys_map src;
179186
int idx, ret;
180187
u8 addr_mode;
181188

@@ -235,7 +242,10 @@ static void st7586_pipe_enable(struct drm_simple_display_pipe *pipe,
235242

236243
msleep(100);
237244

238-
st7586_fb_dirty(fb, &rect);
245+
dma_obj = drm_fb_dma_get_gem_obj(fb, 0);
246+
iosys_map_set_vaddr(&src, dma_obj->vaddr);
247+
248+
st7586_fb_dirty(&src, fb, &rect);
239249

240250
mipi_dbi_command(dbi, MIPI_DCS_SET_DISPLAY_ON);
241251
out_exit:

include/drm/drm_mipi_dbi.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,10 @@
1313
#include <drm/drm_simple_kms_helper.h>
1414

1515
struct drm_rect;
16-
struct spi_device;
1716
struct gpio_desc;
17+
struct iosys_map;
1818
struct regulator;
19+
struct spi_device;
1920

2021
/**
2122
* struct mipi_dbi - MIPI DBI interface
@@ -176,8 +177,9 @@ int mipi_dbi_command_read(struct mipi_dbi *dbi, u8 cmd, u8 *val);
176177
int mipi_dbi_command_buf(struct mipi_dbi *dbi, u8 cmd, u8 *data, size_t len);
177178
int mipi_dbi_command_stackbuf(struct mipi_dbi *dbi, u8 cmd, const u8 *data,
178179
size_t len);
179-
int mipi_dbi_buf_copy(void *dst, struct drm_framebuffer *fb,
180+
int mipi_dbi_buf_copy(void *dst, struct iosys_map *src, struct drm_framebuffer *fb,
180181
struct drm_rect *clip, bool swap);
182+
181183
/**
182184
* mipi_dbi_command - MIPI DCS command with optional parameter(s)
183185
* @dbi: MIPI DBI structure

0 commit comments

Comments
 (0)