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