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