This source file includes following definitions.
- clip_offset
- drm_fb_memcpy
- drm_fb_memcpy_dstclip
- drm_fb_swab16
- drm_fb_xrgb8888_to_rgb565_line
- drm_fb_xrgb8888_to_rgb565
- drm_fb_xrgb8888_to_rgb565_dstclip
- drm_fb_xrgb8888_to_rgb888_line
- drm_fb_xrgb8888_to_rgb888_dstclip
- drm_fb_xrgb8888_to_gray8
1
2
3
4
5
6
7
8
9
10
11 #include <linux/module.h>
12 #include <linux/slab.h>
13 #include <linux/io.h>
14
15 #include <drm/drm_format_helper.h>
16 #include <drm/drm_framebuffer.h>
17 #include <drm/drm_fourcc.h>
18 #include <drm/drm_rect.h>
19
20 static unsigned int clip_offset(struct drm_rect *clip,
21 unsigned int pitch, unsigned int cpp)
22 {
23 return clip->y1 * pitch + clip->x1 * cpp;
24 }
25
26
27
28
29
30
31
32
33
34
35
36 void drm_fb_memcpy(void *dst, void *vaddr, struct drm_framebuffer *fb,
37 struct drm_rect *clip)
38 {
39 unsigned int cpp = fb->format->cpp[0];
40 size_t len = (clip->x2 - clip->x1) * cpp;
41 unsigned int y, lines = clip->y2 - clip->y1;
42
43 vaddr += clip_offset(clip, fb->pitches[0], cpp);
44 for (y = 0; y < lines; y++) {
45 memcpy(dst, vaddr, len);
46 vaddr += fb->pitches[0];
47 dst += len;
48 }
49 }
50 EXPORT_SYMBOL(drm_fb_memcpy);
51
52
53
54
55
56
57
58
59
60
61
62 void drm_fb_memcpy_dstclip(void __iomem *dst, void *vaddr,
63 struct drm_framebuffer *fb,
64 struct drm_rect *clip)
65 {
66 unsigned int cpp = fb->format->cpp[0];
67 unsigned int offset = clip_offset(clip, fb->pitches[0], cpp);
68 size_t len = (clip->x2 - clip->x1) * cpp;
69 unsigned int y, lines = clip->y2 - clip->y1;
70
71 vaddr += offset;
72 dst += offset;
73 for (y = 0; y < lines; y++) {
74 memcpy_toio(dst, vaddr, len);
75 vaddr += fb->pitches[0];
76 dst += fb->pitches[0];
77 }
78 }
79 EXPORT_SYMBOL(drm_fb_memcpy_dstclip);
80
81
82
83
84
85
86
87
88 void drm_fb_swab16(u16 *dst, void *vaddr, struct drm_framebuffer *fb,
89 struct drm_rect *clip)
90 {
91 size_t len = (clip->x2 - clip->x1) * sizeof(u16);
92 unsigned int x, y;
93 u16 *src, *buf;
94
95
96
97
98
99 buf = kmalloc(len, GFP_KERNEL);
100 if (!buf)
101 return;
102
103 for (y = clip->y1; y < clip->y2; y++) {
104 src = vaddr + (y * fb->pitches[0]);
105 src += clip->x1;
106 memcpy(buf, src, len);
107 src = buf;
108 for (x = clip->x1; x < clip->x2; x++)
109 *dst++ = swab16(*src++);
110 }
111
112 kfree(buf);
113 }
114 EXPORT_SYMBOL(drm_fb_swab16);
115
116 static void drm_fb_xrgb8888_to_rgb565_line(u16 *dbuf, u32 *sbuf,
117 unsigned int pixels,
118 bool swab)
119 {
120 unsigned int x;
121 u16 val16;
122
123 for (x = 0; x < pixels; x++) {
124 val16 = ((sbuf[x] & 0x00F80000) >> 8) |
125 ((sbuf[x] & 0x0000FC00) >> 5) |
126 ((sbuf[x] & 0x000000F8) >> 3);
127 if (swab)
128 dbuf[x] = swab16(val16);
129 else
130 dbuf[x] = val16;
131 }
132 }
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148 void drm_fb_xrgb8888_to_rgb565(void *dst, void *vaddr,
149 struct drm_framebuffer *fb,
150 struct drm_rect *clip, bool swab)
151 {
152 size_t linepixels = clip->x2 - clip->x1;
153 size_t src_len = linepixels * sizeof(u32);
154 size_t dst_len = linepixels * sizeof(u16);
155 unsigned y, lines = clip->y2 - clip->y1;
156 void *sbuf;
157
158
159
160
161
162 sbuf = kmalloc(src_len, GFP_KERNEL);
163 if (!sbuf)
164 return;
165
166 vaddr += clip_offset(clip, fb->pitches[0], sizeof(u32));
167 for (y = 0; y < lines; y++) {
168 memcpy(sbuf, vaddr, src_len);
169 drm_fb_xrgb8888_to_rgb565_line(dst, sbuf, linepixels, swab);
170 vaddr += fb->pitches[0];
171 dst += dst_len;
172 }
173
174 kfree(sbuf);
175 }
176 EXPORT_SYMBOL(drm_fb_xrgb8888_to_rgb565);
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193 void drm_fb_xrgb8888_to_rgb565_dstclip(void __iomem *dst, unsigned int dst_pitch,
194 void *vaddr, struct drm_framebuffer *fb,
195 struct drm_rect *clip, bool swab)
196 {
197 size_t linepixels = clip->x2 - clip->x1;
198 size_t dst_len = linepixels * sizeof(u16);
199 unsigned y, lines = clip->y2 - clip->y1;
200 void *dbuf;
201
202 dbuf = kmalloc(dst_len, GFP_KERNEL);
203 if (!dbuf)
204 return;
205
206 vaddr += clip_offset(clip, fb->pitches[0], sizeof(u32));
207 dst += clip_offset(clip, dst_pitch, sizeof(u16));
208 for (y = 0; y < lines; y++) {
209 drm_fb_xrgb8888_to_rgb565_line(dbuf, vaddr, linepixels, swab);
210 memcpy_toio(dst, dbuf, dst_len);
211 vaddr += fb->pitches[0];
212 dst += dst_len;
213 }
214
215 kfree(dbuf);
216 }
217 EXPORT_SYMBOL(drm_fb_xrgb8888_to_rgb565_dstclip);
218
219 static void drm_fb_xrgb8888_to_rgb888_line(u8 *dbuf, u32 *sbuf,
220 unsigned int pixels)
221 {
222 unsigned int x;
223
224 for (x = 0; x < pixels; x++) {
225 *dbuf++ = (sbuf[x] & 0x000000FF) >> 0;
226 *dbuf++ = (sbuf[x] & 0x0000FF00) >> 8;
227 *dbuf++ = (sbuf[x] & 0x00FF0000) >> 16;
228 }
229 }
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245 void drm_fb_xrgb8888_to_rgb888_dstclip(void __iomem *dst, unsigned int dst_pitch,
246 void *vaddr, struct drm_framebuffer *fb,
247 struct drm_rect *clip)
248 {
249 size_t linepixels = clip->x2 - clip->x1;
250 size_t dst_len = linepixels * 3;
251 unsigned y, lines = clip->y2 - clip->y1;
252 void *dbuf;
253
254 dbuf = kmalloc(dst_len, GFP_KERNEL);
255 if (!dbuf)
256 return;
257
258 vaddr += clip_offset(clip, fb->pitches[0], sizeof(u32));
259 dst += clip_offset(clip, dst_pitch, sizeof(u16));
260 for (y = 0; y < lines; y++) {
261 drm_fb_xrgb8888_to_rgb888_line(dbuf, vaddr, linepixels);
262 memcpy_toio(dst, dbuf, dst_len);
263 vaddr += fb->pitches[0];
264 dst += dst_len;
265 }
266
267 kfree(dbuf);
268 }
269 EXPORT_SYMBOL(drm_fb_xrgb8888_to_rgb888_dstclip);
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287 void drm_fb_xrgb8888_to_gray8(u8 *dst, void *vaddr, struct drm_framebuffer *fb,
288 struct drm_rect *clip)
289 {
290 unsigned int len = (clip->x2 - clip->x1) * sizeof(u32);
291 unsigned int x, y;
292 void *buf;
293 u32 *src;
294
295 if (WARN_ON(fb->format->format != DRM_FORMAT_XRGB8888))
296 return;
297
298
299
300
301 buf = kmalloc(len, GFP_KERNEL);
302 if (!buf)
303 return;
304
305 for (y = clip->y1; y < clip->y2; y++) {
306 src = vaddr + (y * fb->pitches[0]);
307 src += clip->x1;
308 memcpy(buf, src, len);
309 src = buf;
310 for (x = clip->x1; x < clip->x2; x++) {
311 u8 r = (*src & 0x00ff0000) >> 16;
312 u8 g = (*src & 0x0000ff00) >> 8;
313 u8 b = *src & 0x000000ff;
314
315
316 *dst++ = (3 * r + 6 * g + b) / 10;
317 src++;
318 }
319 }
320
321 kfree(buf);
322 }
323 EXPORT_SYMBOL(drm_fb_xrgb8888_to_gray8);
324