This source file includes following definitions.
- write_dpr
- read_dpr
- write_dpPort
- sm750_hw_de_init
- sm750_hw_set2dformat
- sm750_hw_fillrect
- sm750_hw_copyarea
- deGetTransparency
- sm750_hw_imageblit
1
2 #include <linux/module.h>
3 #include <linux/kernel.h>
4 #include <linux/errno.h>
5 #include <linux/string.h>
6 #include <linux/mm.h>
7 #include <linux/slab.h>
8 #include <linux/delay.h>
9 #include <linux/fb.h>
10 #include <linux/ioport.h>
11 #include <linux/init.h>
12 #include <linux/pci.h>
13 #include <linux/vmalloc.h>
14 #include <linux/pagemap.h>
15 #include <linux/console.h>
16 #include <linux/platform_device.h>
17 #include <linux/screen_info.h>
18
19 #include "sm750.h"
20 #include "sm750_accel.h"
21 static inline void write_dpr(struct lynx_accel *accel, int offset, u32 regValue)
22 {
23 writel(regValue, accel->dprBase + offset);
24 }
25
26 static inline u32 read_dpr(struct lynx_accel *accel, int offset)
27 {
28 return readl(accel->dprBase + offset);
29 }
30
31 static inline void write_dpPort(struct lynx_accel *accel, u32 data)
32 {
33 writel(data, accel->dpPortBase);
34 }
35
36 void sm750_hw_de_init(struct lynx_accel *accel)
37 {
38
39 u32 reg, clr;
40
41 write_dpr(accel, DE_MASKS, 0xFFFFFFFF);
42
43
44 reg = 0x3;
45
46 clr = DE_STRETCH_FORMAT_PATTERN_XY |
47 DE_STRETCH_FORMAT_PATTERN_Y_MASK |
48 DE_STRETCH_FORMAT_PATTERN_X_MASK |
49 DE_STRETCH_FORMAT_ADDRESSING_MASK |
50 DE_STRETCH_FORMAT_SOURCE_HEIGHT_MASK;
51
52
53 write_dpr(accel, DE_STRETCH_FORMAT,
54 (read_dpr(accel, DE_STRETCH_FORMAT) & ~clr) | reg);
55
56
57 write_dpr(accel, DE_CLIP_TL, 0);
58 write_dpr(accel, DE_CLIP_BR, 0);
59
60 write_dpr(accel, DE_COLOR_COMPARE_MASK, 0);
61 write_dpr(accel, DE_COLOR_COMPARE, 0);
62
63 clr = DE_CONTROL_TRANSPARENCY | DE_CONTROL_TRANSPARENCY_MATCH |
64 DE_CONTROL_TRANSPARENCY_SELECT;
65
66
67 write_dpr(accel, DE_CONTROL, read_dpr(accel, DE_CONTROL) & ~clr);
68 }
69
70
71
72
73
74
75
76 void sm750_hw_set2dformat(struct lynx_accel *accel, int fmt)
77 {
78 u32 reg;
79
80
81 reg = read_dpr(accel, DE_STRETCH_FORMAT);
82 reg &= ~DE_STRETCH_FORMAT_PIXEL_FORMAT_MASK;
83 reg |= ((fmt << DE_STRETCH_FORMAT_PIXEL_FORMAT_SHIFT) &
84 DE_STRETCH_FORMAT_PIXEL_FORMAT_MASK);
85 write_dpr(accel, DE_STRETCH_FORMAT, reg);
86 }
87
88 int sm750_hw_fillrect(struct lynx_accel *accel,
89 u32 base, u32 pitch, u32 Bpp,
90 u32 x, u32 y, u32 width, u32 height,
91 u32 color, u32 rop)
92 {
93 u32 deCtrl;
94
95 if (accel->de_wait() != 0) {
96
97
98
99
100 pr_debug("De engine always busy\n");
101 return -1;
102 }
103
104 write_dpr(accel, DE_WINDOW_DESTINATION_BASE, base);
105 write_dpr(accel, DE_PITCH,
106 ((pitch / Bpp << DE_PITCH_DESTINATION_SHIFT) &
107 DE_PITCH_DESTINATION_MASK) |
108 (pitch / Bpp & DE_PITCH_SOURCE_MASK));
109
110 write_dpr(accel, DE_WINDOW_WIDTH,
111 ((pitch / Bpp << DE_WINDOW_WIDTH_DST_SHIFT) &
112 DE_WINDOW_WIDTH_DST_MASK) |
113 (pitch / Bpp & DE_WINDOW_WIDTH_SRC_MASK));
114
115 write_dpr(accel, DE_FOREGROUND, color);
116
117 write_dpr(accel, DE_DESTINATION,
118 ((x << DE_DESTINATION_X_SHIFT) & DE_DESTINATION_X_MASK) |
119 (y & DE_DESTINATION_Y_MASK));
120
121 write_dpr(accel, DE_DIMENSION,
122 ((width << DE_DIMENSION_X_SHIFT) & DE_DIMENSION_X_MASK) |
123 (height & DE_DIMENSION_Y_ET_MASK));
124
125 deCtrl = DE_CONTROL_STATUS | DE_CONTROL_LAST_PIXEL |
126 DE_CONTROL_COMMAND_RECTANGLE_FILL | DE_CONTROL_ROP_SELECT |
127 (rop & DE_CONTROL_ROP_MASK);
128
129 write_dpr(accel, DE_CONTROL, deCtrl);
130 return 0;
131 }
132
133 int sm750_hw_copyarea(
134 struct lynx_accel *accel,
135 unsigned int sBase,
136 unsigned int sPitch,
137 unsigned int sx,
138 unsigned int sy,
139 unsigned int dBase,
140 unsigned int dPitch,
141 unsigned int Bpp,
142 unsigned int dx,
143 unsigned int dy,
144 unsigned int width,
145 unsigned int height,
146 unsigned int rop2)
147 {
148 unsigned int nDirection, de_ctrl;
149
150 nDirection = LEFT_TO_RIGHT;
151
152 de_ctrl = 0;
153
154
155 if (sBase == dBase && sPitch == dPitch) {
156
157 if (sy < dy) {
158
159
160
161
162
163
164
165
166
167
168 nDirection = BOTTOM_TO_TOP;
169 } else if (sy > dy) {
170
171
172
173
174
175
176
177
178
179
180 nDirection = TOP_TO_BOTTOM;
181 } else {
182
183
184 if (sx <= dx) {
185
186
187
188
189
190
191
192
193 nDirection = RIGHT_TO_LEFT;
194 } else {
195
196
197
198
199
200
201
202
203
204
205 nDirection = LEFT_TO_RIGHT;
206 }
207 }
208 }
209
210 if ((nDirection == BOTTOM_TO_TOP) || (nDirection == RIGHT_TO_LEFT)) {
211 sx += width - 1;
212 sy += height - 1;
213 dx += width - 1;
214 dy += height - 1;
215 }
216
217
218
219
220
221
222
223
224
225
226
227
228
229 write_dpr(accel, DE_WINDOW_SOURCE_BASE, sBase);
230
231
232
233
234
235
236 write_dpr(accel, DE_WINDOW_DESTINATION_BASE, dBase);
237
238
239
240
241
242
243 write_dpr(accel, DE_PITCH,
244 ((dPitch / Bpp << DE_PITCH_DESTINATION_SHIFT) &
245 DE_PITCH_DESTINATION_MASK) |
246 (sPitch / Bpp & DE_PITCH_SOURCE_MASK));
247
248
249
250
251
252
253 write_dpr(accel, DE_WINDOW_WIDTH,
254 ((dPitch / Bpp << DE_WINDOW_WIDTH_DST_SHIFT) &
255 DE_WINDOW_WIDTH_DST_MASK) |
256 (sPitch / Bpp & DE_WINDOW_WIDTH_SRC_MASK));
257
258 if (accel->de_wait() != 0)
259 return -1;
260
261 write_dpr(accel, DE_SOURCE,
262 ((sx << DE_SOURCE_X_K1_SHIFT) & DE_SOURCE_X_K1_MASK) |
263 (sy & DE_SOURCE_Y_K2_MASK));
264 write_dpr(accel, DE_DESTINATION,
265 ((dx << DE_DESTINATION_X_SHIFT) & DE_DESTINATION_X_MASK) |
266 (dy & DE_DESTINATION_Y_MASK));
267 write_dpr(accel, DE_DIMENSION,
268 ((width << DE_DIMENSION_X_SHIFT) & DE_DIMENSION_X_MASK) |
269 (height & DE_DIMENSION_Y_ET_MASK));
270
271 de_ctrl = (rop2 & DE_CONTROL_ROP_MASK) | DE_CONTROL_ROP_SELECT |
272 ((nDirection == RIGHT_TO_LEFT) ? DE_CONTROL_DIRECTION : 0) |
273 DE_CONTROL_COMMAND_BITBLT | DE_CONTROL_STATUS;
274 write_dpr(accel, DE_CONTROL, de_ctrl);
275
276 return 0;
277 }
278
279 static unsigned int deGetTransparency(struct lynx_accel *accel)
280 {
281 unsigned int de_ctrl;
282
283 de_ctrl = read_dpr(accel, DE_CONTROL);
284
285 de_ctrl &= (DE_CONTROL_TRANSPARENCY_MATCH |
286 DE_CONTROL_TRANSPARENCY_SELECT | DE_CONTROL_TRANSPARENCY);
287
288 return de_ctrl;
289 }
290
291 int sm750_hw_imageblit(struct lynx_accel *accel,
292 const char *pSrcbuf,
293 u32 srcDelta,
294 u32 startBit,
295 u32 dBase,
296 u32 dPitch,
297 u32 bytePerPixel,
298 u32 dx,
299 u32 dy,
300 u32 width,
301 u32 height,
302 u32 fColor,
303 u32 bColor,
304 u32 rop2)
305 {
306 unsigned int ulBytesPerScan;
307 unsigned int ul4BytesPerScan;
308 unsigned int ulBytesRemain;
309 unsigned int de_ctrl = 0;
310 unsigned char ajRemain[4];
311 int i, j;
312
313 startBit &= 7;
314 ulBytesPerScan = (width + startBit + 7) / 8;
315 ul4BytesPerScan = ulBytesPerScan & ~3;
316 ulBytesRemain = ulBytesPerScan & 3;
317
318 if (accel->de_wait() != 0)
319 return -1;
320
321
322
323
324
325 write_dpr(accel, DE_WINDOW_SOURCE_BASE, 0);
326
327
328
329
330
331 write_dpr(accel, DE_WINDOW_DESTINATION_BASE, dBase);
332
333
334
335
336
337
338 write_dpr(accel, DE_PITCH,
339 ((dPitch / bytePerPixel << DE_PITCH_DESTINATION_SHIFT) &
340 DE_PITCH_DESTINATION_MASK) |
341 (dPitch / bytePerPixel & DE_PITCH_SOURCE_MASK));
342
343
344
345
346
347
348 write_dpr(accel, DE_WINDOW_WIDTH,
349 ((dPitch / bytePerPixel << DE_WINDOW_WIDTH_DST_SHIFT) &
350 DE_WINDOW_WIDTH_DST_MASK) |
351 (dPitch / bytePerPixel & DE_WINDOW_WIDTH_SRC_MASK));
352
353
354
355
356
357
358 write_dpr(accel, DE_SOURCE,
359 (startBit << DE_SOURCE_X_K1_SHIFT) &
360 DE_SOURCE_X_K1_MONO_MASK);
361
362 write_dpr(accel, DE_DESTINATION,
363 ((dx << DE_DESTINATION_X_SHIFT) & DE_DESTINATION_X_MASK) |
364 (dy & DE_DESTINATION_Y_MASK));
365
366 write_dpr(accel, DE_DIMENSION,
367 ((width << DE_DIMENSION_X_SHIFT) & DE_DIMENSION_X_MASK) |
368 (height & DE_DIMENSION_Y_ET_MASK));
369
370 write_dpr(accel, DE_FOREGROUND, fColor);
371 write_dpr(accel, DE_BACKGROUND, bColor);
372
373 de_ctrl = (rop2 & DE_CONTROL_ROP_MASK) |
374 DE_CONTROL_ROP_SELECT | DE_CONTROL_COMMAND_HOST_WRITE |
375 DE_CONTROL_HOST | DE_CONTROL_STATUS;
376
377 write_dpr(accel, DE_CONTROL, de_ctrl | deGetTransparency(accel));
378
379
380 for (i = 0; i < height; i++) {
381
382 for (j = 0; j < (ul4BytesPerScan / 4); j++)
383 write_dpPort(accel, *(unsigned int *)(pSrcbuf + (j * 4)));
384
385 if (ulBytesRemain) {
386 memcpy(ajRemain, pSrcbuf + ul4BytesPerScan,
387 ulBytesRemain);
388 write_dpPort(accel, *(unsigned int *)ajRemain);
389 }
390
391 pSrcbuf += srcDelta;
392 }
393
394 return 0;
395 }
396