1
2
3
4
5
6
7
8
9
10
11
12
13
14
15#include <linux/bitrev.h>
16#include <linux/compiler.h>
17#include <linux/delay.h>
18#include <linux/device.h>
19#include <linux/errno.h>
20#include <linux/fb.h>
21#include <linux/init.h>
22#include <linux/ioport.h>
23#include <linux/kernel.h>
24#include <linux/mm.h>
25#include <linux/module.h>
26#include <linux/pci.h>
27#include <linux/selection.h>
28#include <linux/string.h>
29#include <linux/tc.h>
30
31#include <asm/io.h>
32
33#include <video/tgafb.h>
34
35#ifdef CONFIG_PCI
36#define TGA_BUS_PCI(dev) (dev->bus == &pci_bus_type)
37#else
38#define TGA_BUS_PCI(dev) 0
39#endif
40
41#ifdef CONFIG_TC
42#define TGA_BUS_TC(dev) (dev->bus == &tc_bus_type)
43#else
44#define TGA_BUS_TC(dev) 0
45#endif
46
47
48
49
50
51static int tgafb_check_var(struct fb_var_screeninfo *, struct fb_info *);
52static int tgafb_set_par(struct fb_info *);
53static void tgafb_set_pll(struct tga_par *, int);
54static int tgafb_setcolreg(unsigned, unsigned, unsigned, unsigned,
55 unsigned, struct fb_info *);
56static int tgafb_blank(int, struct fb_info *);
57static void tgafb_init_fix(struct fb_info *);
58
59static void tgafb_imageblit(struct fb_info *, const struct fb_image *);
60static void tgafb_fillrect(struct fb_info *, const struct fb_fillrect *);
61static void tgafb_copyarea(struct fb_info *, const struct fb_copyarea *);
62static int tgafb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info);
63
64static int tgafb_register(struct device *dev);
65static void tgafb_unregister(struct device *dev);
66
67static const char *mode_option;
68static const char *mode_option_pci = "640x480@60";
69static const char *mode_option_tc = "1280x1024@72";
70
71
72static struct pci_driver tgafb_pci_driver;
73static struct tc_driver tgafb_tc_driver;
74
75
76
77
78
79static struct fb_ops tgafb_ops = {
80 .owner = THIS_MODULE,
81 .fb_check_var = tgafb_check_var,
82 .fb_set_par = tgafb_set_par,
83 .fb_setcolreg = tgafb_setcolreg,
84 .fb_blank = tgafb_blank,
85 .fb_pan_display = tgafb_pan_display,
86 .fb_fillrect = tgafb_fillrect,
87 .fb_copyarea = tgafb_copyarea,
88 .fb_imageblit = tgafb_imageblit,
89};
90
91
92#ifdef CONFIG_PCI
93
94
95
96static int tgafb_pci_register(struct pci_dev *, const struct pci_device_id *);
97static void tgafb_pci_unregister(struct pci_dev *);
98
99static struct pci_device_id const tgafb_pci_table[] = {
100 { PCI_DEVICE(PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_TGA) },
101 { }
102};
103MODULE_DEVICE_TABLE(pci, tgafb_pci_table);
104
105static struct pci_driver tgafb_pci_driver = {
106 .name = "tgafb",
107 .id_table = tgafb_pci_table,
108 .probe = tgafb_pci_register,
109 .remove = tgafb_pci_unregister,
110};
111
112static int tgafb_pci_register(struct pci_dev *pdev,
113 const struct pci_device_id *ent)
114{
115 return tgafb_register(&pdev->dev);
116}
117
118static void tgafb_pci_unregister(struct pci_dev *pdev)
119{
120 tgafb_unregister(&pdev->dev);
121}
122#endif
123
124#ifdef CONFIG_TC
125
126
127
128static int tgafb_tc_register(struct device *);
129static int tgafb_tc_unregister(struct device *);
130
131static struct tc_device_id const tgafb_tc_table[] = {
132 { "DEC ", "PMAGD-AA" },
133 { "DEC ", "PMAGD " },
134 { }
135};
136MODULE_DEVICE_TABLE(tc, tgafb_tc_table);
137
138static struct tc_driver tgafb_tc_driver = {
139 .id_table = tgafb_tc_table,
140 .driver = {
141 .name = "tgafb",
142 .bus = &tc_bus_type,
143 .probe = tgafb_tc_register,
144 .remove = tgafb_tc_unregister,
145 },
146};
147
148static int tgafb_tc_register(struct device *dev)
149{
150 int status = tgafb_register(dev);
151 if (!status)
152 get_device(dev);
153 return status;
154}
155
156static int tgafb_tc_unregister(struct device *dev)
157{
158 put_device(dev);
159 tgafb_unregister(dev);
160 return 0;
161}
162#endif
163
164
165
166
167
168
169
170static int
171tgafb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
172{
173 struct tga_par *par = (struct tga_par *)info->par;
174
175 if (par->tga_type == TGA_TYPE_8PLANE) {
176 if (var->bits_per_pixel != 8)
177 return -EINVAL;
178 } else {
179 if (var->bits_per_pixel != 32)
180 return -EINVAL;
181 }
182 var->red.length = var->green.length = var->blue.length = 8;
183 if (var->bits_per_pixel == 32) {
184 var->red.offset = 16;
185 var->green.offset = 8;
186 var->blue.offset = 0;
187 }
188
189 if (var->xres_virtual != var->xres || var->yres_virtual != var->yres)
190 return -EINVAL;
191 if (var->nonstd)
192 return -EINVAL;
193 if (1000000000 / var->pixclock > TGA_PLL_MAX_FREQ)
194 return -EINVAL;
195 if ((var->vmode & FB_VMODE_MASK) != FB_VMODE_NONINTERLACED)
196 return -EINVAL;
197
198
199
200 if (var->xres * (par->tga_type == TGA_TYPE_8PLANE ? 1 : 4) % 64)
201 return -EINVAL;
202
203 return 0;
204}
205
206
207
208
209
210static int
211tgafb_set_par(struct fb_info *info)
212{
213 static unsigned int const deep_presets[4] = {
214 0x00004000,
215 0x0000440d,
216 0xffffffff,
217 0x0000441d
218 };
219 static unsigned int const rasterop_presets[4] = {
220 0x00000003,
221 0x00000303,
222 0xffffffff,
223 0x00000303
224 };
225 static unsigned int const mode_presets[4] = {
226 0x00000000,
227 0x00000300,
228 0xffffffff,
229 0x00000300
230 };
231 static unsigned int const base_addr_presets[4] = {
232 0x00000000,
233 0x00000001,
234 0xffffffff,
235 0x00000001
236 };
237
238 struct tga_par *par = (struct tga_par *) info->par;
239 int tga_bus_pci = TGA_BUS_PCI(par->dev);
240 int tga_bus_tc = TGA_BUS_TC(par->dev);
241 u32 htimings, vtimings, pll_freq;
242 u8 tga_type;
243 int i;
244
245
246 htimings = (((info->var.xres/4) & TGA_HORIZ_ACT_LSB)
247 | (((info->var.xres/4) & 0x600 << 19) & TGA_HORIZ_ACT_MSB));
248 vtimings = (info->var.yres & TGA_VERT_ACTIVE);
249 htimings |= ((info->var.right_margin/4) << 9) & TGA_HORIZ_FP;
250 vtimings |= (info->var.lower_margin << 11) & TGA_VERT_FP;
251 htimings |= ((info->var.hsync_len/4) << 14) & TGA_HORIZ_SYNC;
252 vtimings |= (info->var.vsync_len << 16) & TGA_VERT_SYNC;
253 htimings |= ((info->var.left_margin/4) << 21) & TGA_HORIZ_BP;
254 vtimings |= (info->var.upper_margin << 22) & TGA_VERT_BP;
255
256 if (info->var.sync & FB_SYNC_HOR_HIGH_ACT)
257 htimings |= TGA_HORIZ_POLARITY;
258 if (info->var.sync & FB_SYNC_VERT_HIGH_ACT)
259 vtimings |= TGA_VERT_POLARITY;
260
261 par->htimings = htimings;
262 par->vtimings = vtimings;
263
264 par->sync_on_green = !!(info->var.sync & FB_SYNC_ON_GREEN);
265
266
267 par->xres = info->var.xres;
268 par->yres = info->var.yres;
269 par->pll_freq = pll_freq = 1000000000 / info->var.pixclock;
270 par->bits_per_pixel = info->var.bits_per_pixel;
271
272 tga_type = par->tga_type;
273
274
275 TGA_WRITE_REG(par, TGA_VALID_VIDEO | TGA_VALID_BLANK, TGA_VALID_REG);
276
277
278 while (TGA_READ_REG(par, TGA_CMD_STAT_REG) & 1)
279 continue;
280 mb();
281 TGA_WRITE_REG(par, deep_presets[tga_type] |
282 (par->sync_on_green ? 0x0 : 0x00010000),
283 TGA_DEEP_REG);
284 while (TGA_READ_REG(par, TGA_CMD_STAT_REG) & 1)
285 continue;
286 mb();
287
288
289 TGA_WRITE_REG(par, rasterop_presets[tga_type], TGA_RASTEROP_REG);
290 TGA_WRITE_REG(par, mode_presets[tga_type], TGA_MODE_REG);
291 TGA_WRITE_REG(par, base_addr_presets[tga_type], TGA_BASE_ADDR_REG);
292
293
294 tgafb_set_pll(par, pll_freq);
295
296
297 TGA_WRITE_REG(par, 0xffffffff, TGA_PLANEMASK_REG);
298 TGA_WRITE_REG(par, 0xffffffff, TGA_PIXELMASK_REG);
299
300
301 TGA_WRITE_REG(par, htimings, TGA_HORIZ_REG);
302 TGA_WRITE_REG(par, vtimings, TGA_VERT_REG);
303
304
305 if (tga_type == TGA_TYPE_8PLANE && tga_bus_pci) {
306
307
308 BT485_WRITE(par, 0xa2 | (par->sync_on_green ? 0x8 : 0x0),
309 BT485_CMD_0);
310 BT485_WRITE(par, 0x01, BT485_ADDR_PAL_WRITE);
311 BT485_WRITE(par, 0x14, BT485_CMD_3);
312 BT485_WRITE(par, 0x40, BT485_CMD_1);
313 BT485_WRITE(par, 0x20, BT485_CMD_2);
314 BT485_WRITE(par, 0xff, BT485_PIXEL_MASK);
315
316
317 BT485_WRITE(par, 0x00, BT485_ADDR_PAL_WRITE);
318 TGA_WRITE_REG(par, BT485_DATA_PAL, TGA_RAMDAC_SETUP_REG);
319
320 for (i = 0; i < 256 * 3; i += 4) {
321 TGA_WRITE_REG(par, 0x55 | (BT485_DATA_PAL << 8),
322 TGA_RAMDAC_REG);
323 TGA_WRITE_REG(par, 0x00 | (BT485_DATA_PAL << 8),
324 TGA_RAMDAC_REG);
325 TGA_WRITE_REG(par, 0x00 | (BT485_DATA_PAL << 8),
326 TGA_RAMDAC_REG);
327 TGA_WRITE_REG(par, 0x00 | (BT485_DATA_PAL << 8),
328 TGA_RAMDAC_REG);
329 }
330
331 } else if (tga_type == TGA_TYPE_8PLANE && tga_bus_tc) {
332
333
334 BT459_WRITE(par, BT459_REG_ACC, BT459_CMD_REG_0, 0x40);
335 BT459_WRITE(par, BT459_REG_ACC, BT459_CMD_REG_1, 0x00);
336 BT459_WRITE(par, BT459_REG_ACC, BT459_CMD_REG_2,
337 (par->sync_on_green ? 0xc0 : 0x40));
338
339 BT459_WRITE(par, BT459_REG_ACC, BT459_CUR_CMD_REG, 0x00);
340
341
342 BT459_LOAD_ADDR(par, 0x0000);
343 TGA_WRITE_REG(par, BT459_PALETTE << 2, TGA_RAMDAC_SETUP_REG);
344
345 for (i = 0; i < 256 * 3; i += 4) {
346 TGA_WRITE_REG(par, 0x55, TGA_RAMDAC_REG);
347 TGA_WRITE_REG(par, 0x00, TGA_RAMDAC_REG);
348 TGA_WRITE_REG(par, 0x00, TGA_RAMDAC_REG);
349 TGA_WRITE_REG(par, 0x00, TGA_RAMDAC_REG);
350 }
351
352 } else {
353
354
355 BT463_WRITE(par, BT463_REG_ACC, BT463_CMD_REG_0, 0x40);
356 BT463_WRITE(par, BT463_REG_ACC, BT463_CMD_REG_1, 0x08);
357 BT463_WRITE(par, BT463_REG_ACC, BT463_CMD_REG_2,
358 (par->sync_on_green ? 0xc0 : 0x40));
359
360 BT463_WRITE(par, BT463_REG_ACC, BT463_READ_MASK_0, 0xff);
361 BT463_WRITE(par, BT463_REG_ACC, BT463_READ_MASK_1, 0xff);
362 BT463_WRITE(par, BT463_REG_ACC, BT463_READ_MASK_2, 0xff);
363 BT463_WRITE(par, BT463_REG_ACC, BT463_READ_MASK_3, 0x0f);
364
365 BT463_WRITE(par, BT463_REG_ACC, BT463_BLINK_MASK_0, 0x00);
366 BT463_WRITE(par, BT463_REG_ACC, BT463_BLINK_MASK_1, 0x00);
367 BT463_WRITE(par, BT463_REG_ACC, BT463_BLINK_MASK_2, 0x00);
368 BT463_WRITE(par, BT463_REG_ACC, BT463_BLINK_MASK_3, 0x00);
369
370
371 BT463_LOAD_ADDR(par, 0x0000);
372 TGA_WRITE_REG(par, BT463_PALETTE << 2, TGA_RAMDAC_SETUP_REG);
373
374#ifdef CONFIG_HW_CONSOLE
375 for (i = 0; i < 16; i++) {
376 int j = color_table[i];
377
378 TGA_WRITE_REG(par, default_red[j], TGA_RAMDAC_REG);
379 TGA_WRITE_REG(par, default_grn[j], TGA_RAMDAC_REG);
380 TGA_WRITE_REG(par, default_blu[j], TGA_RAMDAC_REG);
381 }
382 for (i = 0; i < 512 * 3; i += 4) {
383#else
384 for (i = 0; i < 528 * 3; i += 4) {
385#endif
386 TGA_WRITE_REG(par, 0x55, TGA_RAMDAC_REG);
387 TGA_WRITE_REG(par, 0x00, TGA_RAMDAC_REG);
388 TGA_WRITE_REG(par, 0x00, TGA_RAMDAC_REG);
389 TGA_WRITE_REG(par, 0x00, TGA_RAMDAC_REG);
390 }
391
392
393 while (!(TGA_READ_REG(par, TGA_INTR_STAT_REG) & 0x01))
394 continue;
395 TGA_WRITE_REG(par, 0x01, TGA_INTR_STAT_REG);
396 mb();
397 while (!(TGA_READ_REG(par, TGA_INTR_STAT_REG) & 0x01))
398 continue;
399 TGA_WRITE_REG(par, 0x01, TGA_INTR_STAT_REG);
400
401 BT463_LOAD_ADDR(par, BT463_WINDOW_TYPE_BASE);
402 TGA_WRITE_REG(par, BT463_REG_ACC << 2, TGA_RAMDAC_SETUP_REG);
403
404 for (i = 0; i < 16; i++) {
405 TGA_WRITE_REG(par, 0x00, TGA_RAMDAC_REG);
406 TGA_WRITE_REG(par, 0x01, TGA_RAMDAC_REG);
407 TGA_WRITE_REG(par, 0x00, TGA_RAMDAC_REG);
408 }
409
410 }
411
412
413 TGA_WRITE_REG(par, TGA_VALID_VIDEO, TGA_VALID_REG);
414
415 return 0;
416}
417
418#define DIFFCHECK(X) \
419do { \
420 if (m <= 0x3f) { \
421 int delta = f - (TGA_PLL_BASE_FREQ * (X)) / (r << shift); \
422 if (delta < 0) \
423 delta = -delta; \
424 if (delta < min_diff) \
425 min_diff = delta, vm = m, va = a, vr = r; \
426 } \
427} while (0)
428
429static void
430tgafb_set_pll(struct tga_par *par, int f)
431{
432 int n, shift, base, min_diff, target;
433 int r,a,m,vm = 34, va = 1, vr = 30;
434
435 for (r = 0 ; r < 12 ; r++)
436 TGA_WRITE_REG(par, !r, TGA_CLOCK_REG);
437
438 if (f > TGA_PLL_MAX_FREQ)
439 f = TGA_PLL_MAX_FREQ;
440
441 if (f >= TGA_PLL_MAX_FREQ / 2)
442 shift = 0;
443 else if (f >= TGA_PLL_MAX_FREQ / 4)
444 shift = 1;
445 else
446 shift = 2;
447
448 TGA_WRITE_REG(par, shift & 1, TGA_CLOCK_REG);
449 TGA_WRITE_REG(par, shift >> 1, TGA_CLOCK_REG);
450
451 for (r = 0 ; r < 10 ; r++)
452 TGA_WRITE_REG(par, 0, TGA_CLOCK_REG);
453
454 if (f <= 120000) {
455 TGA_WRITE_REG(par, 0, TGA_CLOCK_REG);
456 TGA_WRITE_REG(par, 0, TGA_CLOCK_REG);
457 }
458 else if (f <= 200000) {
459 TGA_WRITE_REG(par, 1, TGA_CLOCK_REG);
460 TGA_WRITE_REG(par, 0, TGA_CLOCK_REG);
461 }
462 else {
463 TGA_WRITE_REG(par, 0, TGA_CLOCK_REG);
464 TGA_WRITE_REG(par, 1, TGA_CLOCK_REG);
465 }
466
467 TGA_WRITE_REG(par, 1, TGA_CLOCK_REG);
468 TGA_WRITE_REG(par, 0, TGA_CLOCK_REG);
469 TGA_WRITE_REG(par, 0, TGA_CLOCK_REG);
470 TGA_WRITE_REG(par, 1, TGA_CLOCK_REG);
471 TGA_WRITE_REG(par, 0, TGA_CLOCK_REG);
472 TGA_WRITE_REG(par, 1, TGA_CLOCK_REG);
473
474 target = (f << shift) / TGA_PLL_BASE_FREQ;
475 min_diff = TGA_PLL_MAX_FREQ;
476
477 r = 7 / target;
478 if (!r) r = 1;
479
480 base = target * r;
481 while (base < 449) {
482 for (n = base < 7 ? 7 : base; n < base + target && n < 449; n++) {
483 m = ((n + 3) / 7) - 1;
484 a = 0;
485 DIFFCHECK((m + 1) * 7);
486 m++;
487 DIFFCHECK((m + 1) * 7);
488 m = (n / 6) - 1;
489 if ((a = n % 6))
490 DIFFCHECK(n);
491 }
492 r++;
493 base += target;
494 }
495
496 vr--;
497
498 for (r = 0; r < 8; r++)
499 TGA_WRITE_REG(par, (vm >> r) & 1, TGA_CLOCK_REG);
500 for (r = 0; r < 8 ; r++)
501 TGA_WRITE_REG(par, (va >> r) & 1, TGA_CLOCK_REG);
502 for (r = 0; r < 7 ; r++)
503 TGA_WRITE_REG(par, (vr >> r) & 1, TGA_CLOCK_REG);
504 TGA_WRITE_REG(par, ((vr >> 7) & 1)|2, TGA_CLOCK_REG);
505}
506
507
508
509
510
511
512
513
514
515
516
517static int
518tgafb_setcolreg(unsigned regno, unsigned red, unsigned green, unsigned blue,
519 unsigned transp, struct fb_info *info)
520{
521 struct tga_par *par = (struct tga_par *) info->par;
522 int tga_bus_pci = TGA_BUS_PCI(par->dev);
523 int tga_bus_tc = TGA_BUS_TC(par->dev);
524
525 if (regno > 255)
526 return 1;
527 red >>= 8;
528 green >>= 8;
529 blue >>= 8;
530
531 if (par->tga_type == TGA_TYPE_8PLANE && tga_bus_pci) {
532 BT485_WRITE(par, regno, BT485_ADDR_PAL_WRITE);
533 TGA_WRITE_REG(par, BT485_DATA_PAL, TGA_RAMDAC_SETUP_REG);
534 TGA_WRITE_REG(par, red|(BT485_DATA_PAL<<8),TGA_RAMDAC_REG);
535 TGA_WRITE_REG(par, green|(BT485_DATA_PAL<<8),TGA_RAMDAC_REG);
536 TGA_WRITE_REG(par, blue|(BT485_DATA_PAL<<8),TGA_RAMDAC_REG);
537 } else if (par->tga_type == TGA_TYPE_8PLANE && tga_bus_tc) {
538 BT459_LOAD_ADDR(par, regno);
539 TGA_WRITE_REG(par, BT459_PALETTE << 2, TGA_RAMDAC_SETUP_REG);
540 TGA_WRITE_REG(par, red, TGA_RAMDAC_REG);
541 TGA_WRITE_REG(par, green, TGA_RAMDAC_REG);
542 TGA_WRITE_REG(par, blue, TGA_RAMDAC_REG);
543 } else {
544 if (regno < 16) {
545 u32 value = (regno << 16) | (regno << 8) | regno;
546 ((u32 *)info->pseudo_palette)[regno] = value;
547 }
548 BT463_LOAD_ADDR(par, regno);
549 TGA_WRITE_REG(par, BT463_PALETTE << 2, TGA_RAMDAC_SETUP_REG);
550 TGA_WRITE_REG(par, red, TGA_RAMDAC_REG);
551 TGA_WRITE_REG(par, green, TGA_RAMDAC_REG);
552 TGA_WRITE_REG(par, blue, TGA_RAMDAC_REG);
553 }
554
555 return 0;
556}
557
558
559
560
561
562
563
564static int
565tgafb_blank(int blank, struct fb_info *info)
566{
567 struct tga_par *par = (struct tga_par *) info->par;
568 u32 vhcr, vvcr, vvvr;
569 unsigned long flags;
570
571 local_irq_save(flags);
572
573 vhcr = TGA_READ_REG(par, TGA_HORIZ_REG);
574 vvcr = TGA_READ_REG(par, TGA_VERT_REG);
575 vvvr = TGA_READ_REG(par, TGA_VALID_REG);
576 vvvr &= ~(TGA_VALID_VIDEO | TGA_VALID_BLANK);
577
578 switch (blank) {
579 case FB_BLANK_UNBLANK:
580 if (par->vesa_blanked) {
581 TGA_WRITE_REG(par, vhcr & 0xbfffffff, TGA_HORIZ_REG);
582 TGA_WRITE_REG(par, vvcr & 0xbfffffff, TGA_VERT_REG);
583 par->vesa_blanked = 0;
584 }
585 TGA_WRITE_REG(par, vvvr | TGA_VALID_VIDEO, TGA_VALID_REG);
586 break;
587
588 case FB_BLANK_NORMAL:
589 TGA_WRITE_REG(par, vvvr | TGA_VALID_VIDEO | TGA_VALID_BLANK,
590 TGA_VALID_REG);
591 break;
592
593 case FB_BLANK_VSYNC_SUSPEND:
594 TGA_WRITE_REG(par, vvcr | 0x40000000, TGA_VERT_REG);
595 TGA_WRITE_REG(par, vvvr | TGA_VALID_BLANK, TGA_VALID_REG);
596 par->vesa_blanked = 1;
597 break;
598
599 case FB_BLANK_HSYNC_SUSPEND:
600 TGA_WRITE_REG(par, vhcr | 0x40000000, TGA_HORIZ_REG);
601 TGA_WRITE_REG(par, vvvr | TGA_VALID_BLANK, TGA_VALID_REG);
602 par->vesa_blanked = 1;
603 break;
604
605 case FB_BLANK_POWERDOWN:
606 TGA_WRITE_REG(par, vhcr | 0x40000000, TGA_HORIZ_REG);
607 TGA_WRITE_REG(par, vvcr | 0x40000000, TGA_VERT_REG);
608 TGA_WRITE_REG(par, vvvr | TGA_VALID_BLANK, TGA_VALID_REG);
609 par->vesa_blanked = 1;
610 break;
611 }
612
613 local_irq_restore(flags);
614 return 0;
615}
616
617
618
619
620
621
622static void
623tgafb_mono_imageblit(struct fb_info *info, const struct fb_image *image)
624{
625 struct tga_par *par = (struct tga_par *) info->par;
626 u32 fgcolor, bgcolor, dx, dy, width, height, vxres, vyres, pixelmask;
627 unsigned long rincr, line_length, shift, pos, is8bpp;
628 unsigned long i, j;
629 const unsigned char *data;
630 void __iomem *regs_base;
631 void __iomem *fb_base;
632
633 is8bpp = info->var.bits_per_pixel == 8;
634
635 dx = image->dx;
636 dy = image->dy;
637 width = image->width;
638 height = image->height;
639 vxres = info->var.xres_virtual;
640 vyres = info->var.yres_virtual;
641 line_length = info->fix.line_length;
642 rincr = (width + 7) / 8;
643
644
645 if (unlikely(width == 0))
646 return;
647
648 if (dx > vxres || dy > vyres)
649 return;
650 if (dx + width > vxres)
651 width = vxres - dx;
652 if (dy + height > vyres)
653 height = vyres - dy;
654
655 regs_base = par->tga_regs_base;
656 fb_base = par->tga_fb_base;
657
658
659
660
661 fgcolor = image->fg_color;
662 bgcolor = image->bg_color;
663 if (is8bpp) {
664 fgcolor |= fgcolor << 8;
665 fgcolor |= fgcolor << 16;
666 bgcolor |= bgcolor << 8;
667 bgcolor |= bgcolor << 16;
668 } else {
669 if (fgcolor < 16)
670 fgcolor = ((u32 *)info->pseudo_palette)[fgcolor];
671 if (bgcolor < 16)
672 bgcolor = ((u32 *)info->pseudo_palette)[bgcolor];
673 }
674 __raw_writel(fgcolor, regs_base + TGA_FOREGROUND_REG);
675 __raw_writel(bgcolor, regs_base + TGA_BACKGROUND_REG);
676
677
678
679 pos = dy * line_length;
680 if (is8bpp) {
681 pos += dx;
682 shift = pos & 3;
683 pos &= -4;
684 } else {
685 pos += dx * 4;
686 shift = (pos & 7) >> 2;
687 pos &= -8;
688 }
689
690 data = (const unsigned char *) image->data;
691
692
693 __raw_writel((is8bpp
694 ? TGA_MODE_SBM_8BPP | TGA_MODE_OPAQUE_STIPPLE
695 : TGA_MODE_SBM_24BPP | TGA_MODE_OPAQUE_STIPPLE),
696 regs_base + TGA_MODE_REG);
697
698 if (width + shift <= 32) {
699 unsigned long bwidth;
700
701
702
703
704
705 pixelmask = (2ul << (width - 1)) - 1;
706 pixelmask <<= shift;
707 __raw_writel(pixelmask, regs_base + TGA_PIXELMASK_REG);
708 wmb();
709
710 bwidth = (width + 7) / 8;
711
712 for (i = 0; i < height; ++i) {
713 u32 mask = 0;
714
715
716
717 for (j = 0; j < bwidth; ++j)
718 mask |= bitrev8(data[j]) << (j * 8);
719
720 __raw_writel(mask << shift, fb_base + pos);
721
722 pos += line_length;
723 data += rincr;
724 }
725 wmb();
726 __raw_writel(0xffffffff, regs_base + TGA_PIXELMASK_REG);
727 } else if (shift == 0) {
728 unsigned long pos0 = pos;
729 const unsigned char *data0 = data;
730 unsigned long bincr = (is8bpp ? 8 : 8*4);
731 unsigned long bwidth;
732
733
734
735
736
737
738
739 wmb();
740
741 bwidth = (width / 8) & -4;
742 for (i = 0; i < height; ++i) {
743 for (j = 0; j < bwidth; j += 4) {
744 u32 mask = 0;
745 mask |= bitrev8(data[j+0]) << (0 * 8);
746 mask |= bitrev8(data[j+1]) << (1 * 8);
747 mask |= bitrev8(data[j+2]) << (2 * 8);
748 mask |= bitrev8(data[j+3]) << (3 * 8);
749 __raw_writel(mask, fb_base + pos + j*bincr);
750 }
751 pos += line_length;
752 data += rincr;
753 }
754 wmb();
755
756 pixelmask = (1ul << (width & 31)) - 1;
757 if (pixelmask) {
758 __raw_writel(pixelmask, regs_base + TGA_PIXELMASK_REG);
759 wmb();
760
761 pos = pos0 + bwidth*bincr;
762 data = data0 + bwidth;
763 bwidth = ((width & 31) + 7) / 8;
764
765 for (i = 0; i < height; ++i) {
766 u32 mask = 0;
767 for (j = 0; j < bwidth; ++j)
768 mask |= bitrev8(data[j]) << (j * 8);
769 __raw_writel(mask, fb_base + pos);
770 pos += line_length;
771 data += rincr;
772 }
773 wmb();
774 __raw_writel(0xffffffff, regs_base + TGA_PIXELMASK_REG);
775 }
776 } else {
777 unsigned long pos0 = pos;
778 const unsigned char *data0 = data;
779 unsigned long bincr = (is8bpp ? 8 : 8*4);
780 unsigned long bwidth;
781
782
783
784
785
786
787 pixelmask = 0xffff << shift;
788 __raw_writel(pixelmask, regs_base + TGA_PIXELMASK_REG);
789 wmb();
790
791 bwidth = (width / 8) & -2;
792 for (i = 0; i < height; ++i) {
793 for (j = 0; j < bwidth; j += 2) {
794 u32 mask = 0;
795 mask |= bitrev8(data[j+0]) << (0 * 8);
796 mask |= bitrev8(data[j+1]) << (1 * 8);
797 mask <<= shift;
798 __raw_writel(mask, fb_base + pos + j*bincr);
799 }
800 pos += line_length;
801 data += rincr;
802 }
803 wmb();
804
805 pixelmask = ((1ul << (width & 15)) - 1) << shift;
806 if (pixelmask) {
807 __raw_writel(pixelmask, regs_base + TGA_PIXELMASK_REG);
808 wmb();
809
810 pos = pos0 + bwidth*bincr;
811 data = data0 + bwidth;
812 bwidth = (width & 15) > 8;
813
814 for (i = 0; i < height; ++i) {
815 u32 mask = bitrev8(data[0]);
816 if (bwidth)
817 mask |= bitrev8(data[1]) << 8;
818 mask <<= shift;
819 __raw_writel(mask, fb_base + pos);
820 pos += line_length;
821 data += rincr;
822 }
823 wmb();
824 }
825 __raw_writel(0xffffffff, regs_base + TGA_PIXELMASK_REG);
826 }
827
828
829 __raw_writel((is8bpp
830 ? TGA_MODE_SBM_8BPP | TGA_MODE_SIMPLE
831 : TGA_MODE_SBM_24BPP | TGA_MODE_SIMPLE),
832 regs_base + TGA_MODE_REG);
833}
834
835static void
836tgafb_clut_imageblit(struct fb_info *info, const struct fb_image *image)
837{
838 struct tga_par *par = (struct tga_par *) info->par;
839 u32 color, dx, dy, width, height, vxres, vyres;
840 u32 *palette = ((u32 *)info->pseudo_palette);
841 unsigned long pos, line_length, i, j;
842 const unsigned char *data;
843 void __iomem *regs_base, *fb_base;
844
845 dx = image->dx;
846 dy = image->dy;
847 width = image->width;
848 height = image->height;
849 vxres = info->var.xres_virtual;
850 vyres = info->var.yres_virtual;
851 line_length = info->fix.line_length;
852
853
854 if (dx > vxres || dy > vyres)
855 return;
856 if (dx + width > vxres)
857 width = vxres - dx;
858 if (dy + height > vyres)
859 height = vyres - dy;
860
861 regs_base = par->tga_regs_base;
862 fb_base = par->tga_fb_base;
863
864 pos = dy * line_length + (dx * 4);
865 data = image->data;
866
867
868 for (i = 0; i < height; i++) {
869 for (j = 0; j < width; j++) {
870 color = palette[*data++];
871 __raw_writel(color, fb_base + pos + j*4);
872 }
873 pos += line_length;
874 }
875}
876
877
878
879
880
881
882
883
884
885static void
886tgafb_imageblit(struct fb_info *info, const struct fb_image *image)
887{
888 unsigned int is8bpp = info->var.bits_per_pixel == 8;
889
890
891 if (image->depth == 1) {
892 tgafb_mono_imageblit(info, image);
893 return;
894 }
895
896
897
898
899
900 if (image->depth == info->var.bits_per_pixel) {
901 cfb_imageblit(info, image);
902 return;
903 }
904
905
906 if (!is8bpp && image->depth == 8) {
907 tgafb_clut_imageblit(info, image);
908 return;
909 }
910
911
912}
913
914
915
916
917
918
919
920
921
922static void
923tgafb_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
924{
925 struct tga_par *par = (struct tga_par *) info->par;
926 int is8bpp = info->var.bits_per_pixel == 8;
927 u32 dx, dy, width, height, vxres, vyres, color;
928 unsigned long pos, align, line_length, i, j;
929 void __iomem *regs_base;
930 void __iomem *fb_base;
931
932 dx = rect->dx;
933 dy = rect->dy;
934 width = rect->width;
935 height = rect->height;
936 vxres = info->var.xres_virtual;
937 vyres = info->var.yres_virtual;
938 line_length = info->fix.line_length;
939 regs_base = par->tga_regs_base;
940 fb_base = par->tga_fb_base;
941
942
943 if (dx > vxres || dy > vyres || !width || !height)
944 return;
945 if (dx + width > vxres)
946 width = vxres - dx;
947 if (dy + height > vyres)
948 height = vyres - dy;
949
950 pos = dy * line_length + dx * (is8bpp ? 1 : 4);
951
952
953
954
955
956 if (rect->rop != ROP_COPY) {
957 cfb_fillrect(info, rect);
958 return;
959 }
960
961
962 color = rect->color;
963 if (is8bpp) {
964 color |= color << 8;
965 color |= color << 16;
966 __raw_writel(color, regs_base + TGA_BLOCK_COLOR0_REG);
967 __raw_writel(color, regs_base + TGA_BLOCK_COLOR1_REG);
968 } else {
969 if (color < 16)
970 color = ((u32 *)info->pseudo_palette)[color];
971 __raw_writel(color, regs_base + TGA_BLOCK_COLOR0_REG);
972 __raw_writel(color, regs_base + TGA_BLOCK_COLOR1_REG);
973 __raw_writel(color, regs_base + TGA_BLOCK_COLOR2_REG);
974 __raw_writel(color, regs_base + TGA_BLOCK_COLOR3_REG);
975 __raw_writel(color, regs_base + TGA_BLOCK_COLOR4_REG);
976 __raw_writel(color, regs_base + TGA_BLOCK_COLOR5_REG);
977 __raw_writel(color, regs_base + TGA_BLOCK_COLOR6_REG);
978 __raw_writel(color, regs_base + TGA_BLOCK_COLOR7_REG);
979 }
980
981
982
983 __raw_writel(0xffffffff, regs_base + TGA_DATA_REG);
984
985
986 __raw_writel((is8bpp
987 ? TGA_MODE_SBM_8BPP | TGA_MODE_BLOCK_FILL
988 : TGA_MODE_SBM_24BPP | TGA_MODE_BLOCK_FILL),
989 regs_base + TGA_MODE_REG);
990 wmb();
991
992
993
994
995 if (width == line_length)
996 width *= height, height = 1;
997
998
999
1000
1001 align = (pos & 3) << 16;
1002 pos &= -4;
1003
1004 if (width <= 2048) {
1005 u32 data;
1006
1007 data = (width - 1) | align;
1008
1009 for (i = 0; i < height; ++i) {
1010 __raw_writel(data, fb_base + pos);
1011 pos += line_length;
1012 }
1013 } else {
1014 unsigned long Bpp = (is8bpp ? 1 : 4);
1015 unsigned long nwidth = width & -2048;
1016 u32 fdata, ldata;
1017
1018 fdata = (2048 - 1) | align;
1019 ldata = ((width & 2047) - 1) | align;
1020
1021 for (i = 0; i < height; ++i) {
1022 for (j = 0; j < nwidth; j += 2048)
1023 __raw_writel(fdata, fb_base + pos + j*Bpp);
1024 if (j < width)
1025 __raw_writel(ldata, fb_base + pos + j*Bpp);
1026 pos += line_length;
1027 }
1028 }
1029 wmb();
1030
1031
1032 __raw_writel((is8bpp
1033 ? TGA_MODE_SBM_8BPP | TGA_MODE_SIMPLE
1034 : TGA_MODE_SBM_24BPP | TGA_MODE_SIMPLE),
1035 regs_base + TGA_MODE_REG);
1036}
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052static inline void
1053copyarea_line_8bpp(struct fb_info *info, u32 dy, u32 sy,
1054 u32 height, u32 width)
1055{
1056 struct tga_par *par = (struct tga_par *) info->par;
1057 void __iomem *tga_regs = par->tga_regs_base;
1058 unsigned long dpos, spos, i, n64;
1059
1060
1061 __raw_writel(TGA_MODE_SBM_8BPP | TGA_MODE_COPY, tga_regs+TGA_MODE_REG);
1062 __raw_writel(0, tga_regs+TGA_PIXELSHIFT_REG);
1063 wmb();
1064
1065 n64 = (height * width) / 64;
1066
1067 if (sy < dy) {
1068 spos = (sy + height) * width;
1069 dpos = (dy + height) * width;
1070
1071 for (i = 0; i < n64; ++i) {
1072 spos -= 64;
1073 dpos -= 64;
1074 __raw_writel(spos, tga_regs+TGA_COPY64_SRC);
1075 wmb();
1076 __raw_writel(dpos, tga_regs+TGA_COPY64_DST);
1077 wmb();
1078 }
1079 } else {
1080 spos = sy * width;
1081 dpos = dy * width;
1082
1083 for (i = 0; i < n64; ++i) {
1084 __raw_writel(spos, tga_regs+TGA_COPY64_SRC);
1085 wmb();
1086 __raw_writel(dpos, tga_regs+TGA_COPY64_DST);
1087 wmb();
1088 spos += 64;
1089 dpos += 64;
1090 }
1091 }
1092
1093
1094 __raw_writel(TGA_MODE_SBM_8BPP|TGA_MODE_SIMPLE, tga_regs+TGA_MODE_REG);
1095}
1096
1097static inline void
1098copyarea_line_32bpp(struct fb_info *info, u32 dy, u32 sy,
1099 u32 height, u32 width)
1100{
1101 struct tga_par *par = (struct tga_par *) info->par;
1102 void __iomem *tga_regs = par->tga_regs_base;
1103 void __iomem *tga_fb = par->tga_fb_base;
1104 void __iomem *src;
1105 void __iomem *dst;
1106 unsigned long i, n16;
1107
1108
1109 __raw_writel(TGA_MODE_SBM_24BPP | TGA_MODE_COPY, tga_regs+TGA_MODE_REG);
1110 __raw_writel(0, tga_regs+TGA_PIXELSHIFT_REG);
1111 wmb();
1112
1113 n16 = (height * width) / 16;
1114
1115 if (sy < dy) {
1116 src = tga_fb + (sy + height) * width * 4;
1117 dst = tga_fb + (dy + height) * width * 4;
1118
1119 for (i = 0; i < n16; ++i) {
1120 src -= 64;
1121 dst -= 64;
1122 __raw_writel(0xffff, src);
1123 wmb();
1124 __raw_writel(0xffff, dst);
1125 wmb();
1126 }
1127 } else {
1128 src = tga_fb + sy * width * 4;
1129 dst = tga_fb + dy * width * 4;
1130
1131 for (i = 0; i < n16; ++i) {
1132 __raw_writel(0xffff, src);
1133 wmb();
1134 __raw_writel(0xffff, dst);
1135 wmb();
1136 src += 64;
1137 dst += 64;
1138 }
1139 }
1140
1141
1142 __raw_writel(TGA_MODE_SBM_24BPP|TGA_MODE_SIMPLE, tga_regs+TGA_MODE_REG);
1143}
1144
1145
1146static inline void
1147copyarea_foreward_8bpp(struct fb_info *info, u32 dx, u32 dy, u32 sx, u32 sy,
1148 u32 height, u32 width, u32 line_length)
1149{
1150 struct tga_par *par = (struct tga_par *) info->par;
1151 unsigned long i, copied, left;
1152 unsigned long dpos, spos, dalign, salign, yincr;
1153 u32 smask_first, dmask_first, dmask_last;
1154 int pixel_shift, need_prime, need_second;
1155 unsigned long n64, n32, xincr_first;
1156 void __iomem *tga_regs;
1157 void __iomem *tga_fb;
1158
1159 yincr = line_length;
1160 if (dy > sy) {
1161 dy += height - 1;
1162 sy += height - 1;
1163 yincr = -yincr;
1164 }
1165
1166
1167
1168 dpos = dy * line_length + dx;
1169 spos = sy * line_length + sx;
1170 dalign = dpos & 7;
1171 salign = spos & 7;
1172 dpos &= -8;
1173 spos &= -8;
1174
1175
1176
1177 if (dalign >= salign)
1178 pixel_shift = dalign - salign;
1179 else
1180 pixel_shift = 8 - (salign - dalign);
1181
1182
1183
1184 need_prime = (salign > dalign);
1185 if (need_prime)
1186 dpos -= 8;
1187
1188
1189
1190 copied = 32 - (dalign + (dpos & 31));
1191 if (copied == 32)
1192 copied = 0;
1193 xincr_first = (copied + 7) & -8;
1194 smask_first = dmask_first = (1ul << copied) - 1;
1195 smask_first <<= salign;
1196 dmask_first <<= dalign + need_prime*8;
1197 if (need_prime && copied > 24)
1198 copied -= 8;
1199 left = width - copied;
1200
1201
1202 if (copied > width) {
1203 u32 t;
1204 t = (1ul << width) - 1;
1205 t <<= dalign + need_prime*8;
1206 dmask_first &= t;
1207 left = 0;
1208 }
1209
1210
1211
1212 n64 = need_second = 0;
1213 if ((dpos & 63) == (spos & 63)
1214 && (height == 1 || line_length % 64 == 0)) {
1215
1216 need_second = (dpos + xincr_first) & 63;
1217 if ((need_second & 32) != need_second)
1218 printk(KERN_ERR "tgafb: need_second wrong\n");
1219 if (left >= need_second + 64) {
1220 left -= need_second;
1221 n64 = left / 64;
1222 left %= 64;
1223 } else
1224 need_second = 0;
1225 }
1226
1227
1228
1229 n32 = left / 32;
1230 left %= 32;
1231
1232
1233 dmask_last = (1ul << left) - 1;
1234
1235 tga_regs = par->tga_regs_base;
1236 tga_fb = par->tga_fb_base;
1237
1238
1239 __raw_writel(TGA_MODE_SBM_8BPP|TGA_MODE_COPY, tga_regs+TGA_MODE_REG);
1240 __raw_writel(pixel_shift, tga_regs+TGA_PIXELSHIFT_REG);
1241 wmb();
1242
1243 for (i = 0; i < height; ++i) {
1244 unsigned long j;
1245 void __iomem *sfb;
1246 void __iomem *dfb;
1247
1248 sfb = tga_fb + spos;
1249 dfb = tga_fb + dpos;
1250 if (dmask_first) {
1251 __raw_writel(smask_first, sfb);
1252 wmb();
1253 __raw_writel(dmask_first, dfb);
1254 wmb();
1255 sfb += xincr_first;
1256 dfb += xincr_first;
1257 }
1258
1259 if (need_second) {
1260 __raw_writel(0xffffffff, sfb);
1261 wmb();
1262 __raw_writel(0xffffffff, dfb);
1263 wmb();
1264 sfb += 32;
1265 dfb += 32;
1266 }
1267
1268 if (n64 && (((unsigned long)sfb | (unsigned long)dfb) & 63))
1269 printk(KERN_ERR
1270 "tgafb: misaligned copy64 (s:%p, d:%p)\n",
1271 sfb, dfb);
1272
1273 for (j = 0; j < n64; ++j) {
1274 __raw_writel(sfb - tga_fb, tga_regs+TGA_COPY64_SRC);
1275 wmb();
1276 __raw_writel(dfb - tga_fb, tga_regs+TGA_COPY64_DST);
1277 wmb();
1278 sfb += 64;
1279 dfb += 64;
1280 }
1281
1282 for (j = 0; j < n32; ++j) {
1283 __raw_writel(0xffffffff, sfb);
1284 wmb();
1285 __raw_writel(0xffffffff, dfb);
1286 wmb();
1287 sfb += 32;
1288 dfb += 32;
1289 }
1290
1291 if (dmask_last) {
1292 __raw_writel(0xffffffff, sfb);
1293 wmb();
1294 __raw_writel(dmask_last, dfb);
1295 wmb();
1296 }
1297
1298 spos += yincr;
1299 dpos += yincr;
1300 }
1301
1302
1303 __raw_writel(TGA_MODE_SBM_8BPP|TGA_MODE_SIMPLE, tga_regs+TGA_MODE_REG);
1304}
1305
1306
1307static inline void
1308copyarea_backward_8bpp(struct fb_info *info, u32 dx, u32 dy, u32 sx, u32 sy,
1309 u32 height, u32 width, u32 line_length,
1310 const struct fb_copyarea *area)
1311{
1312 struct tga_par *par = (struct tga_par *) info->par;
1313 unsigned long i, left, yincr;
1314 unsigned long depos, sepos, dealign, sealign;
1315 u32 mask_first, mask_last;
1316 unsigned long n32;
1317 void __iomem *tga_regs;
1318 void __iomem *tga_fb;
1319
1320 yincr = line_length;
1321 if (dy > sy) {
1322 dy += height - 1;
1323 sy += height - 1;
1324 yincr = -yincr;
1325 }
1326
1327
1328
1329 depos = dy * line_length + dx + width;
1330 sepos = sy * line_length + sx + width;
1331 dealign = depos & 7;
1332 sealign = sepos & 7;
1333
1334
1335
1336
1337
1338
1339 if (dealign != sealign) {
1340 cfb_copyarea(info, area);
1341 return;
1342 }
1343
1344
1345
1346 mask_first = (1ul << dealign) - 1;
1347 left = width - dealign;
1348
1349
1350 if (dealign > width) {
1351 mask_first ^= (1ul << (dealign - width)) - 1;
1352 left = 0;
1353 }
1354
1355
1356 n32 = left / 32;
1357 left %= 32;
1358
1359
1360 mask_last = -1 << (32 - left);
1361
1362 tga_regs = par->tga_regs_base;
1363 tga_fb = par->tga_fb_base;
1364
1365
1366 __raw_writel(TGA_MODE_SBM_8BPP|TGA_MODE_COPY, tga_regs+TGA_MODE_REG);
1367 __raw_writel(0, tga_regs+TGA_PIXELSHIFT_REG);
1368 wmb();
1369
1370 for (i = 0; i < height; ++i) {
1371 unsigned long j;
1372 void __iomem *sfb;
1373 void __iomem *dfb;
1374
1375 sfb = tga_fb + sepos;
1376 dfb = tga_fb + depos;
1377 if (mask_first) {
1378 __raw_writel(mask_first, sfb);
1379 wmb();
1380 __raw_writel(mask_first, dfb);
1381 wmb();
1382 }
1383
1384 for (j = 0; j < n32; ++j) {
1385 sfb -= 32;
1386 dfb -= 32;
1387 __raw_writel(0xffffffff, sfb);
1388 wmb();
1389 __raw_writel(0xffffffff, dfb);
1390 wmb();
1391 }
1392
1393 if (mask_last) {
1394 sfb -= 32;
1395 dfb -= 32;
1396 __raw_writel(mask_last, sfb);
1397 wmb();
1398 __raw_writel(mask_last, dfb);
1399 wmb();
1400 }
1401
1402 sepos += yincr;
1403 depos += yincr;
1404 }
1405
1406
1407 __raw_writel(TGA_MODE_SBM_8BPP|TGA_MODE_SIMPLE, tga_regs+TGA_MODE_REG);
1408}
1409
1410static void
1411tgafb_copyarea(struct fb_info *info, const struct fb_copyarea *area)
1412{
1413 unsigned long dx, dy, width, height, sx, sy, vxres, vyres;
1414 unsigned long line_length, bpp;
1415
1416 dx = area->dx;
1417 dy = area->dy;
1418 width = area->width;
1419 height = area->height;
1420 sx = area->sx;
1421 sy = area->sy;
1422 vxres = info->var.xres_virtual;
1423 vyres = info->var.yres_virtual;
1424 line_length = info->fix.line_length;
1425
1426
1427 if (dx > vxres || sx > vxres || dy > vyres || sy > vyres)
1428 return;
1429
1430
1431 if (dx + width > vxres)
1432 width = vxres - dx;
1433 if (dy + height > vyres)
1434 height = vyres - dy;
1435
1436
1437 if (sx + width > vxres || sy + height > vyres)
1438 return;
1439
1440 bpp = info->var.bits_per_pixel;
1441
1442
1443 if (width * (bpp >> 3) == line_length) {
1444 if (bpp == 8)
1445 copyarea_line_8bpp(info, dy, sy, height, width);
1446 else
1447 copyarea_line_32bpp(info, dy, sy, height, width);
1448 }
1449
1450
1451
1452
1453 else if (bpp == 32)
1454 cfb_copyarea(info, area);
1455
1456
1457
1458 else if (dy == sy && dx > sx && dx < sx + width)
1459 copyarea_backward_8bpp(info, dx, dy, sx, sy, height,
1460 width, line_length, area);
1461 else
1462 copyarea_foreward_8bpp(info, dx, dy, sx, sy, height,
1463 width, line_length);
1464}
1465
1466
1467
1468
1469
1470
1471static void
1472tgafb_init_fix(struct fb_info *info)
1473{
1474 struct tga_par *par = (struct tga_par *)info->par;
1475 int tga_bus_pci = TGA_BUS_PCI(par->dev);
1476 int tga_bus_tc = TGA_BUS_TC(par->dev);
1477 u8 tga_type = par->tga_type;
1478 const char *tga_type_name = NULL;
1479
1480 switch (tga_type) {
1481 case TGA_TYPE_8PLANE:
1482 if (tga_bus_pci)
1483 tga_type_name = "Digital ZLXp-E1";
1484 if (tga_bus_tc)
1485 tga_type_name = "Digital ZLX-E1";
1486 break;
1487 case TGA_TYPE_24PLANE:
1488 if (tga_bus_pci)
1489 tga_type_name = "Digital ZLXp-E2";
1490 if (tga_bus_tc)
1491 tga_type_name = "Digital ZLX-E2";
1492 break;
1493 case TGA_TYPE_24PLUSZ:
1494 if (tga_bus_pci)
1495 tga_type_name = "Digital ZLXp-E3";
1496 if (tga_bus_tc)
1497 tga_type_name = "Digital ZLX-E3";
1498 break;
1499 default:
1500 tga_type_name = "Unknown";
1501 break;
1502 }
1503
1504 strlcpy(info->fix.id, tga_type_name, sizeof(info->fix.id));
1505
1506 info->fix.type = FB_TYPE_PACKED_PIXELS;
1507 info->fix.type_aux = 0;
1508 info->fix.visual = (tga_type == TGA_TYPE_8PLANE
1509 ? FB_VISUAL_PSEUDOCOLOR
1510 : FB_VISUAL_DIRECTCOLOR);
1511
1512 info->fix.line_length = par->xres * (par->bits_per_pixel >> 3);
1513 info->fix.smem_start = (size_t) par->tga_fb_base;
1514 info->fix.smem_len = info->fix.line_length * par->yres;
1515 info->fix.mmio_start = (size_t) par->tga_regs_base;
1516 info->fix.mmio_len = 512;
1517
1518 info->fix.xpanstep = 0;
1519 info->fix.ypanstep = 0;
1520 info->fix.ywrapstep = 0;
1521
1522 info->fix.accel = FB_ACCEL_DEC_TGA;
1523
1524
1525
1526
1527
1528 if (tga_type != TGA_TYPE_8PLANE) {
1529 info->var.red.length = 8;
1530 info->var.green.length = 8;
1531 info->var.blue.length = 8;
1532 info->var.red.offset = 16;
1533 info->var.green.offset = 8;
1534 info->var.blue.offset = 0;
1535 }
1536}
1537
1538static int tgafb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
1539{
1540
1541 tgafb_set_par(info);
1542 return 0;
1543}
1544
1545static int tgafb_register(struct device *dev)
1546{
1547 static const struct fb_videomode modedb_tc = {
1548
1549 "1280x1024@72", 0, 1280, 1024, 7645, 224, 28, 33, 3, 160, 3,
1550 FB_SYNC_ON_GREEN, FB_VMODE_NONINTERLACED
1551 };
1552
1553 static unsigned int const fb_offset_presets[4] = {
1554 TGA_8PLANE_FB_OFFSET,
1555 TGA_24PLANE_FB_OFFSET,
1556 0xffffffff,
1557 TGA_24PLUSZ_FB_OFFSET
1558 };
1559
1560 const struct fb_videomode *modedb_tga = NULL;
1561 resource_size_t bar0_start = 0, bar0_len = 0;
1562 const char *mode_option_tga = NULL;
1563 int tga_bus_pci = TGA_BUS_PCI(dev);
1564 int tga_bus_tc = TGA_BUS_TC(dev);
1565 unsigned int modedbsize_tga = 0;
1566 void __iomem *mem_base;
1567 struct fb_info *info;
1568 struct tga_par *par;
1569 u8 tga_type;
1570 int ret = 0;
1571
1572
1573 if (tga_bus_pci && pci_enable_device(to_pci_dev(dev))) {
1574 printk(KERN_ERR "tgafb: Cannot enable PCI device\n");
1575 return -ENODEV;
1576 }
1577
1578
1579 info = framebuffer_alloc(sizeof(struct tga_par), dev);
1580 if (!info) {
1581 printk(KERN_ERR "tgafb: Cannot allocate memory\n");
1582 return -ENOMEM;
1583 }
1584
1585 par = info->par;
1586 dev_set_drvdata(dev, info);
1587
1588
1589 ret = -ENODEV;
1590 if (tga_bus_pci) {
1591 bar0_start = pci_resource_start(to_pci_dev(dev), 0);
1592 bar0_len = pci_resource_len(to_pci_dev(dev), 0);
1593 }
1594 if (tga_bus_tc) {
1595 bar0_start = to_tc_dev(dev)->resource.start;
1596 bar0_len = to_tc_dev(dev)->resource.end - bar0_start + 1;
1597 }
1598 if (!request_mem_region (bar0_start, bar0_len, "tgafb")) {
1599 printk(KERN_ERR "tgafb: cannot reserve FB region\n");
1600 goto err0;
1601 }
1602
1603
1604 mem_base = ioremap_nocache(bar0_start, bar0_len);
1605 if (!mem_base) {
1606 printk(KERN_ERR "tgafb: Cannot map MMIO\n");
1607 goto err1;
1608 }
1609
1610
1611 tga_type = (readl(mem_base) >> 12) & 0x0f;
1612 par->dev = dev;
1613 par->tga_mem_base = mem_base;
1614 par->tga_fb_base = mem_base + fb_offset_presets[tga_type];
1615 par->tga_regs_base = mem_base + TGA_REGS_OFFSET;
1616 par->tga_type = tga_type;
1617 if (tga_bus_pci)
1618 par->tga_chip_rev = (to_pci_dev(dev))->revision;
1619 if (tga_bus_tc)
1620 par->tga_chip_rev = TGA_READ_REG(par, TGA_START_REG) & 0xff;
1621
1622
1623 info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_COPYAREA |
1624 FBINFO_HWACCEL_IMAGEBLIT | FBINFO_HWACCEL_FILLRECT;
1625 info->fbops = &tgafb_ops;
1626 info->screen_base = par->tga_fb_base;
1627 info->pseudo_palette = par->palette;
1628
1629
1630 if (tga_bus_pci) {
1631 mode_option_tga = mode_option_pci;
1632 }
1633 if (tga_bus_tc) {
1634 mode_option_tga = mode_option_tc;
1635 modedb_tga = &modedb_tc;
1636 modedbsize_tga = 1;
1637 }
1638 ret = fb_find_mode(&info->var, info,
1639 mode_option ? mode_option : mode_option_tga,
1640 modedb_tga, modedbsize_tga, NULL,
1641 tga_type == TGA_TYPE_8PLANE ? 8 : 32);
1642 if (ret == 0 || ret == 4) {
1643 printk(KERN_ERR "tgafb: Could not find valid video mode\n");
1644 ret = -EINVAL;
1645 goto err1;
1646 }
1647
1648 if (fb_alloc_cmap(&info->cmap, 256, 0)) {
1649 printk(KERN_ERR "tgafb: Could not allocate color map\n");
1650 ret = -ENOMEM;
1651 goto err1;
1652 }
1653
1654 tgafb_set_par(info);
1655 tgafb_init_fix(info);
1656
1657 if (register_framebuffer(info) < 0) {
1658 printk(KERN_ERR "tgafb: Could not register framebuffer\n");
1659 ret = -EINVAL;
1660 goto err2;
1661 }
1662
1663 if (tga_bus_pci) {
1664 pr_info("tgafb: DC21030 [TGA] detected, rev=0x%02x\n",
1665 par->tga_chip_rev);
1666 pr_info("tgafb: at PCI bus %d, device %d, function %d\n",
1667 to_pci_dev(dev)->bus->number,
1668 PCI_SLOT(to_pci_dev(dev)->devfn),
1669 PCI_FUNC(to_pci_dev(dev)->devfn));
1670 }
1671 if (tga_bus_tc)
1672 pr_info("tgafb: SFB+ detected, rev=0x%02x\n",
1673 par->tga_chip_rev);
1674 pr_info("fb%d: %s frame buffer device at 0x%lx\n",
1675 info->node, info->fix.id, (long)bar0_start);
1676
1677 return 0;
1678
1679 err2:
1680 fb_dealloc_cmap(&info->cmap);
1681 err1:
1682 if (mem_base)
1683 iounmap(mem_base);
1684 release_mem_region(bar0_start, bar0_len);
1685 err0:
1686 framebuffer_release(info);
1687 return ret;
1688}
1689
1690static void tgafb_unregister(struct device *dev)
1691{
1692 resource_size_t bar0_start = 0, bar0_len = 0;
1693 int tga_bus_pci = TGA_BUS_PCI(dev);
1694 int tga_bus_tc = TGA_BUS_TC(dev);
1695 struct fb_info *info = NULL;
1696 struct tga_par *par;
1697
1698 info = dev_get_drvdata(dev);
1699 if (!info)
1700 return;
1701
1702 par = info->par;
1703 unregister_framebuffer(info);
1704 fb_dealloc_cmap(&info->cmap);
1705 iounmap(par->tga_mem_base);
1706 if (tga_bus_pci) {
1707 bar0_start = pci_resource_start(to_pci_dev(dev), 0);
1708 bar0_len = pci_resource_len(to_pci_dev(dev), 0);
1709 }
1710 if (tga_bus_tc) {
1711 bar0_start = to_tc_dev(dev)->resource.start;
1712 bar0_len = to_tc_dev(dev)->resource.end - bar0_start + 1;
1713 }
1714 release_mem_region(bar0_start, bar0_len);
1715 framebuffer_release(info);
1716}
1717
1718static void tgafb_exit(void)
1719{
1720 tc_unregister_driver(&tgafb_tc_driver);
1721 pci_unregister_driver(&tgafb_pci_driver);
1722}
1723
1724#ifndef MODULE
1725static int tgafb_setup(char *arg)
1726{
1727 char *this_opt;
1728
1729 if (arg && *arg) {
1730 while ((this_opt = strsep(&arg, ","))) {
1731 if (!*this_opt)
1732 continue;
1733 if (!strncmp(this_opt, "mode:", 5))
1734 mode_option = this_opt+5;
1735 else
1736 printk(KERN_ERR
1737 "tgafb: unknown parameter %s\n",
1738 this_opt);
1739 }
1740 }
1741
1742 return 0;
1743}
1744#endif
1745
1746static int tgafb_init(void)
1747{
1748 int status;
1749#ifndef MODULE
1750 char *option = NULL;
1751
1752 if (fb_get_options("tgafb", &option))
1753 return -ENODEV;
1754 tgafb_setup(option);
1755#endif
1756 status = pci_register_driver(&tgafb_pci_driver);
1757 if (!status)
1758 status = tc_register_driver(&tgafb_tc_driver);
1759 return status;
1760}
1761
1762
1763
1764
1765
1766module_init(tgafb_init);
1767module_exit(tgafb_exit);
1768
1769MODULE_DESCRIPTION("Framebuffer driver for TGA/SFB+ chipset");
1770MODULE_LICENSE("GPL");
1771