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 *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 fb_base = par->tga_fb_base;
859
860 pos = dy * line_length + (dx * 4);
861 data = image->data;
862
863
864 for (i = 0; i < height; i++) {
865 for (j = 0; j < width; j++) {
866 color = palette[*data++];
867 __raw_writel(color, fb_base + pos + j*4);
868 }
869 pos += line_length;
870 }
871}
872
873
874
875
876
877
878
879
880
881static void
882tgafb_imageblit(struct fb_info *info, const struct fb_image *image)
883{
884 unsigned int is8bpp = info->var.bits_per_pixel == 8;
885
886
887 if (image->depth == 1) {
888 tgafb_mono_imageblit(info, image);
889 return;
890 }
891
892
893
894
895
896 if (image->depth == info->var.bits_per_pixel) {
897 cfb_imageblit(info, image);
898 return;
899 }
900
901
902 if (!is8bpp && image->depth == 8) {
903 tgafb_clut_imageblit(info, image);
904 return;
905 }
906
907
908}
909
910
911
912
913
914
915
916
917
918static void
919tgafb_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
920{
921 struct tga_par *par = (struct tga_par *) info->par;
922 int is8bpp = info->var.bits_per_pixel == 8;
923 u32 dx, dy, width, height, vxres, vyres, color;
924 unsigned long pos, align, line_length, i, j;
925 void __iomem *regs_base;
926 void __iomem *fb_base;
927
928 dx = rect->dx;
929 dy = rect->dy;
930 width = rect->width;
931 height = rect->height;
932 vxres = info->var.xres_virtual;
933 vyres = info->var.yres_virtual;
934 line_length = info->fix.line_length;
935 regs_base = par->tga_regs_base;
936 fb_base = par->tga_fb_base;
937
938
939 if (dx > vxres || dy > vyres || !width || !height)
940 return;
941 if (dx + width > vxres)
942 width = vxres - dx;
943 if (dy + height > vyres)
944 height = vyres - dy;
945
946 pos = dy * line_length + dx * (is8bpp ? 1 : 4);
947
948
949
950
951
952 if (rect->rop != ROP_COPY) {
953 cfb_fillrect(info, rect);
954 return;
955 }
956
957
958 color = rect->color;
959 if (is8bpp) {
960 color |= color << 8;
961 color |= color << 16;
962 __raw_writel(color, regs_base + TGA_BLOCK_COLOR0_REG);
963 __raw_writel(color, regs_base + TGA_BLOCK_COLOR1_REG);
964 } else {
965 if (color < 16)
966 color = ((u32 *)info->pseudo_palette)[color];
967 __raw_writel(color, regs_base + TGA_BLOCK_COLOR0_REG);
968 __raw_writel(color, regs_base + TGA_BLOCK_COLOR1_REG);
969 __raw_writel(color, regs_base + TGA_BLOCK_COLOR2_REG);
970 __raw_writel(color, regs_base + TGA_BLOCK_COLOR3_REG);
971 __raw_writel(color, regs_base + TGA_BLOCK_COLOR4_REG);
972 __raw_writel(color, regs_base + TGA_BLOCK_COLOR5_REG);
973 __raw_writel(color, regs_base + TGA_BLOCK_COLOR6_REG);
974 __raw_writel(color, regs_base + TGA_BLOCK_COLOR7_REG);
975 }
976
977
978
979 __raw_writel(0xffffffff, regs_base + TGA_DATA_REG);
980
981
982 __raw_writel((is8bpp
983 ? TGA_MODE_SBM_8BPP | TGA_MODE_BLOCK_FILL
984 : TGA_MODE_SBM_24BPP | TGA_MODE_BLOCK_FILL),
985 regs_base + TGA_MODE_REG);
986 wmb();
987
988
989
990
991 if (width == line_length) {
992 width *= height;
993 height = 1;
994 }
995
996
997
998
999 align = (pos & 3) << 16;
1000 pos &= -4;
1001
1002 if (width <= 2048) {
1003 u32 data;
1004
1005 data = (width - 1) | align;
1006
1007 for (i = 0; i < height; ++i) {
1008 __raw_writel(data, fb_base + pos);
1009 pos += line_length;
1010 }
1011 } else {
1012 unsigned long Bpp = (is8bpp ? 1 : 4);
1013 unsigned long nwidth = width & -2048;
1014 u32 fdata, ldata;
1015
1016 fdata = (2048 - 1) | align;
1017 ldata = ((width & 2047) - 1) | align;
1018
1019 for (i = 0; i < height; ++i) {
1020 for (j = 0; j < nwidth; j += 2048)
1021 __raw_writel(fdata, fb_base + pos + j*Bpp);
1022 if (j < width)
1023 __raw_writel(ldata, fb_base + pos + j*Bpp);
1024 pos += line_length;
1025 }
1026 }
1027 wmb();
1028
1029
1030 __raw_writel((is8bpp
1031 ? TGA_MODE_SBM_8BPP | TGA_MODE_SIMPLE
1032 : TGA_MODE_SBM_24BPP | TGA_MODE_SIMPLE),
1033 regs_base + TGA_MODE_REG);
1034}
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050static inline void
1051copyarea_line_8bpp(struct fb_info *info, u32 dy, u32 sy,
1052 u32 height, u32 width)
1053{
1054 struct tga_par *par = (struct tga_par *) info->par;
1055 void __iomem *tga_regs = par->tga_regs_base;
1056 unsigned long dpos, spos, i, n64;
1057
1058
1059 __raw_writel(TGA_MODE_SBM_8BPP | TGA_MODE_COPY, tga_regs+TGA_MODE_REG);
1060 __raw_writel(0, tga_regs+TGA_PIXELSHIFT_REG);
1061 wmb();
1062
1063 n64 = (height * width) / 64;
1064
1065 if (sy < dy) {
1066 spos = (sy + height) * width;
1067 dpos = (dy + height) * width;
1068
1069 for (i = 0; i < n64; ++i) {
1070 spos -= 64;
1071 dpos -= 64;
1072 __raw_writel(spos, tga_regs+TGA_COPY64_SRC);
1073 wmb();
1074 __raw_writel(dpos, tga_regs+TGA_COPY64_DST);
1075 wmb();
1076 }
1077 } else {
1078 spos = sy * width;
1079 dpos = dy * width;
1080
1081 for (i = 0; i < n64; ++i) {
1082 __raw_writel(spos, tga_regs+TGA_COPY64_SRC);
1083 wmb();
1084 __raw_writel(dpos, tga_regs+TGA_COPY64_DST);
1085 wmb();
1086 spos += 64;
1087 dpos += 64;
1088 }
1089 }
1090
1091
1092 __raw_writel(TGA_MODE_SBM_8BPP|TGA_MODE_SIMPLE, tga_regs+TGA_MODE_REG);
1093}
1094
1095static inline void
1096copyarea_line_32bpp(struct fb_info *info, u32 dy, u32 sy,
1097 u32 height, u32 width)
1098{
1099 struct tga_par *par = (struct tga_par *) info->par;
1100 void __iomem *tga_regs = par->tga_regs_base;
1101 void __iomem *tga_fb = par->tga_fb_base;
1102 void __iomem *src;
1103 void __iomem *dst;
1104 unsigned long i, n16;
1105
1106
1107 __raw_writel(TGA_MODE_SBM_24BPP | TGA_MODE_COPY, tga_regs+TGA_MODE_REG);
1108 __raw_writel(0, tga_regs+TGA_PIXELSHIFT_REG);
1109 wmb();
1110
1111 n16 = (height * width) / 16;
1112
1113 if (sy < dy) {
1114 src = tga_fb + (sy + height) * width * 4;
1115 dst = tga_fb + (dy + height) * width * 4;
1116
1117 for (i = 0; i < n16; ++i) {
1118 src -= 64;
1119 dst -= 64;
1120 __raw_writel(0xffff, src);
1121 wmb();
1122 __raw_writel(0xffff, dst);
1123 wmb();
1124 }
1125 } else {
1126 src = tga_fb + sy * width * 4;
1127 dst = tga_fb + dy * width * 4;
1128
1129 for (i = 0; i < n16; ++i) {
1130 __raw_writel(0xffff, src);
1131 wmb();
1132 __raw_writel(0xffff, dst);
1133 wmb();
1134 src += 64;
1135 dst += 64;
1136 }
1137 }
1138
1139
1140 __raw_writel(TGA_MODE_SBM_24BPP|TGA_MODE_SIMPLE, tga_regs+TGA_MODE_REG);
1141}
1142
1143
1144static inline void
1145copyarea_8bpp(struct fb_info *info, u32 dx, u32 dy, u32 sx, u32 sy,
1146 u32 height, u32 width, u32 line_length,
1147 const struct fb_copyarea *area)
1148{
1149 struct tga_par *par = (struct tga_par *) info->par;
1150 unsigned i, yincr;
1151 int depos, sepos, backward, last_step, step;
1152 u32 mask_last;
1153 unsigned n32;
1154 void __iomem *tga_regs;
1155 void __iomem *tga_fb;
1156
1157
1158 if ((dx | sx | width) & 7) {
1159 cfb_copyarea(info, area);
1160 return;
1161 }
1162
1163 yincr = line_length;
1164 if (dy > sy) {
1165 dy += height - 1;
1166 sy += height - 1;
1167 yincr = -yincr;
1168 }
1169 backward = dy == sy && dx > sx && dx < sx + width;
1170
1171
1172
1173 depos = dy * line_length + dx;
1174 sepos = sy * line_length + sx;
1175 if (backward) {
1176 depos += width;
1177 sepos += width;
1178 }
1179
1180
1181 n32 = width / 32;
1182 last_step = width % 32;
1183
1184
1185 mask_last = (1ul << last_step) - 1;
1186
1187 if (!backward) {
1188 step = 32;
1189 last_step = 32;
1190 } else {
1191 step = -32;
1192 last_step = -last_step;
1193 sepos -= 32;
1194 depos -= 32;
1195 }
1196
1197 tga_regs = par->tga_regs_base;
1198 tga_fb = par->tga_fb_base;
1199
1200
1201 __raw_writel(TGA_MODE_SBM_8BPP|TGA_MODE_COPY, tga_regs+TGA_MODE_REG);
1202 __raw_writel(0, tga_regs+TGA_PIXELSHIFT_REG);
1203 wmb();
1204
1205 for (i = 0; i < height; ++i) {
1206 unsigned long j;
1207 void __iomem *sfb;
1208 void __iomem *dfb;
1209
1210 sfb = tga_fb + sepos;
1211 dfb = tga_fb + depos;
1212
1213 for (j = 0; j < n32; j++) {
1214 if (j < 2 && j + 1 < n32 && !backward &&
1215 !(((unsigned long)sfb | (unsigned long)dfb) & 63)) {
1216 do {
1217 __raw_writel(sfb - tga_fb, tga_regs+TGA_COPY64_SRC);
1218 wmb();
1219 __raw_writel(dfb - tga_fb, tga_regs+TGA_COPY64_DST);
1220 wmb();
1221 sfb += 64;
1222 dfb += 64;
1223 j += 2;
1224 } while (j + 1 < n32);
1225 j--;
1226 continue;
1227 }
1228 __raw_writel(0xffffffff, sfb);
1229 wmb();
1230 __raw_writel(0xffffffff, dfb);
1231 wmb();
1232 sfb += step;
1233 dfb += step;
1234 }
1235
1236 if (mask_last) {
1237 sfb += last_step - step;
1238 dfb += last_step - step;
1239 __raw_writel(mask_last, sfb);
1240 wmb();
1241 __raw_writel(mask_last, dfb);
1242 wmb();
1243 }
1244
1245 sepos += yincr;
1246 depos += yincr;
1247 }
1248
1249
1250 __raw_writel(TGA_MODE_SBM_8BPP|TGA_MODE_SIMPLE, tga_regs+TGA_MODE_REG);
1251}
1252
1253static void
1254tgafb_copyarea(struct fb_info *info, const struct fb_copyarea *area)
1255{
1256 unsigned long dx, dy, width, height, sx, sy, vxres, vyres;
1257 unsigned long line_length, bpp;
1258
1259 dx = area->dx;
1260 dy = area->dy;
1261 width = area->width;
1262 height = area->height;
1263 sx = area->sx;
1264 sy = area->sy;
1265 vxres = info->var.xres_virtual;
1266 vyres = info->var.yres_virtual;
1267 line_length = info->fix.line_length;
1268
1269
1270 if (dx > vxres || sx > vxres || dy > vyres || sy > vyres)
1271 return;
1272
1273
1274 if (dx + width > vxres)
1275 width = vxres - dx;
1276 if (dy + height > vyres)
1277 height = vyres - dy;
1278
1279
1280 if (sx + width > vxres || sy + height > vyres)
1281 return;
1282
1283 bpp = info->var.bits_per_pixel;
1284
1285
1286 if (!(line_length & 63) && width * (bpp >> 3) == line_length) {
1287 if (bpp == 8)
1288 copyarea_line_8bpp(info, dy, sy, height, width);
1289 else
1290 copyarea_line_32bpp(info, dy, sy, height, width);
1291 }
1292
1293
1294
1295
1296 else if (bpp == 32)
1297 cfb_copyarea(info, area);
1298
1299 else
1300 copyarea_8bpp(info, dx, dy, sx, sy, height,
1301 width, line_length, area);
1302}
1303
1304
1305
1306
1307
1308
1309static void
1310tgafb_init_fix(struct fb_info *info)
1311{
1312 struct tga_par *par = (struct tga_par *)info->par;
1313 int tga_bus_pci = dev_is_pci(par->dev);
1314 int tga_bus_tc = TGA_BUS_TC(par->dev);
1315 u8 tga_type = par->tga_type;
1316 const char *tga_type_name = NULL;
1317 unsigned memory_size;
1318
1319 switch (tga_type) {
1320 case TGA_TYPE_8PLANE:
1321 if (tga_bus_pci)
1322 tga_type_name = "Digital ZLXp-E1";
1323 if (tga_bus_tc)
1324 tga_type_name = "Digital ZLX-E1";
1325 memory_size = 2097152;
1326 break;
1327 case TGA_TYPE_24PLANE:
1328 if (tga_bus_pci)
1329 tga_type_name = "Digital ZLXp-E2";
1330 if (tga_bus_tc)
1331 tga_type_name = "Digital ZLX-E2";
1332 memory_size = 8388608;
1333 break;
1334 case TGA_TYPE_24PLUSZ:
1335 if (tga_bus_pci)
1336 tga_type_name = "Digital ZLXp-E3";
1337 if (tga_bus_tc)
1338 tga_type_name = "Digital ZLX-E3";
1339 memory_size = 16777216;
1340 break;
1341 }
1342 if (!tga_type_name) {
1343 tga_type_name = "Unknown";
1344 memory_size = 16777216;
1345 }
1346
1347 strlcpy(info->fix.id, tga_type_name, sizeof(info->fix.id));
1348
1349 info->fix.type = FB_TYPE_PACKED_PIXELS;
1350 info->fix.type_aux = 0;
1351 info->fix.visual = (tga_type == TGA_TYPE_8PLANE
1352 ? FB_VISUAL_PSEUDOCOLOR
1353 : FB_VISUAL_DIRECTCOLOR);
1354
1355 info->fix.smem_start = (size_t) par->tga_fb_base;
1356 info->fix.smem_len = memory_size;
1357 info->fix.mmio_start = (size_t) par->tga_regs_base;
1358 info->fix.mmio_len = 512;
1359
1360 info->fix.xpanstep = 0;
1361 info->fix.ypanstep = 0;
1362 info->fix.ywrapstep = 0;
1363
1364 info->fix.accel = FB_ACCEL_DEC_TGA;
1365
1366
1367
1368
1369
1370 if (tga_type != TGA_TYPE_8PLANE) {
1371 info->var.red.length = 8;
1372 info->var.green.length = 8;
1373 info->var.blue.length = 8;
1374 info->var.red.offset = 16;
1375 info->var.green.offset = 8;
1376 info->var.blue.offset = 0;
1377 }
1378}
1379
1380static int tgafb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
1381{
1382
1383 tgafb_set_par(info);
1384 return 0;
1385}
1386
1387static int tgafb_register(struct device *dev)
1388{
1389 static const struct fb_videomode modedb_tc = {
1390
1391 "1280x1024@72", 0, 1280, 1024, 7645, 224, 28, 33, 3, 160, 3,
1392 FB_SYNC_ON_GREEN, FB_VMODE_NONINTERLACED
1393 };
1394
1395 static unsigned int const fb_offset_presets[4] = {
1396 TGA_8PLANE_FB_OFFSET,
1397 TGA_24PLANE_FB_OFFSET,
1398 0xffffffff,
1399 TGA_24PLUSZ_FB_OFFSET
1400 };
1401
1402 const struct fb_videomode *modedb_tga = NULL;
1403 resource_size_t bar0_start = 0, bar0_len = 0;
1404 const char *mode_option_tga = NULL;
1405 int tga_bus_pci = dev_is_pci(dev);
1406 int tga_bus_tc = TGA_BUS_TC(dev);
1407 unsigned int modedbsize_tga = 0;
1408 void __iomem *mem_base;
1409 struct fb_info *info;
1410 struct tga_par *par;
1411 u8 tga_type;
1412 int ret = 0;
1413
1414
1415 if (tga_bus_pci && pci_enable_device(to_pci_dev(dev))) {
1416 printk(KERN_ERR "tgafb: Cannot enable PCI device\n");
1417 return -ENODEV;
1418 }
1419
1420
1421 info = framebuffer_alloc(sizeof(struct tga_par), dev);
1422 if (!info)
1423 return -ENOMEM;
1424
1425 par = info->par;
1426 dev_set_drvdata(dev, info);
1427
1428
1429 ret = -ENODEV;
1430 if (tga_bus_pci) {
1431 bar0_start = pci_resource_start(to_pci_dev(dev), 0);
1432 bar0_len = pci_resource_len(to_pci_dev(dev), 0);
1433 }
1434 if (tga_bus_tc) {
1435 bar0_start = to_tc_dev(dev)->resource.start;
1436 bar0_len = to_tc_dev(dev)->resource.end - bar0_start + 1;
1437 }
1438 if (!request_mem_region (bar0_start, bar0_len, "tgafb")) {
1439 printk(KERN_ERR "tgafb: cannot reserve FB region\n");
1440 goto err0;
1441 }
1442
1443
1444 mem_base = ioremap(bar0_start, bar0_len);
1445 if (!mem_base) {
1446 printk(KERN_ERR "tgafb: Cannot map MMIO\n");
1447 goto err1;
1448 }
1449
1450
1451 tga_type = (readl(mem_base) >> 12) & 0x0f;
1452 par->dev = dev;
1453 par->tga_mem_base = mem_base;
1454 par->tga_fb_base = mem_base + fb_offset_presets[tga_type];
1455 par->tga_regs_base = mem_base + TGA_REGS_OFFSET;
1456 par->tga_type = tga_type;
1457 if (tga_bus_pci)
1458 par->tga_chip_rev = (to_pci_dev(dev))->revision;
1459 if (tga_bus_tc)
1460 par->tga_chip_rev = TGA_READ_REG(par, TGA_START_REG) & 0xff;
1461
1462
1463 info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_COPYAREA |
1464 FBINFO_HWACCEL_IMAGEBLIT | FBINFO_HWACCEL_FILLRECT;
1465 info->fbops = &tgafb_ops;
1466 info->screen_base = par->tga_fb_base;
1467 info->pseudo_palette = par->palette;
1468
1469
1470 if (tga_bus_pci) {
1471 mode_option_tga = mode_option_pci;
1472 }
1473 if (tga_bus_tc) {
1474 mode_option_tga = mode_option_tc;
1475 modedb_tga = &modedb_tc;
1476 modedbsize_tga = 1;
1477 }
1478
1479 tgafb_init_fix(info);
1480
1481 ret = fb_find_mode(&info->var, info,
1482 mode_option ? mode_option : mode_option_tga,
1483 modedb_tga, modedbsize_tga, NULL,
1484 tga_type == TGA_TYPE_8PLANE ? 8 : 32);
1485 if (ret == 0 || ret == 4) {
1486 printk(KERN_ERR "tgafb: Could not find valid video mode\n");
1487 ret = -EINVAL;
1488 goto err1;
1489 }
1490
1491 if (fb_alloc_cmap(&info->cmap, 256, 0)) {
1492 printk(KERN_ERR "tgafb: Could not allocate color map\n");
1493 ret = -ENOMEM;
1494 goto err1;
1495 }
1496
1497 tgafb_set_par(info);
1498
1499 if (register_framebuffer(info) < 0) {
1500 printk(KERN_ERR "tgafb: Could not register framebuffer\n");
1501 ret = -EINVAL;
1502 goto err2;
1503 }
1504
1505 if (tga_bus_pci) {
1506 pr_info("tgafb: DC21030 [TGA] detected, rev=0x%02x\n",
1507 par->tga_chip_rev);
1508 pr_info("tgafb: at PCI bus %d, device %d, function %d\n",
1509 to_pci_dev(dev)->bus->number,
1510 PCI_SLOT(to_pci_dev(dev)->devfn),
1511 PCI_FUNC(to_pci_dev(dev)->devfn));
1512 }
1513 if (tga_bus_tc)
1514 pr_info("tgafb: SFB+ detected, rev=0x%02x\n",
1515 par->tga_chip_rev);
1516 fb_info(info, "%s frame buffer device at 0x%lx\n",
1517 info->fix.id, (long)bar0_start);
1518
1519 return 0;
1520
1521 err2:
1522 fb_dealloc_cmap(&info->cmap);
1523 err1:
1524 if (mem_base)
1525 iounmap(mem_base);
1526 release_mem_region(bar0_start, bar0_len);
1527 err0:
1528 framebuffer_release(info);
1529 return ret;
1530}
1531
1532static void tgafb_unregister(struct device *dev)
1533{
1534 resource_size_t bar0_start = 0, bar0_len = 0;
1535 int tga_bus_pci = dev_is_pci(dev);
1536 int tga_bus_tc = TGA_BUS_TC(dev);
1537 struct fb_info *info = NULL;
1538 struct tga_par *par;
1539
1540 info = dev_get_drvdata(dev);
1541 if (!info)
1542 return;
1543
1544 par = info->par;
1545 unregister_framebuffer(info);
1546 fb_dealloc_cmap(&info->cmap);
1547 iounmap(par->tga_mem_base);
1548 if (tga_bus_pci) {
1549 bar0_start = pci_resource_start(to_pci_dev(dev), 0);
1550 bar0_len = pci_resource_len(to_pci_dev(dev), 0);
1551 }
1552 if (tga_bus_tc) {
1553 bar0_start = to_tc_dev(dev)->resource.start;
1554 bar0_len = to_tc_dev(dev)->resource.end - bar0_start + 1;
1555 }
1556 release_mem_region(bar0_start, bar0_len);
1557 framebuffer_release(info);
1558}
1559
1560static void tgafb_exit(void)
1561{
1562 tc_unregister_driver(&tgafb_tc_driver);
1563 pci_unregister_driver(&tgafb_pci_driver);
1564}
1565
1566#ifndef MODULE
1567static int tgafb_setup(char *arg)
1568{
1569 char *this_opt;
1570
1571 if (arg && *arg) {
1572 while ((this_opt = strsep(&arg, ","))) {
1573 if (!*this_opt)
1574 continue;
1575 if (!strncmp(this_opt, "mode:", 5))
1576 mode_option = this_opt+5;
1577 else
1578 printk(KERN_ERR
1579 "tgafb: unknown parameter %s\n",
1580 this_opt);
1581 }
1582 }
1583
1584 return 0;
1585}
1586#endif
1587
1588static int tgafb_init(void)
1589{
1590 int status;
1591#ifndef MODULE
1592 char *option = NULL;
1593
1594 if (fb_get_options("tgafb", &option))
1595 return -ENODEV;
1596 tgafb_setup(option);
1597#endif
1598 status = pci_register_driver(&tgafb_pci_driver);
1599 if (!status)
1600 status = tc_register_driver(&tgafb_tc_driver);
1601 return status;
1602}
1603
1604
1605
1606
1607
1608module_init(tgafb_init);
1609module_exit(tgafb_exit);
1610
1611MODULE_DESCRIPTION("Framebuffer driver for TGA/SFB+ chipset");
1612MODULE_LICENSE("GPL");
1613