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