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"
21static inline void write_dpr(struct lynx_accel *accel, int offset, u32 regValue)
22{
23 writel(regValue, accel->dprBase + offset);
24}
25
26static inline u32 read_dpr(struct lynx_accel *accel, int offset)
27{
28 return readl(accel->dprBase + offset);
29}
30
31static inline void write_dpPort(struct lynx_accel *accel, u32 data)
32{
33 writel(data, accel->dpPortBase);
34}
35
36void 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
76void 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
88int 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
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149int sm750_hw_copyarea(struct lynx_accel *accel,
150 unsigned int sBase, unsigned int sPitch,
151 unsigned int sx, unsigned int sy,
152 unsigned int dBase, unsigned int dPitch,
153 unsigned int Bpp, unsigned int dx, unsigned int dy,
154 unsigned int width, unsigned int height,
155 unsigned int rop2)
156{
157 unsigned int nDirection, de_ctrl;
158
159 nDirection = LEFT_TO_RIGHT;
160
161 de_ctrl = 0;
162
163
164 if (sBase == dBase && sPitch == dPitch) {
165
166 if (sy < dy) {
167
168
169
170
171
172
173
174
175
176
177 nDirection = BOTTOM_TO_TOP;
178 } else if (sy > dy) {
179
180
181
182
183
184
185
186
187
188
189 nDirection = TOP_TO_BOTTOM;
190 } else {
191
192
193 if (sx <= dx) {
194
195
196
197
198
199
200
201
202 nDirection = RIGHT_TO_LEFT;
203 } else {
204
205
206
207
208
209
210
211
212
213
214 nDirection = LEFT_TO_RIGHT;
215 }
216 }
217 }
218
219 if ((nDirection == BOTTOM_TO_TOP) || (nDirection == RIGHT_TO_LEFT)) {
220 sx += width - 1;
221 sy += height - 1;
222 dx += width - 1;
223 dy += height - 1;
224 }
225
226
227
228
229
230
231
232
233
234
235
236
237
238 write_dpr(accel, DE_WINDOW_SOURCE_BASE, sBase);
239
240
241
242
243
244
245 write_dpr(accel, DE_WINDOW_DESTINATION_BASE, dBase);
246
247
248
249
250
251
252 write_dpr(accel, DE_PITCH,
253 ((dPitch / Bpp << DE_PITCH_DESTINATION_SHIFT) &
254 DE_PITCH_DESTINATION_MASK) |
255 (sPitch / Bpp & DE_PITCH_SOURCE_MASK));
256
257
258
259
260
261
262 write_dpr(accel, DE_WINDOW_WIDTH,
263 ((dPitch / Bpp << DE_WINDOW_WIDTH_DST_SHIFT) &
264 DE_WINDOW_WIDTH_DST_MASK) |
265 (sPitch / Bpp & DE_WINDOW_WIDTH_SRC_MASK));
266
267 if (accel->de_wait() != 0)
268 return -1;
269
270 write_dpr(accel, DE_SOURCE,
271 ((sx << DE_SOURCE_X_K1_SHIFT) & DE_SOURCE_X_K1_MASK) |
272 (sy & DE_SOURCE_Y_K2_MASK));
273 write_dpr(accel, DE_DESTINATION,
274 ((dx << DE_DESTINATION_X_SHIFT) & DE_DESTINATION_X_MASK) |
275 (dy & DE_DESTINATION_Y_MASK));
276 write_dpr(accel, DE_DIMENSION,
277 ((width << DE_DIMENSION_X_SHIFT) & DE_DIMENSION_X_MASK) |
278 (height & DE_DIMENSION_Y_ET_MASK));
279
280 de_ctrl = (rop2 & DE_CONTROL_ROP_MASK) | DE_CONTROL_ROP_SELECT |
281 ((nDirection == RIGHT_TO_LEFT) ? DE_CONTROL_DIRECTION : 0) |
282 DE_CONTROL_COMMAND_BITBLT | DE_CONTROL_STATUS;
283 write_dpr(accel, DE_CONTROL, de_ctrl);
284
285 return 0;
286}
287
288static unsigned int deGetTransparency(struct lynx_accel *accel)
289{
290 unsigned int de_ctrl;
291
292 de_ctrl = read_dpr(accel, DE_CONTROL);
293
294 de_ctrl &= (DE_CONTROL_TRANSPARENCY_MATCH |
295 DE_CONTROL_TRANSPARENCY_SELECT | DE_CONTROL_TRANSPARENCY);
296
297 return de_ctrl;
298}
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319int sm750_hw_imageblit(struct lynx_accel *accel, const char *pSrcbuf,
320 u32 srcDelta, u32 startBit, u32 dBase, u32 dPitch,
321 u32 bytePerPixel, u32 dx, u32 dy, u32 width,
322 u32 height, u32 fColor, u32 bColor, u32 rop2)
323{
324 unsigned int ulBytesPerScan;
325 unsigned int ul4BytesPerScan;
326 unsigned int ulBytesRemain;
327 unsigned int de_ctrl = 0;
328 unsigned char ajRemain[4];
329 int i, j;
330
331 startBit &= 7;
332 ulBytesPerScan = (width + startBit + 7) / 8;
333 ul4BytesPerScan = ulBytesPerScan & ~3;
334 ulBytesRemain = ulBytesPerScan & 3;
335
336 if (accel->de_wait() != 0)
337 return -1;
338
339
340
341
342
343 write_dpr(accel, DE_WINDOW_SOURCE_BASE, 0);
344
345
346
347
348
349 write_dpr(accel, DE_WINDOW_DESTINATION_BASE, dBase);
350
351
352
353
354
355
356 write_dpr(accel, DE_PITCH,
357 ((dPitch / bytePerPixel << DE_PITCH_DESTINATION_SHIFT) &
358 DE_PITCH_DESTINATION_MASK) |
359 (dPitch / bytePerPixel & DE_PITCH_SOURCE_MASK));
360
361
362
363
364
365
366 write_dpr(accel, DE_WINDOW_WIDTH,
367 ((dPitch / bytePerPixel << DE_WINDOW_WIDTH_DST_SHIFT) &
368 DE_WINDOW_WIDTH_DST_MASK) |
369 (dPitch / bytePerPixel & DE_WINDOW_WIDTH_SRC_MASK));
370
371
372
373
374
375
376 write_dpr(accel, DE_SOURCE,
377 (startBit << DE_SOURCE_X_K1_SHIFT) &
378 DE_SOURCE_X_K1_MONO_MASK);
379
380 write_dpr(accel, DE_DESTINATION,
381 ((dx << DE_DESTINATION_X_SHIFT) & DE_DESTINATION_X_MASK) |
382 (dy & DE_DESTINATION_Y_MASK));
383
384 write_dpr(accel, DE_DIMENSION,
385 ((width << DE_DIMENSION_X_SHIFT) & DE_DIMENSION_X_MASK) |
386 (height & DE_DIMENSION_Y_ET_MASK));
387
388 write_dpr(accel, DE_FOREGROUND, fColor);
389 write_dpr(accel, DE_BACKGROUND, bColor);
390
391 de_ctrl = (rop2 & DE_CONTROL_ROP_MASK) |
392 DE_CONTROL_ROP_SELECT | DE_CONTROL_COMMAND_HOST_WRITE |
393 DE_CONTROL_HOST | DE_CONTROL_STATUS;
394
395 write_dpr(accel, DE_CONTROL, de_ctrl | deGetTransparency(accel));
396
397
398 for (i = 0; i < height; i++) {
399
400 for (j = 0; j < (ul4BytesPerScan / 4); j++)
401 write_dpPort(accel, *(unsigned int *)(pSrcbuf + (j * 4)));
402
403 if (ulBytesRemain) {
404 memcpy(ajRemain, pSrcbuf + ul4BytesPerScan,
405 ulBytesRemain);
406 write_dpPort(accel, *(unsigned int *)ajRemain);
407 }
408
409 pSrcbuf += srcDelta;
410 }
411
412 return 0;
413}
414
415