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