1 /* MGA-M83 framebuffer driver
3 * make -C ../linux-2.6.14 SUBDIRS=$PWD modules
5 * Copyright (C) 2005-2006, Alexander Shmelev <ashmelev@task.sun.mcst.ru>
7 * To specify a video mode at bootup, use the following boot options:
8 * video=mgam83fb:<xres>x<yres>[-<bpp>][@refresh]
10 * Supported resolutions:
11 * 640x480, 800x600, 1024x768, 1280x1024, 1600x1200
13 * 8bpp, 16bpp, 24bpp, 32bpp
15 * Details about modes can be found in Linux/Documentation/fb/modedb.txt
18 * 1.0 PCI model support only
19 * 1.1 SBUS model support added
20 * 2.0 Linux-2.6 version
23 /* Debuging - mga debug, dma debug */
25 #include <linux/module.h>
26 #include <linux/kernel.h>
27 #include <linux/errno.h>
28 #include <linux/string.h>
30 #include <linux/tty.h>
31 #include <linux/slab.h>
32 #include <linux/delay.h>
34 #include <linux/init.h>
35 #include <linux/proc_fs.h>
36 #include <linux/rmap.h>
37 #include <linux/dma-mapping.h>
38 #include <linux/interrupt.h>
40 #include <asm/uaccess.h>
44 #ifdef CONFIG_E90_FASTBOOT
45 #include <asm/bootinfo.h>
47 #include <linux/pci.h>
50 #ifdef CONFIG_FB_SOFT_CURSOR
51 extern int soft_cursor(struct fb_info
*info
, struct fb_cursor
*cursor
);
53 static char *mgam83fb_default_mode
= "1024x768-8@60";
54 static int next_index
= 0;
55 static bool use_irq
= 0;
57 /*******************************************************************************
59 *******************************************************************************
63 int index
; // MGAM index
67 int iospace
; // iospace
69 unsigned long base
; // phys address
70 uint8_t* vbase
; // virtual address
74 unsigned long base
; // phys address
75 uint8_t* vbase
; // virtual address
79 unsigned long base
; // phys address
80 uint8_t* vbase
; // virtual address
92 int dma_not_supported
;
94 /* Current videomode **************************************************/
95 __u32 xres
; // visible resolution
97 __u32 xres_virtual
; // virtual resolution
99 __u32 xoffset
; // offset from virtual to visible
100 __u32 yoffset
; // resolution
102 __u32 bits_per_pixel
; // Bits per pixel
104 __u32 pixclock
; // pixel clock in ps (pico seconds)
105 __u32 left_margin
; // time from sync to picture
106 __u32 right_margin
; // time from picture to sync
107 __u32 upper_margin
; // time from sync to picture
109 __u32 hsync_len
; // length of horizontal sync
110 __u32 vsync_len
; // length of vertical sync
114 u32 pseudo_palette
[16];
119 /*******************************************************************************
121 *******************************************************************************
123 /* Framebuffer entry points */
124 static int mgam83fb_check_var(struct fb_var_screeninfo
* var
, struct fb_info
* info
);
125 static int mgam83fb_set_par(struct fb_info
* info
);
126 static int mgam83fb_setcolreg(unsigned regno
, unsigned red
, unsigned green
,
127 unsigned blue
, unsigned transp
,
128 struct fb_info
*info
);
130 static int mgam83fb_mmap(struct fb_info
*info
, struct vm_area_struct
*vma
);
132 void __proc_init( struct mgam83fb_par
* p
);
133 int mgafb_proc_write(struct file
*file
, const char *buffer
, unsigned long count
, void *data
);
134 int mgafb_proc_read(char *buf
, char **start
, off_t off
, int count
, int *eof
, void *data
);
135 void __fb_fill ( struct mgam83fb_par
* p
);
136 void __dump_var( const struct fb_var_screeninfo
* var
);
137 void __dump_par( const struct mgam83fb_par
* p
);
138 void __dump_mmio( struct mgam83fb_par
* p
);
140 #undef MGAM_TRACE_FUNC
141 #ifdef MGAM_TRACE_FUNC
142 extern void mgam_trace_func(unsigned int i
);
143 #define trace_func(x) mgam_trace_func(x)
145 #define trace_func(x)
148 /* After the sync (FULL) bug is fixed must be removed (defined) */
149 #undef AFTER_FIXING_SYNC_BUG
151 /*******************************************************************************
152 * MMIO BitBlt Module Registers
153 *******************************************************************************
155 #define REG_BB_CTRL 0x1000 /* BitBlt module control register (write only)*/
156 #define REG_BB_STAT 0x1000 /* BitBlt module status register (read only) */
158 #define REG_BB_WINDOW 0x1004 /* Operation geometry */
159 #define REG_BB_SADDR 0x1008 /* Source start address */
160 #define REG_BB_DADDR 0x100c /* Destination start address */
161 #define REG_BB_PITCH 0x1010 /* */
162 #define REG_BB_BG 0x1014 /* Background color */
163 #define REG_BB_FG 0x1018 /* Foreground color */
165 /* BitBlt status register bits */
166 #define BB_STAT_PROCESS (0x1<<31) /* 1 - processing operation, 0 - idle */
167 #define BB_STAT_FULL (0x1<<30) /* 1 - pipeline full */
168 #define BB_STAT_DMA (0x1<<26) /* DMA support */
171 #define BB_CTRL_CMD_MASK 0xC0000000
172 #define BB_CTRL_CMD_START (0x1<<31)
173 #define BB_CTRL_CMD_ABORT (0x1<<30)
175 #define BB_CTRL_HALFWORD_TWISTER (0x1<<24)
176 #define BB_CTRL_BYTES_TWISTER (0x1<<23)
177 #define BB_CTRL_BITS_IN_BYTE_TWISTER (0x1<<22)
179 #define BB_CTRL_DDMA_EN (0x1<<21)
180 #define BB_CTRL_SDMA_EN (0x1<<20)
181 #define BB_CTRL_SOFFS_MASK (0x7<<16)
183 /* Binary raster operations */
184 #define BB_CTRL_ROP_MASK 0x0000F000
186 #define BB_CTRL_ROP_0 (0x0<<12) /* clear */
187 #define BB_CTRL_ROP_AND (0x1<<12) /* and */
188 #define BB_CTRL_ROP_NOT_SRC_AND_DST (0x2<<12) /* andReverse */
189 #define BB_CTRL_ROP_DST (0x3<<12) /* copy */
190 #define BB_CTRL_ROP_SRC_AND_NOT_DST (0x4<<12) /* andInverted */
191 #define BB_CTRL_ROP_SRC (0x5<<12) /* noop */
192 #define BB_CTRL_ROP_XOR (0x6<<12) /* xor */
193 #define BB_CTRL_ROP_OR (0x7<<12) /* or */
194 #define BB_CTRL_ROP_NOR (0x8<<12) /* nor */
195 #define BB_CTRL_ROP_NXOR (0x9<<12) /* equiv */
196 #define BB_CTRL_ROP_NOT_SRC (0xa<<12) /* invert */
197 #define BB_CTRL_ROP_NOT_SRC_OR_DST (0xb<<12) /* orReverse */
198 #define BB_CTRL_ROP_NOT_DST (0xc<<12) /* copyInverted */
199 #define BB_CTRL_ROP_SRC_OR_NOT_DST (0xd<<12) /* orInverted */
200 #define BB_CTRL_ROP_NAND (0xe<<12) /* nand */
201 #define BB_CTRL_ROP_1 (0xf<<12) /* set */
204 #define BB_CTRL_HDIR (0x1<<5)
205 #define BB_CTRL_VDIR (0x1<<6)
207 #define BB_CTRL_CE_EN (0x1<<0)
208 #define BB_CTRL_PAT_EN (0x1<<1)
209 #define BB_CTRL_SFILL_EN (0x1<<2)
210 #define BB_CTRL_TR_EN (0x1<<4)
212 #define BB_CTRL_SRC_MODE (0x1<<7)
214 #define BB_CTRL_TERM_00 (0x0<<8)
215 #define BB_CTRL_TERM_01 (0x1<<8)
216 #define BB_CTRL_TERM_10 (0x2<<8)
219 #define BB_CTRL_BPP_8 (0x0<<10)
220 #define BB_CTRL_BPP_16 (0x1<<10)
221 #define BB_CTRL_BPP_24 (0x2<<10)
222 #define BB_CTRL_BPP_32 (0x3<<10)
224 #define BB_CTRL_BPP_CD_8 (BB_CTRL_BPP_8)
225 #define BB_CTRL_BPP_CD_16 (BB_CTRL_BPP_16 | 0x0800000)
226 #define BB_CTRL_BPP_CD_24 (BB_CTRL_BPP_24 | 0x1800000)
227 #define BB_CTRL_BPP_CD_32 (BB_CTRL_BPP_32 | 0x1800000)
228 #else /* __BIG_ENDIAN */
229 #define BB_CTRL_BPP_CD_8 BB_CTRL_BPP_8
230 #define BB_CTRL_BPP_CD_16 BB_CTRL_BPP_16
231 #define BB_CTRL_BPP_CD_24 BB_CTRL_BPP_24
232 #define BB_CTRL_BPP_CD_32 BB_CTRL_BPP_32
233 #endif /* __BIG_ENDIAN */
235 /*******************************************************************************
237 *******************************************************************************
239 static void MMIO_WRITE( struct mgam83fb_par
* p
, unsigned long reg
, uint32_t val
)
241 TRACE_MSG( "MMIO[0x%03lx] <= 0x%08x\n", reg
, val
);
243 switch( p
->vers
.bus
) {
245 writel( val
, (void*)((unsigned long)p
->mmio
.vbase
+ reg
) );
248 printk( KERN_WARNING
"Cannot write to mmio: unsupported MGA/M video card model!\n" );
251 TRACE_MSG( "Sleeping 10 msecs...\n" );
254 static uint32_t MMIO_READ( struct mgam83fb_par
* p
, unsigned long reg
)
258 switch( p
->vers
.bus
) {
260 result
= readl( (void*)((unsigned long) p
->mmio
.vbase
+ reg
) );
263 result
= ~(uint32_t)0;
264 printk( KERN_WARNING
"Cannot write to mmio: unsupported MGA/M video card model!\n" );
266 TRACE_MSG( "MMIO[0x%03lx] => 0x%08x\n", reg
, result
);
270 /*******************************************************************************
271 * External entry points
272 *******************************************************************************
275 static struct { struct fb_bitfield transp
, red
, green
, blue
; } ver_05_2009_colors
[] = {
276 { { 0, 0, 0}, { 0, 8, 0}, { 0, 8, 0}, { 0, 8, 0} }, // 8bpp
277 { { 0, 0, 0}, { 11, 5, 0}, { 5, 6, 0}, { 0, 5, 0} }, // 16bpp
278 #ifdef __LITTLE_ENDIAN
279 { { 0, 0, 0}, { 16, 8, 0}, { 8, 8, 0}, { 0, 8, 0} }, // 24bpp
280 #else /* __BIG_ENDIAN */
281 { { 0, 0, 0}, { 0, 8, 0}, { 8, 8, 0}, { 16, 8, 0} }, // 24bpp
283 { { 24, 8, 0}, { 16, 8, 0}, { 8, 8, 0}, { 0, 8, 0} }, // 32bpp
286 static struct { struct fb_bitfield transp
, red
, green
, blue
; } ver_old_colors
[] = {
287 #ifdef __LITTLE_ENDIAN
288 { { 0, 0, 0}, { 0, 8, 0}, { 0, 8, 0}, { 0, 8, 0} }, // 8bpp
289 { { 0, 0, 0}, { 11, 5, 0}, { 5, 6, 0}, { 0, 5, 0} }, // 16bpp
290 { { 0, 0, 0}, { 16, 8, 0}, { 8, 8, 0}, { 0, 8, 0} }, // 24bpp
291 { { 0, 8, 0}, { 8, 8, 0}, {16, 8, 0}, {24, 8, 0} }, // 32bpp
293 { { 0, 0, 0}, { 0, 8, 0}, { 0, 8, 0}, { 0, 8, 0} }, // 8bpp
294 { { 0, 0, 0}, { 11, 5, 0}, { 5, 6, 0}, { 0, 5, 0} }, // 16bpp
295 { { 0, 0, 0}, { 0, 8, 0}, { 8, 8, 0}, {16, 8, 0} }, // 24bpp
296 { { 24, 8, 0}, { 16, 8, 0}, { 8, 8, 0}, { 0, 8, 0} }, // 32bpp
297 #endif /* __LITTLE_ENDIAN */
300 static struct { struct fb_bitfield transp
, red
, green
, blue
; } colors
[4];
302 void set_up_colors_bounds(struct mgam83fb_par
* p
)
304 printk("entering set_up_colors bounds routine, revision = %d\n",
306 if (p
->vers
.revision
>= VER_05_2009
307 && p
->vers
.revision
!= MGA_MODEL_PMUP2_0
308 && p
->vers
.revision
!= MGA_MODEL_PMUP2_1
) {
309 printk("using ver_05_2009_colors map\n");
310 memcpy(colors
, ver_05_2009_colors
, sizeof(colors
));
312 printk("using ver_old_colors map\n");
313 memcpy(colors
, ver_old_colors
, sizeof(colors
));
318 static int mgam83fb_check_var(struct fb_var_screeninfo
* var
, struct fb_info
* info
)
320 struct mgam83fb_par
* p
= (struct mgam83fb_par
*)info
->par
;
321 int colors_index
= (var
->bits_per_pixel
>>3) - 1; // Index in colors table
323 DEBUG_MSG("mgam83fb: mgam83fb_check_var start\n");
324 if ( (var
->vmode
& FB_VMODE_MASK
) == FB_VMODE_INTERLACED
) {
325 INFO_MSG( "mode %dx%dx%d rejected, interlaced not supported\n",
326 var
->xres
, var
->yres
, var
->bits_per_pixel
);
330 if ( var
->bits_per_pixel
!= 8 &&
331 var
->bits_per_pixel
!= 16 &&
332 var
->bits_per_pixel
!= 24 &&
333 var
->bits_per_pixel
!= 32 )
335 INFO_MSG( "mode %dx%dx%d rejected, color depth invalid\n",
336 var
->xres
, var
->yres
, var
->bits_per_pixel
);
337 printk("mgam83fb: mgam83fb_check_var finish with error\n");
341 if (var
->xres_virtual
* var
->yres_virtual
* ( var
->bits_per_pixel
>> 3) > p
->mem
.len
) {
342 INFO_MSG( "mode %dx%dx%d rejected, not enough memory\n",
343 var
->xres
, var
->yres
, var
->bits_per_pixel
);
344 printk("mgam83fb: mgam83fb_check_var finish with error\n");
348 var
->red
= colors
[colors_index
].red
;
349 var
->green
= colors
[colors_index
].green
;
350 var
->blue
= colors
[colors_index
].blue
;
351 var
->transp
= colors
[colors_index
].transp
;
352 DEBUG_MSG("mgam83fb: mgam83fb_check_var finish\n");
357 static int __set_mode(struct mgam83fb_par
*p
)
359 struct fb_info
*info
= p
->info
;
360 struct fb_var_screeninfo
*var
= &info
->var
;
361 int hsync
= p
->hsync_len
; // The Horizontal Syncronization Time (Sync Pulse )
362 int hgdel
= p
->left_margin
; // The Horizontal Gate Delay Time (Back Porch)
363 int hgate
= p
->xres
; // The Horizontal Gate Time (Active Time)
364 int hlen
= hsync
+ hgdel
+ hgate
+ p
->right_margin
; // The Horizontal Length Time (Line Total)
365 int vsync
= p
->vsync_len
; // The Vertical Syncronization Time (Sync Pulse )
366 int vgdel
= p
->upper_margin
; // The Vertical Gate Delay Time (Back Porch)
367 int vgate
= p
->yres
; // The Vertical Gate Time (Active Time)
368 int vlen
= vsync
+ vgdel
+ vgate
+ p
->lower_margin
; // The Vertical Length Time (Frame total)
369 int vbl
= CTRL_VBL1024
; // Video Memory Burst Length
370 int ctrl
= CTRL_BL_NEG
| vbl
;
375 /* MGA device always works in little endian mode */
376 switch( p
->bits_per_pixel
) {
378 ctrl
|= CTRL_CD_8BPP
| CTRL_PC_PSEUDO
;
381 ctrl
|= CTRL_CD_16BPP
;
382 if (p
->vers
.revision
>= VER_05_2009
383 && p
->vers
.revision
!= MGA_MODEL_PMUP2_0
384 && p
->vers
.revision
!= MGA_MODEL_PMUP2_1
){
385 #ifdef __LITTLE_ENDIAN
386 /* Turn off bytes-in-half word twister (seted by default) */
387 ctrl
|= CTRL_IN_WORDS16_TWISTER
;
392 ctrl
|= CTRL_CD_24BPP
;
393 DEBUG_MSG("mga: revision = %d\n", p
->vers
.revision
);
394 if (p
->vers
.revision
>= VER_05_2009
395 && p
->vers
.revision
!= MGA_MODEL_PMUP2_0
396 && p
->vers
.revision
!= MGA_MODEL_PMUP2_1
){
397 #ifndef __LITTLE_ENDIAN
398 DEBUG_MSG("mga: New version! not __LE\n");
399 DEBUG_MSG("ctrl to setup is 0x%x\n", ctrl
);
404 ctrl
|= CTRL_CD_32BPP
;
405 if (p
->vers
.revision
>= VER_05_2009
406 && p
->vers
.revision
!= MGA_MODEL_PMUP2_0
407 && p
->vers
.revision
!= MGA_MODEL_PMUP2_1
){
408 #ifdef __LITTLE_ENDIAN
409 /* Turn off half words twister (seted by default ) */
410 ctrl
|= CTRL_WORDS16_IN_WORDS32_TWISTER
;
411 /* Turn off bytes-in-half word twister (seted by default) */
412 ctrl
|= CTRL_IN_WORDS16_TWISTER
;
417 ERROR_MSG( "Invalid color depth: %s %s %d\n", __FILE__
, __FUNCTION__
, __LINE__
);
422 ctrl
|= ( p
->sync
& FB_SYNC_COMP_HIGH_ACT
) ? CTRL_CSYNC_HIGH
: CTRL_CSYNC_LOW
;
423 ctrl
|= ( p
->sync
& FB_SYNC_VERT_HIGH_ACT
) ? CTRL_VSYNC_HIGH
: CTRL_VSYNC_LOW
;
424 ctrl
|= ( p
->sync
& FB_SYNC_HOR_HIGH_ACT
) ? CTRL_HSYNC_HIGH
: CTRL_HSYNC_LOW
;
426 hsync
--, hgdel
--, hgate
--, vsync
--, vgdel
--, vgate
--, hlen
--, vlen
--;
428 MMIO_WRITE( p
, REG_CTRL
, ctrl
);
431 MMIO_WRITE( p
, REG_HTIM
, hsync
<< 24 | hgdel
<< 16 | hgate
);
433 MMIO_WRITE( p
, REG_VTIM
, vsync
<< 24 | vgdel
<< 16 | vgate
);
435 MMIO_WRITE( p
, REG_HVLEN
, hlen
<< 16 | vlen
);
437 MMIO_WRITE(p
, REG_VBARa
, var
->yoffset
* info
->fix
.line_length
);
439 DEBUG_MSG( "hsync: %d hgdel: %d hgate %d\n", hsync
, hgdel
, hgate
);
440 DEBUG_MSG( "vsync: %d vgdel: %d vgate %d\n", vsync
, vgdel
, vgate
);
441 DEBUG_MSG( "hlen: %d vlen: %d\n", hlen
, vlen
);
443 MMIO_WRITE(p
, REG_CTRL
, ctrl
| CTRL_VEN
);
451 # define DEBUG_MSG_SET_PAR_MODE 0
453 # define DEBUG_MSG_SET_PAR_MODE 0
455 #if DEBUG_MSG_SET_PAR_MODE
456 # define DEBUG_MSG_SET_PAR prom_printf
458 # define DEBUG_MSG_SET_PAR(...)
461 static int mgam83fb_set_par(struct fb_info
* info
)
463 struct fb_var_screeninfo
* mode
= &info
->var
;
464 struct mgam83fb_par
* p
= (struct mgam83fb_par
*)info
->par
;
468 DEBUG_MSG_SET_PAR("mgam83fb_set_par: start\n");
470 info
->fix
.visual
= (mode
->bits_per_pixel
== 8) ? FB_VISUAL_PSEUDOCOLOR
: FB_VISUAL_TRUECOLOR
;
471 info
->fix
.line_length
= mode
->xres_virtual
* (mode
->bits_per_pixel
>> 3) ;
474 p
->xres
= mode
->xres
;
475 DEBUG_MSG_SET_PAR("mgam83fb_set_par: p->xres = 0x%x\n", p
->xres
);
476 p
->yres
= mode
->yres
;
477 DEBUG_MSG_SET_PAR("mgam83fb_set_par: p->yres = 0x%x\n", p
->yres
);
478 p
->xres_virtual
= mode
->xres_virtual
;
479 DEBUG_MSG_SET_PAR("mgam83fb_set_par: p->xres_virtual = 0x%x\n", p
->xres_virtual
);
480 p
->yres_virtual
= mode
->yres_virtual
;
481 DEBUG_MSG_SET_PAR("mgam83fb_set_par: p->yres_virtual = 0x%x\n", p
->yres_virtual
);
482 p
->xoffset
= mode
->xoffset
;
483 DEBUG_MSG_SET_PAR("mgam83fb_set_par: p->xoffset = 0x%x\n", p
->xoffset
);
484 p
->yoffset
= mode
->yoffset
;
485 DEBUG_MSG_SET_PAR("mgam83fb_set_par: p->yoffset = 0x%x\n", p
->yoffset
);
486 p
->left_margin
= mode
->left_margin
;
487 DEBUG_MSG_SET_PAR("mgam83fb_set_par: p->left_margin = 0x%x\n", p
->left_margin
);
488 p
->right_margin
= mode
->right_margin
;
489 DEBUG_MSG_SET_PAR("mgam83fb_set_par: p->right_margin = 0x%x\n", p
->right_margin
);
490 p
->hsync_len
= mode
->hsync_len
;
491 DEBUG_MSG_SET_PAR("mgam83fb_set_par: p->hsync_len = 0x%x\n", p
->hsync_len
);
492 p
->upper_margin
= mode
->upper_margin
;
493 DEBUG_MSG_SET_PAR("mgam83fb_set_par: p->upper_margin = 0x%x\n", p
->upper_margin
);
494 p
->lower_margin
= mode
->lower_margin
;
495 DEBUG_MSG_SET_PAR("mgam83fb_set_par: p->lower_margin = 0x%x\n", p
->lower_margin
);
496 p
->vsync_len
= mode
->vsync_len
;
497 DEBUG_MSG_SET_PAR("mgam83fb_set_par: p->vsync_len = 0x%x\n", p
->vsync_len
);
498 p
->bits_per_pixel
= mode
->bits_per_pixel
;
499 DEBUG_MSG_SET_PAR("mgam83fb_set_par: p->bits_per_pixel = 0x%x\n", p
->bits_per_pixel
);
500 p
->pixclock
= mode
->pixclock
;
501 DEBUG_MSG_SET_PAR("mgam83fb_set_par: p->pixclock = 0x%x\n", p
->pixclock
);
502 DEBUG_MSG_SET_PAR("mgam83fb_set_par: p->sync = 0x%x\n", p
->sync
);
507 DEBUG_MSG_SET_PAR( KERN_DEBUG
" xres:%d yres:%d xvirt:%d yvirt:%d bpp:%d\n",
509 p
->xres_virtual
, p
->yres_virtual
, p
->bits_per_pixel
);
510 DEBUG_MSG_SET_PAR( KERN_DEBUG
" pixclock:%d left:%d right:%d upper:%d "
511 "lower:%d hslen:%d vslen:%d\n",
512 p
->pixclock
, p
->left_margin
, p
->right_margin
,
513 p
->upper_margin
, p
->lower_margin
,
514 p
->hsync_len
, p
->vsync_len
);
516 /* Turning of display*/
517 MMIO_WRITE(p
, REG_CTRL
, MMIO_READ(p
, REG_CTRL
) & ~CTRL_VEN
);
520 __set_pixclock( &p
->vers
, (unsigned long)p
->i2c
.vbase
, p
->pixclock
);
528 DEBUG_MSG_SET_PAR("mgam83fb_set_par finish\n");
533 static int mgam83_get_cmap_len(int bpp
)
536 case 8: return 256; /* pseudocolor... 256 entries HW palette */
539 case 32: return 16; /* directcolor... 16 entries SW palette */
544 static inline u16
flip_16 (u16 l
)
546 return ((l
&0xff)<<8) | ((l
>>8)&0xff);
549 static int mgam83fb_setcolreg(unsigned regno
, unsigned red
, unsigned green
,
550 unsigned blue
, unsigned transp
,
551 struct fb_info
*info
)
553 struct mgam83fb_par
* p
= (struct mgam83fb_par
*)info
->par
;
556 DEBUG_MSG("mgam83fb_setcolreg start\n");
557 if (regno
>= mgam83_get_cmap_len(p
->bits_per_pixel
)){ /* no. of hw registers */
558 DEBUG_MSG("mgam83fb: mgam83fb_setcolreg finish with error\n");
561 /* grayscale works only partially under directcolor */
562 if (info
->var
.grayscale
) {
563 /* grayscale = 0.30*R + 0.59*G + 0.11*B */
564 red
= green
= blue
= (red
* 77 + green
* 151 + blue
* 28) >> 8;
567 red
>>= (16 - info
->var
.red
.length
);
568 green
>>= (16 - info
->var
.green
.length
);
569 blue
>>= (16 - info
->var
.blue
.length
);
570 transp
>>= (16 - info
->var
.transp
.length
);
572 if (info
->fix
.visual
== FB_VISUAL_PSEUDOCOLOR
) {
573 uint32_t val
= (red
<< 16) | (green
<< 8) | blue
;
574 DEBUG_MSG("Using pseudocolors\n");
577 MMIO_WRITE( p
, 0x800 + regno
* 4, val
);
580 /* Truecolor has hardware independent palette */
581 if (info
->fix
.visual
== FB_VISUAL_TRUECOLOR
) {
584 DEBUG_MSG("Using truecolors\n");
586 INFO_MSG("mgam83fb_setcolreg finish "
587 "with error, regno = 0x%x\n", regno
);
591 v
= (red
<< info
->var
.red
.offset
) |
592 (green
<< info
->var
.green
.offset
) |
593 (blue
<< info
->var
.blue
.offset
) |
594 (transp
<< info
->var
.transp
.offset
);
595 DEBUG_MSG("setcolreg: red off = %d, green off = %d,"
596 "blue off = %d, v = 0x%x\n", info
->var
.red
.offset
,
597 info
->var
.green
.offset
, info
->var
.blue
.offset
, v
);
598 if (p
->vers
.revision
< VER_05_2009
){
599 #ifdef __LITTLE_ENDIAN
600 if (p
->bits_per_pixel
== 16){
607 // 16bpp, 24bpp or 32bpp
609 ((u32
*)(info
->pseudo_palette
))[regno
] = v
;
612 DEBUG_MSG("mgam83fb_setcolreg finish\n");
617 unsigned long phys_addr
; /* dma addr */
622 u32 phys_addr
; /* dma addr */
627 unsigned long phys_addr
; /* dma addr */
631 struct ker_dma_mem
*next
;
634 #define FBIOALLOC_DMA_MEM 0x4631
635 #define FBIOFREE_ALL_DMA_MEMS 0x4632
636 #define FBIOWHOAMI 0x4633
638 #define DEBUG_IOCTL_MSG_ON 0
639 #define DEBUG_IOCTL_MSG if (DEBUG_IOCTL_MSG_ON) printk
642 mgam83fb_ioctl(struct fb_info
*info
,
643 unsigned int cmd
, unsigned long arg
)
648 struct page
*map
, *mapend
;
649 struct mgam83fb_par
* par
= (struct mgam83fb_par
*)info
->par
;
650 void __user
*argp
= (void __user
*)arg
;
652 DEBUG_IOCTL_MSG("mgam83fb_ioctl: cmd = 0x%x\n", cmd
);
656 case FBIOALLOC_DMA_MEM
:
657 if (!par
->video_buf
.ioaddr
) {
658 if (copy_from_user(&dmem
, argp
, sizeof(dmem
))) {
659 DEBUG_IOCTL_MSG("mgam83fb_ioctl: can't copy_from_user\n");
662 DEBUG_IOCTL_MSG("mgam83fb_ioctl: Ask to alloc 0x%lx bytes\n", (unsigned long)dmem
.size
);
663 order
= get_order(dmem
.size
);
664 if (order
>= MAX_ORDER
) {
665 DEBUG_IOCTL_MSG("mgam83fb_ioctl: order fail\n");
668 DEBUG_IOCTL_MSG("mgam83fb_ioctl: order = %d\n", order
);
669 kvaddr
= (void *)__get_free_pages(GFP_KERNEL
| GFP_DMA
, order
);
672 DEBUG_IOCTL_MSG("mgam83fb_ioctl: failed to alloc dma buffer\n");
675 mapend
= virt_to_page (kvaddr
+ (PAGE_SIZE
<< order
) - 1);
676 for (map
= virt_to_page(kvaddr
); map
<= mapend
; map
++) {
677 SetPageReserved(map
);
679 par
->video_buf
.ioaddr
= pci_map_single(par
->pdev
, (void *)kvaddr
, dmem
.size
,
680 PCI_DMA_BIDIRECTIONAL
);
682 par
->video_buf
.kvaddr
= kvaddr
;
683 dmem
.phys_addr
= par
->video_buf
.ioaddr
;
684 par
->video_buf
.size
= dmem
.size
;
686 dmem
.size
= par
->video_buf
.size
;
687 dmem
.phys_addr
= par
->video_buf
.ioaddr
;
689 DEBUG_IOCTL_MSG("FBIOALLOC_DMA_MEM: kvaddr = 0x%08lx; dmem.phys_addr = 0x%08lx\n",
690 (unsigned long)par
->video_buf
.kvaddr
, dmem
.phys_addr
);
692 if (copy_to_user(argp
, &dmem
, sizeof(dmem
))){
693 DEBUG_IOCTL_MSG("mgam83fb_ioctl: failed to copy_to_user\n");
698 DEBUG_IOCTL_MSG("Unsupported cmd 0x%x\n", cmd
);
706 mgam83fb_compat_ioctl(struct fb_info
*info
, unsigned int cmd
,
709 unsigned long kvaddr
;
710 struct dma_mem32 dmem
;
712 struct page
*map
, *mapend
;
713 struct mgam83fb_par
* par
= (struct mgam83fb_par
*)info
->par
;
714 void __user
*argp
= (void __user
*)arg
;
719 case FBIOALLOC_DMA_MEM
:
720 if (!par
->video_buf
.ioaddr
) {
721 if (copy_from_user(&dmem
, argp
, sizeof(dmem
))) {
724 DEBUG_IOCTL_MSG("mgam83fbicompat__ioctl: Ask to alloc 0x%x bytes\n", dmem
.size
);
725 order
= get_order(dmem
.size
);
726 if (order
>= MAX_ORDER
) {
727 DEBUG_IOCTL_MSG("mgam83fb_ioctl: order fail\n");
731 kvaddr
= __get_free_pages(GFP_KERNEL
| GFP_DMA
, order
);
734 DEBUG_IOCTL_MSG("mgam83fb_compat__ioctl: failed to alloc dma buffer\n");
737 mapend
= virt_to_page (kvaddr
+ (PAGE_SIZE
<< order
) - 1);
738 for (map
= virt_to_page(kvaddr
); map
<= mapend
; map
++) {
739 SetPageReserved(map
);
741 par
->video_buf
.ioaddr
= pci_map_single(par
->pdev
, (void *)kvaddr
, dmem
.size
,
742 PCI_DMA_BIDIRECTIONAL
);
743 par
->video_buf
.kvaddr
= (void *) kvaddr
;
744 par
->video_buf
.size
= dmem
.size
;
745 dmem
.phys_addr
= (u32
)par
->video_buf
.ioaddr
;
747 dmem
.size
= par
->video_buf
.size
;
748 dmem
.phys_addr
= (u32
)par
->video_buf
.ioaddr
;
750 DEBUG_IOCTL_MSG("FBIOALLOC_DMA_MEM: kvaddr = 0x%08lx; dmem.phys_addr = 0x%08x / 0x%08lx\n",
751 (unsigned long)par
->video_buf
.kvaddr
, dmem
.phys_addr
, par
->video_buf
.ioaddr
);
753 if (copy_to_user(argp
, &dmem
, sizeof(dmem
))){
754 DEBUG_IOCTL_MSG("mgam83fb_compat_ioctl: failed to copy_to_user\n");
764 #define DEBUG_MMAP_MSG_ON 0
765 #define DEBUG_MMAP_MSG if (DEBUG_MMAP_MSG_ON) printk
767 static int mgam83fb_mmap(struct fb_info
*info
, struct vm_area_struct
*vma
)
771 struct mgam83fb_par
* p
= (struct mgam83fb_par
*)info
->par
;
775 off
= vma
->vm_pgoff
<< PAGE_SHIFT
;
777 vma
->vm_pgoff
= off
>> PAGE_SHIFT
;
778 /* frame buffer memory */
779 start
= info
->fix
.smem_start
;
780 len
= PAGE_ALIGN((start
& ~PAGE_MASK
) + info
->fix
.smem_len
);
781 DEBUG_MMAP_MSG("mgam83fb_mmap: start = 0x%lx, off = 0x%lx, len = 0x%x\n",
783 /* off that's in range of 0..."fb len" corresponds to framebuffer */
784 /* off that's in range of "fb len"..."io len" corresponds to mmio */
786 DEBUG_MMAP_MSG("mgam83fb_mmap: given off corresponds to fbmem\n");
788 vma
->vm_page_prot
= (cpu_has(CPU_FEAT_WC_PCI_PREFETCH
)) ?
789 pgprot_writecombine(vma
->vm_page_prot
) :
790 pgprot_noncached(vma
->vm_page_prot
);
794 if ((off
>= len
) && (off
< 0x80000000)) {
795 /* memory mapped io */
796 DEBUG_MMAP_MSG("mgam83fb_mmap: given off corresponds to mmio\n");
798 start
= info
->fix
.mmio_start
;
799 len
= PAGE_ALIGN((start
& ~PAGE_MASK
) + info
->fix
.mmio_len
);
801 vma
->vm_page_prot
= pgprot_noncached(vma
->vm_page_prot
);
805 if (off
>= 0x80000000) {
806 if (vma
->vm_end
- vma
->vm_start
> p
->video_buf
.size
) {
807 DEBUG_MMAP_MSG("%s: Len to map too big 0x%x > 0x%x\n",
808 __FUNCTION__
, len
, p
->video_buf
.size
);
811 if (!p
->video_buf
.ioaddr
) {
812 DEBUG_MMAP_MSG("%s: Video buf not allocated\n", __FUNCTION__
);
815 off
= virt_to_phys(p
->video_buf
.kvaddr
);
816 DEBUG_MMAP_MSG("%s: dvma_pha = 0x%08lx\n", __FUNCTION__
, off
);
817 vma
->vm_pgoff
= off
>> PAGE_SHIFT
;
818 vma
->vm_flags
|= VM_IO
;
820 if (vma
->vm_flags
& VM_WRITECOMBINED
)
822 pgprot_writecombine(vma
->vm_page_prot
);
824 if (remap_pfn_range(vma
, vma
->vm_start
,
826 vma
->vm_end
- vma
->vm_start
, vma
->vm_page_prot
)) {
827 DEBUG_MMAP_MSG("Mapping failed\n");
831 DEBUG_MMAP_MSG("mgam83fb_mmap: mapping done successfully"
832 " to addr 0x%08lx\n", vma
->vm_start
);
837 if ((off
+ vma
->vm_end
- vma
->vm_start
) > len
)
841 vma
->vm_pgoff
= off
>> PAGE_SHIFT
;
842 /* This is an IO map - tell maydump to skip this VMA */
843 vma
->vm_flags
|= VM_IO
| VM_IO
;
845 #if !defined(__e2k__)
846 vma
->vm_page_prot
= pgprot_noncached(vma
->vm_page_prot
);
849 DEBUG_MMAP_MSG("%s: mapping iospace 0x%08lx to 0x%08lx - 0x%08lx\n",
850 __FUNCTION__
, off
, vma
->vm_start
, vma
->vm_end
);
852 pfn
= MK_IOSPACE_PFN(0xa, (off
>> PAGE_SHIFT
));
854 pfn
= off
>> PAGE_SHIFT
;
856 if (io_remap_pfn_range(vma
, vma
->vm_start
, pfn
,
857 vma
->vm_end
- vma
->vm_start
, vma
->vm_page_prot
)) {
858 DEBUG_MMAP_MSG("Mapping failed\n");
866 unsigned long virt_addr
;
871 static unsigned int rnum
= 0;
872 static struct dma_image d_image
[2];
875 static inline void mgam83fb_do_sync(struct mgam83fb_par
*p
)
877 while (MMIO_READ(p
, BBR0
) & PROCESS
)
881 #ifdef CONFIG_MGA_HWIMAGEBLIT
883 #define FB_WRITEL fb_writel
884 #define FB_READL fb_readl
887 static int expand_dma_buf(struct pci_dev
*dev
, struct dma_image
*d
,
890 struct page
*map
, *mapend
;
893 /* Free previous allocated pages */
895 mapend
= virt_to_page(d
->virt_addr
+ d
->size
- 1);
897 for (map
= virt_to_page(d
->virt_addr
); map
<= mapend
; map
++)
898 ClearPageReserved(map
);
900 pci_unmap_single(dev
, d
->dma_addr
, d
->size
, PCI_DMA_FROMDEVICE
);
901 free_pages(d
->virt_addr
, get_order(d
->size
));
904 /* Allocate new pages */
905 order
= get_order(size
);
906 size
= PAGE_SIZE
<< order
;
908 d
->virt_addr
= __get_free_pages(GFP_KERNEL
| GFP_DMA
, order
);
912 mapend
= virt_to_page(d
->virt_addr
+ size
- 1);
913 for (map
= virt_to_page(d
->virt_addr
); map
<= mapend
; map
++)
914 SetPageReserved(map
);
915 d
->dma_addr
= pci_map_single(dev
, (void *)d
->virt_addr
,
916 size
, PCI_DMA_FROMDEVICE
);
917 if (pci_dma_mapping_error(dev
, d
->dma_addr
))
925 for (map
= virt_to_page(d
->virt_addr
); map
<= mapend
; map
++)
926 ClearPageReserved(map
);
928 free_pages(d
->virt_addr
, order
);
936 static void mgam83fb_imageblit(struct fb_info
*p
, const struct fb_image
*image
)
938 struct mgam83fb_par
* par
= (struct mgam83fb_par
*)p
->par
;
939 u32 fgcolor
, bgcolor
;
940 u32 Bpp
= p
->var
.bits_per_pixel
/ 8;
941 u32 dx
, dy
, width
, height
;
943 unsigned line_length
; /* bytes per line */
944 u32 dst_idx
, src_idx
;
947 unsigned ctrl
= BB_CTRL_CE_EN
| BB_CTRL_SDMA_EN
|
948 BB_CTRL_CMD_START
| BB_CTRL_ROP_SRC
|
949 BB_CTRL_SRC_MODE
| BITS_IN_BYTE_TWISTER
;
951 if (p
->state
!= FBINFO_STATE_RUNNING
)
954 if (par
->vers
.revision
< VER_05_2009
||
955 par
->vers
.revision
== MGA_MODEL_PMUP2_0
||
956 par
->vers
.revision
== MGA_MODEL_PMUP2_1
) {
957 cfb_imageblit(p
, image
);
961 if (par
->dma_not_supported
) {
962 cfb_imageblit(p
, image
);
966 if ((p
->flags
& FBINFO_HWACCEL_DISABLED
)) {
967 cfb_imageblit(p
, image
);
973 cbpp
= BB_CTRL_BPP_32
;
976 cbpp
= BB_CTRL_BPP_24
;
979 cbpp
= BB_CTRL_BPP_16
;
982 cbpp
= BB_CTRL_BPP_8
;
991 width
= image
->width
;
992 height
= image
->height
;
994 size
= width
* height
* Bpp
; /* Size in bytes */
996 if (d_image
[rnum
].size
< size
) {
997 if (expand_dma_buf(par
->pdev
, &d_image
[rnum
], size
)) {
998 cfb_imageblit(p
, image
);
1003 st
= (u8
*)d_image
[rnum
].virt_addr
;
1004 sf
= (u8
*)image
->data
;
1006 mgam83fb_do_sync(par
);
1008 memcpy(st
, sf
, size
);
1010 line_length
= p
->var
.xres_virtual
* Bpp
;
1011 src_idx
= d_image
[rnum
].dma_addr
;
1012 dst_idx
= dy
* line_length
+ dx
* Bpp
;
1014 if (p
->fix
.visual
== FB_VISUAL_TRUECOLOR
||
1015 p
->fix
.visual
== FB_VISUAL_DIRECTCOLOR
) {
1016 fgcolor
= ((u32
*)(p
->pseudo_palette
))[image
->fg_color
];
1017 bgcolor
= ((u32
*)(p
->pseudo_palette
))[image
->bg_color
];
1019 fgcolor
= image
->fg_color
;
1020 bgcolor
= image
->bg_color
;
1023 MMIO_WRITE(par
, REG_BB_FG
, fgcolor
);
1024 MMIO_WRITE(par
, REG_BB_BG
, bgcolor
);
1025 MMIO_WRITE(par
, BBR1
, ((height
<< 16) | width
* Bpp
));
1026 MMIO_WRITE(par
, BBR2
, src_idx
);
1027 MMIO_WRITE(par
, BBR3
, dst_idx
);
1028 MMIO_WRITE(par
, BBR4
, (line_length
<< 16));
1032 MMIO_WRITE(par
, BBR0
, ctrl
);
1038 #ifdef CONFIG_MGA_HWCOPYAREA
1039 static void mgam83fb_copyarea(struct fb_info
*info
, const struct fb_copyarea
*region
)
1041 struct mgam83fb_par
* p
= (struct mgam83fb_par
*)info
->par
;
1042 unsigned int line_length
= info
->var
.xres_virtual
* (info
->var
.bits_per_pixel
>> 3); /* Bytes */
1043 unsigned int command
= 0;
1044 struct fb_copyarea modded
;
1045 u32 dx
= region
->dx
, dy
= region
->dy
;
1046 u32 sx
= region
->sx
, sy
= region
->sy
;
1047 int dst_idx
= 0, src_idx
= 0;
1048 u32 spitch
= line_length
;
1049 u32 dpitch
= line_length
;
1054 modded
.width
= region
->width
;
1055 modded
.height
= region
->height
;
1057 if ((info
->flags
& FBINFO_HWACCEL_DISABLED
)) {
1058 cfb_copyarea(info
, region
);
1062 vxres
= info
->var
.xres_virtual
;
1063 vyres
= info
->var
.yres_virtual
;
1065 if(!region
->width
|| !region
->height
||
1066 sx
>= vxres
|| sy
>= vyres
||
1067 dx
>= vxres
|| dy
>= vyres
)
1070 if(sx
+ modded
.width
> vxres
) modded
.width
= vxres
- sx
;
1071 if(dx
+ modded
.width
> vxres
) modded
.width
= vxres
- dx
;
1072 if(sy
+ modded
.height
> vyres
) modded
.height
= vyres
- sy
;
1073 if(dy
+ modded
.height
> vyres
) modded
.height
= vyres
- dy
;
1075 width
= ((modded
.width
)*(info
->var
.bits_per_pixel
>> 3)); /* window lenght in bytes */
1076 height
= modded
.height
; /* number of lines */
1082 dst_idx
= dy
*line_length
+ dx
*(info
->var
.bits_per_pixel
>> 3); /* Bytes */
1083 src_idx
= sy
*line_length
+ sx
*(info
->var
.bits_per_pixel
>> 3); /* Bytes */
1085 mgam83fb_do_sync(p
);
1087 MMIO_WRITE(p
, BBR1
, ((height
<< 16) | width
));
1088 MMIO_WRITE(p
, BBR2
, src_idx
);
1089 MMIO_WRITE(p
, BBR3
, dst_idx
);
1090 MMIO_WRITE(p
, BBR4
, ((dpitch
<< 16) | spitch
));
1092 command
|= (ROP_05
| START
);
1097 MMIO_WRITE(p
, BBR0
, command
);
1103 * fb_blank - NOT a required function. Blanks the display.
1104 * @blank_mode: the blank mode we want.
1105 * @info: frame buffer structure that represents a single frame buffer
1107 * Blank the screen if blank_mode != FB_BLANK_UNBLANK, else unblank.
1108 * Return 0 if blanking succeeded, != 0 if un-/blanking failed due to
1109 * e.g. a video mode which doesn't support it.
1111 * Implements VESA suspend and powerdown modes on hardware that supports
1112 * disabling hsync/vsync:
1114 * FB_BLANK_NORMAL = display is blanked, syncs are on.
1115 * FB_BLANK_HSYNC_SUSPEND = hsync off
1116 * FB_BLANK_VSYNC_SUSPEND = vsync off
1117 * FB_BLANK_POWERDOWN = hsync and vsync off
1119 * If implementing this function, at least support FB_BLANK_UNBLANK.
1120 * Return !0 for any modes that are unimplemented.
1123 static int mgam83fb_blank(int blank
, struct fb_info
*info
)
1125 struct mgam83fb_par
*p
= (struct mgam83fb_par
*)info
->par
;
1126 u32 val
= MMIO_READ(p
, REG_CTRL
);
1129 case FB_BLANK_UNBLANK
: /* Unblanking */
1133 case FB_BLANK_NORMAL
: /* Normal blanking */
1134 case FB_BLANK_VSYNC_SUSPEND
: /* VESA blank (vsync off) */
1135 case FB_BLANK_HSYNC_SUSPEND
: /* VESA blank (hsync off) */
1136 case FB_BLANK_POWERDOWN
: /* Poweroff */
1141 MMIO_WRITE(p
, REG_CTRL
, val
);
1146 * fb_fillrect - REQUIRED function. Can use generic routines if
1147 * non acclerated hardware and packed pixel based.
1148 * Draws a rectangle on the screen.
1150 * @info: frame buffer structure that represents a single frame buffer
1151 * @region: The structure representing the rectangular region we
1154 * This drawing operation places/removes a retangle on the screen
1155 * depending on the rastering operation with the value of color which
1156 * is in the current color depth format.
1158 void mgam83fb_fillrect(struct fb_info
*info
, const struct fb_fillrect
*rect
)
1160 struct fb_var_screeninfo
*var
= &info
->var
;
1161 struct mgam83fb_par
*p
= (struct mgam83fb_par
*)info
->par
;
1163 u32 x
= rect
->dx
; u32 y
= rect
->dy
;
1164 u32 height
= rect
->height
; u32 width
= rect
->width
;
1165 u32 pitch
= info
->fix
.line_length
;
1166 u32 Bpp
= info
->var
.bits_per_pixel
>> 3;
1168 u32 color
= (Bpp
== 1) ? rect
->color
:
1169 ((u32
*) info
->pseudo_palette
)[rect
->color
];
1170 u32 rop
= (rect
->rop
!= ROP_COPY
) ? BB_CTRL_ROP_XOR
: BB_CTRL_ROP_SRC
;
1172 u32 ctrl
= rop
| BB_CTRL_CE_EN
| BB_CTRL_SFILL_EN
1173 | ((Bpp
- 1) & 0x3) << 10;
1175 u32 daddr
= var
->yoffset
* pitch
+ y
* pitch
+ x
* Bpp
;
1177 mgam83fb_do_sync(p
);
1179 MMIO_WRITE(p
, REG_BB_FG
, color
);
1180 MMIO_WRITE(p
, REG_BB_WINDOW
, (height
<< 16) | (width
* Bpp
));
1181 MMIO_WRITE(p
, REG_BB_DADDR
, daddr
);
1182 MMIO_WRITE(p
, REG_BB_PITCH
, pitch
<< 16 | 0);
1183 MMIO_WRITE(p
, REG_BB_CTRL
, ctrl
| BB_CTRL_CMD_START
);
1187 * pan_display - NOT a required function. Pans the display.
1188 * @var: frame buffer variable screen structure
1189 * @info: frame buffer structure that represents a single frame buffer
1191 * Pan (or wrap, depending on the `vmode' field) the display using the
1192 * `xoffset' and `yoffset' fields of the `var' structure.
1193 * If the values don't fit, return -EINVAL.
1195 * Returns negative errno on error, or zero on success.
1197 static int mgam83fb_pan_display(struct fb_var_screeninfo
*var
,
1198 struct fb_info
*info
)
1200 struct mgam83fb_par
*p
= (struct mgam83fb_par
*)info
->par
;
1201 u32 addr
= var
->yoffset
* info
->fix
.line_length
;
1205 MMIO_WRITE(p
, REG_VBARa
, addr
);
1210 * fb_sync - NOT a required function. Normally the accel engine
1211 * for a graphics card take a specific amount of time.
1212 * Often we have to wait for the accelerator to finish
1213 * its operation before we can write to the framebuffer
1214 * so we can have consistent display output.
1216 * @info: frame buffer structure that represents a single frame buffer
1218 * If the driver has implemented its own hardware-based drawing function,
1219 * implementing this function is highly recommended.
1222 static int mgam83fb_sync(struct fb_info
*info
)
1224 struct mgam83fb_par
*p
= (struct mgam83fb_par
*)info
->par
;
1225 mgam83fb_do_sync(p
);
1230 * Driver initialization
1233 static struct fb_ops mgam83fb_ops
= {
1234 .owner
= THIS_MODULE
,
1236 .fb_check_var
= mgam83fb_check_var
,
1237 .fb_set_par
= mgam83fb_set_par
,
1238 .fb_setcolreg
= mgam83fb_setcolreg
,
1239 .fb_blank
= mgam83fb_blank
,
1240 .fb_ioctl
= mgam83fb_ioctl
,
1241 #ifdef CONFIG_COMPAT
1242 .fb_compat_ioctl
= mgam83fb_compat_ioctl
,
1244 .fb_mmap
= mgam83fb_mmap
,
1245 .fb_pan_display
= mgam83fb_pan_display
,
1246 .fb_sync
= mgam83fb_sync
,
1247 .fb_fillrect
= mgam83fb_fillrect
, /*HW function*/
1248 #ifdef CONFIG_MGA_HWCOPYAREA
1249 .fb_copyarea
= mgam83fb_copyarea
, /*HW function*/
1251 .fb_copyarea
= cfb_copyarea
, /*Generic function*/
1253 #ifdef CONFIG_MGA_HWIMAGEBLIT
1254 .fb_imageblit
= mgam83fb_imageblit
, /*HW function*/
1256 .fb_imageblit
= cfb_imageblit
, /*Generic function*/
1260 static irqreturn_t
mga_debug_handler(int irq
, void *data
)
1262 struct mgam83fb_par
*p
= data
;
1263 uint32_t stat
= MMIO_READ(p
, REG_STAT
);
1265 /* Check if bit 0 or bit 1 are set */
1267 printk(KERN_ALERT
"mga_debug_handler: stat=0x%08lx\n",
1268 (unsigned long)stat
);
1270 * All magic constants were received from Maxim Vorontsov.
1271 * See bug62291 for details.
1273 MMIO_WRITE(p
, REG_STAT
, 0xf3);
1279 static int __fb_init(struct fb_info
*info
)
1281 struct mgam83fb_par
*p
= (struct mgam83fb_par
*)info
->par
;
1284 INFO_MSG("MEM : base 0x%08lx vbase 0x%08lx len 0x%lx\n",
1285 (unsigned long)p
->mem
.base
, (unsigned long)p
->mem
.vbase
,
1286 (unsigned long)p
->mem
.len
);
1287 INFO_MSG("MMIO: base 0x%08lx vbase 0x%08lx len 0x%lx\n",
1288 (unsigned long)p
->mmio
.base
, (unsigned long)p
->mmio
.vbase
,
1289 (unsigned long)p
->mmio
.len
);
1290 INFO_MSG("I2C : base 0x%08lx vbase 0x%08lx len 0x%lx\n",
1291 (unsigned long)p
->i2c
.base
, (unsigned long)p
->i2c
.vbase
,
1292 (unsigned long)p
->i2c
.len
);
1295 * Here we set the screen_base to the virtual memory address
1296 * for the framebuffer.
1298 info
->screen_base
= p
->mem
.vbase
; // Framebuffer virtual memory
1299 info
->fbops
= &mgam83fb_ops
;
1301 strncpy( info
->fix
.id
, "mcst_mga", 8 );
1302 info
->fix
.smem_start
= p
->mem
.base
;
1303 info
->fix
.smem_len
= p
->mem
.len
;
1304 info
->fix
.type
= FB_TYPE_PACKED_PIXELS
;
1305 info
->fix
.type_aux
= 0;
1306 info
->fix
.xpanstep
= 0;
1307 info
->fix
.ypanstep
= 0;
1308 info
->fix
.ywrapstep
= 0;
1309 info
->fix
.mmio_start
= p
->mmio
.base
;
1310 info
->fix
.mmio_len
= p
->mmio
.len
;
1311 info
->fix
.accel
= 0;
1313 info
->pseudo_palette
= p
->pseudo_palette
; /* The pseudopalette is an
1316 /* Set up flags to indicate what sort of acceleration driver can provide */
1318 info
->flags
= FBINFO_DEFAULT
1319 | FBINFO_HWACCEL_YPAN
1320 #ifdef CONFIG_MGA_HWCOPYAREA
1321 | FBINFO_HWACCEL_COPYAREA
1323 #ifdef CONFIG_MGA_HWIMAGEBLIT
1324 | FBINFO_HWACCEL_IMAGEBLIT
1328 retval
= fb_find_mode(&info
->var
, info
, mgam83fb_default_mode
,
1330 if (!retval
|| retval
== 4) {
1331 ERROR_MSG( "fb_find_mode() failed\n");
1334 INFO_MSG("default mode %dx%d-%d\n", info
->var
.xres
, info
->var
.yres
,
1335 info
->var
.bits_per_pixel
);
1337 /* úÄÅÓØ ÉÎÉÃÉÁÌÉÚÉÒÕÅÔÓÑ ÓÔÒÕËÔÕÒÁ cmap É ÚÁÐÏÌÎÑÅÔÓÑ Ã×ÅÔÁÍÉ ÐÏ default
1338 îÁ ÒÅÇÉÓÔÒÙ ÒÁÓËÌÁÄËÁ ÌÏÖÉÔÓÑ Æ-ÅÊ fb_set_cmap -> fb_setcolreg ÉÌÉ ÐÏ default
1339 ÉÌÉ ÐÏÌØÚÏ×ÁÔÅÌØÓËÁÑ ÉÓÐÏÌØÚÕÑ FBIOPUTCMAP */
1340 retval
= fb_alloc_cmap(&info
->cmap
, 256, 0);
1342 ERROR_MSG( "unable to allocate colormap\n" );
1347 * For drivers that can...
1349 /* ÚÄÅÓØ ÉÎÉÃÉÁÌÉÚÉÒÕÅÔÓÑ ÍÁÓÓÉ× fb_bitfield ÄÌÑ Ã×ÅÔÏ× */
1350 DEBUG_MSG("__fb_init: fb_bitfield initialization\n");
1351 if (mgam83fb_check_var(&info
->var
, info
)) {
1352 ERROR_MSG( "unable to validate variable\n" );
1356 if (register_framebuffer(info
) < 0) {
1357 ERROR_MSG( "register_framebuffer() failed\n" );
1358 fb_dealloc_cmap(&info
->cmap
);
1361 INFO_MSG("fb%d: %s frame buffer device\n", info
->node
, info
->fix
.id
);
1362 p
->index
= next_index
++;
1370 static int mgam83fb_probe(struct pci_dev
*dev
,
1371 const struct pci_device_id
*ent
)
1374 static struct mfgid mfg
;
1376 struct fb_info
* info
;
1377 struct mgam83fb_par
* p
;
1381 DEBUG_MSG("mgam83fb: pci driver_init\n");
1382 if ( (ret
= pci_enable_device(dev
)) ) {
1383 printk( KERN_ERR
"%s: cannot enable pci device\n", pci_name(dev
));
1387 pci_set_master(dev
);
1390 * Dynamically allocate info and par
1392 info
= framebuffer_alloc(sizeof(struct mgam83fb_par
), &dev
->dev
);
1394 ERROR_MSG( "failed to allocate fb_info instance!\n");
1399 p
->vers
.bus
= BUS_TYPE_PCI
;
1403 // TODO what to do if it is sparc, but not E90?
1404 p
->mem
.iospace
= PCI_IOSPACE
;
1406 p
->mem
.base
= pci_resource_start(dev
, PCI_MEM_BAR
);
1407 if ((ret
= pci_read_config_byte(dev
, PCI_REVISION_ID
, &revision
))) {
1408 printk( KERN_ERR
"%s: cannot read revision id\n", pci_name(dev
));
1411 if (revision
== 0) {
1412 // This card has wrong size in bar
1413 p
->mem
.len
= MGA_MEM_SIZE
;
1415 p
->mem
.len
= pci_resource_len( dev
, PCI_MEM_BAR
);
1418 if ( (ret
= pci_request_region(dev
, PCI_MEM_BAR
, "mgam83 FB")) )
1421 p
->mem
.vbase
= ioremap(p
->mem
.base
, p
->mem
.len
);
1425 ERROR_MSG( "cannot ioremap MEM (%lx, 0x%x)\n", p
->mem
.base
, p
->mem
.len
);
1427 goto fail_ioremap_mem
;
1430 // Video card registers
1431 p
->mmio
.base
= pci_resource_start( dev
, PCI_MMIO_BAR
);
1432 p
->mmio
.len
= pci_resource_len( dev
, PCI_MMIO_BAR
);
1434 if ( (ret
= pci_request_region(dev
, PCI_MMIO_BAR
, "mgam83 MMIO")) )
1437 p
->mmio
.vbase
= ioremap( p
->mmio
.base
, p
->mmio
.len
);
1438 if ( !p
->mmio
.vbase
)
1440 ERROR_MSG( "cannot ioremap MMIO (0x%08lx:0x%x)\n", p
->mmio
.base
, p
->mmio
.len
);
1442 goto fail_mmio_ioremap
;
1445 // I2C bus registers
1446 p
->i2c
.base
= pci_resource_start( dev
, PCI_I2C_BAR
);
1447 p
->i2c
.len
= pci_resource_len( dev
, PCI_I2C_BAR
);
1448 if ( (ret
= pci_request_region(dev
, PCI_I2C_BAR
, "mgam83 I2C")) )
1450 p
->i2c
.vbase
= ioremap( p
->i2c
.base
, p
->i2c
.len
);
1451 if ( !p
->i2c
.vbase
)
1453 ERROR_MSG( "cannot ioremap I2C (0x%08lx:0x%x)\n", p
->i2c
.base
, p
->i2c
.len
);
1455 goto fail_i2c_ioremap
;
1458 /* Debug handler (bug62291) */
1460 ret
= request_irq(dev
->irq
, mga_debug_handler
, IRQF_SHARED
,
1466 /* Mga driver version on all other machines depends on RevID
1467 * in pci configuration space */
1468 pci_read_config_byte(dev
, PCI_REVISION_ID
, &p
->vers
.revision
);
1469 INFO_MSG("MGA version driver from pci config space = 0x%x\n",
1472 #ifdef CONFIG_E90_FASTBOOT
1473 if (!bootblock
) // OpenPROM boot
1475 if(p
->vers
.revision
!= MGA_MODEL_PMUP2_0
1476 && p
->vers
.revision
!= MGA_MODEL_PMUP2_1
) {
1477 get_mcst_mfgid(&mfg
);
1478 p
->vers
.revision
= mfg
.tty1Mbit
;
1479 printk(KERN_NOTICE
"mgam83fb: MGA version driver from mfgid = 0x%x\n",
1484 set_up_colors_bounds(p
);
1485 /* Turning of display */
1486 MMIO_WRITE(p
, REG_CTRL
, MMIO_READ(p
, REG_CTRL
) & ~CTRL_VEN
);
1488 p
->dma_not_supported
= (MMIO_READ(p
, BBR0
) & DMA_SUPPORT
) == 0;
1490 // Filling info, selecting mode and initializating framebuffer
1491 DEBUG_MSG("mgam83fb: framebuffer init ...\n");
1492 if ( (ret
= __fb_init( info
)) )
1493 goto fail_register_fb
;
1495 pci_set_drvdata(dev
, info
);
1500 free_irq(dev
->irq
, p
);
1502 iounmap(p
->i2c
.vbase
);
1504 pci_release_region(dev
, PCI_I2C_BAR
);
1506 iounmap(p
->mmio
.vbase
);
1508 pci_release_region(dev
, PCI_MMIO_BAR
);
1510 iounmap(p
->mem
.vbase
);
1512 pci_release_region(dev
, PCI_MEM_BAR
);
1514 framebuffer_release(info
);
1519 static void mgam83fb_remove(struct pci_dev
*dev
)
1521 struct fb_info
*info
= pci_get_drvdata(dev
);
1522 struct page
*map
, *mapend
;
1523 struct mgam83fb_par
* p
;
1529 p
= (struct mgam83fb_par
*)info
->par
;
1532 free_irq(dev
->irq
, p
);
1534 if (p
->video_buf
.ioaddr
) {
1535 struct page
*map
, *mapend
;
1536 pci_unmap_single(p
->pdev
, p
->video_buf
.ioaddr
,
1537 p
->video_buf
.size
, PCI_DMA_FROMDEVICE
);
1538 mapend
= virt_to_page(p
->video_buf
.kvaddr
+ p
->video_buf
.size
-1);
1539 for (map
= virt_to_page(p
->video_buf
.kvaddr
); map
<= mapend
; map
++) {
1540 ClearPageReserved(map
);
1542 free_pages((unsigned long)p
->video_buf
.kvaddr
, get_order(p
->video_buf
.size
));
1543 p
->video_buf
.ioaddr
= 0;
1544 p
->video_buf
.kvaddr
= 0;
1545 p
->video_buf
.size
= 0;
1547 for (rnum
= 0; rnum
!= 2; rnum
++) {
1548 if (d_image
[rnum
].size
!= 0){
1549 mapend
= virt_to_page((d_image
[rnum
].virt_addr
) +
1550 (PAGE_SIZE
<< get_order(d_image
[rnum
].size
)) - 1);
1551 for (map
= virt_to_page((d_image
[rnum
].virt_addr
)); map
<= mapend
; map
++) {
1552 ClearPageReserved(map
);
1554 pci_unmap_single(p
->pdev
, d_image
[rnum
].dma_addr
,
1555 d_image
[rnum
].size
, PCI_DMA_FROMDEVICE
);
1556 free_pages(d_image
[rnum
].virt_addr
, get_order(d_image
[rnum
].size
));
1557 d_image
[rnum
].size
= 0;
1558 d_image
[rnum
].virt_addr
= 0;
1559 d_image
[rnum
].dma_addr
= 0;
1562 /* Turning of display */
1563 MMIO_WRITE(p
, REG_CTRL
, MMIO_READ(p
, REG_CTRL
) & ~CTRL_VEN
);
1565 unregister_framebuffer(info
);
1566 fb_dealloc_cmap(&info
->cmap
);
1567 iounmap(p
->i2c
.vbase
);
1568 pci_release_region(dev
, PCI_I2C_BAR
);
1569 iounmap(p
->mmio
.vbase
);
1570 pci_release_region(dev
, PCI_MMIO_BAR
);
1571 iounmap(p
->mem
.vbase
);
1572 pci_release_region(dev
, PCI_MEM_BAR
);
1573 framebuffer_release(info
);
1575 /* First time when we load driver drvdata is NULL, but if we reload it,
1576 * we get garbage here, because drvdata is not cleared after driver unload
1578 pci_set_drvdata(dev
, NULL
);
1581 static int mgam83fb_suspend(struct pci_dev
*dev
, pm_message_t state
)
1583 return pci_save_state(dev
);
1586 static int mgam83fb_resume(struct pci_dev
*dev
)
1588 struct fb_info
*info
= pci_get_drvdata(dev
);
1589 pci_restore_state(dev
);
1590 mgam83fb_set_par(info
);
1594 static struct pci_device_id mgam83fb_devices
[] = {
1595 { PCI_DEVICE(PCI_VENDOR_ID_MGAM83
, PCI_DEVICE_ID_MGAM83
) },
1599 static struct pci_driver mgam83fb_driver
= {
1601 .id_table
= mgam83fb_devices
,
1602 .probe
= mgam83fb_probe
,
1603 .remove
= mgam83fb_remove
,
1604 .suspend
= mgam83fb_suspend
,
1605 .resume
= mgam83fb_resume
,
1610 static int __init
mgam83fb_setup(char *options
)
1612 if (!options
|| !*options
)
1614 mgam83fb_default_mode
= options
;
1619 static int __init
mgam83fb_init(void)
1623 char *option
= NULL
;
1624 if (fb_get_options("mgam83fb", &option
))
1626 mgam83fb_setup(option
);
1628 DEBUG_MSG("Module initialization\n");
1630 pci_ret
= pci_register_driver(&mgam83fb_driver
);
1637 static void mgam83fb_cleanup(void)
1639 pci_unregister_driver(&mgam83fb_driver
);
1642 ////////////////////////////////////////////////////////////////////////////////
1644 ////////////////////////////////////////////////////////////////////////////////
1646 module_init(mgam83fb_init
);
1647 module_exit(mgam83fb_cleanup
);
1649 module_param(use_irq
, bool, S_IRUGO
);
1650 MODULE_PARM_DESC(use_irq
, "Register interrupt handler");
1651 MODULE_LICENSE("GPL");
1654 /*******************************************************************************
1656 *******************************************************************************
1659 void __dump_mmio( struct mgam83fb_par
* p
)
1662 DEBUG_MSG( "CTRL: 0x%08x\n", MMIO_READ( p
, REG_CTRL
) );
1663 DEBUG_MSG( "STAT: 0x%08x\n", MMIO_READ( p
, REG_STAT
) );
1664 DEBUG_MSG( "HTIM: 0x%08x\n", MMIO_READ( p
, REG_HTIM
) );
1665 DEBUG_MSG( "VTIM: 0x%08x\n", MMIO_READ( p
, REG_VTIM
) );
1666 DEBUG_MSG( "HVLEN: 0x%08x\n", MMIO_READ( p
, REG_HVLEN
) );
1667 DEBUG_MSG( "VBARa: 0x%08x\n", MMIO_READ( p
, REG_VBARa
) );
1668 DEBUG_MSG( "VBARb: 0x%08x\n", MMIO_READ( p
, REG_VBARb
) );
1669 DEBUG_MSG( "C0XY: 0x%08x\n", MMIO_READ( p
, REG_C0XY
) );
1670 DEBUG_MSG( "C0BAR: 0x%08x\n", MMIO_READ( p
, REG_C0BAR
) );
1671 DEBUG_MSG( "C0CR: 0x%08x\n", MMIO_READ( p
, REG_C0CR
) );
1672 DEBUG_MSG( "C1XY: 0x%08x\n", MMIO_READ( p
, REG_C1XY
) );
1673 DEBUG_MSG( "C1BAR: 0x%08x\n", MMIO_READ( p
, REG_C1BAR
) );
1674 DEBUG_MSG( "C1CR: 0x%08x\n", MMIO_READ( p
, REG_C1CR
) );
1676 if ( 8 == p
->bits_per_pixel
) {
1677 unsigned long col_regno
;
1678 DEBUG_MSG( "CLUT0 ==================================DUMP BEGIN\n" );
1679 for( col_regno
= 0; col_regno
< 256; col_regno
++ ) {
1680 int val
= MMIO_READ( p
, 0x800 + col_regno
* 4 );
1681 DEBUG_MSG( "%03ld: r %02x g %02x b %02x\n", col_regno
, (val
& 0x00FF0000) >> 16, (val
& 0x0000FF00), (val
& 0x000000FF) );
1683 DEBUG_MSG( "CLUT0 ====================================DUMP END\n" );
1687 void __dump_par( const struct mgam83fb_par
* p
)
1689 char buf
[256] = { 0, };
1692 if ( p
->sync
& FB_SYNC_HOR_HIGH_ACT
)
1693 pos
+= sprintf( buf
+ pos
, "FB_SYNC_HOR_HIGH_ACT " );
1694 if ( p
->sync
& FB_SYNC_VERT_HIGH_ACT
)
1695 pos
+= sprintf( buf
+ pos
, "FB_SYNC_VERT_HIGH_ACT " );
1696 if ( p
->sync
& FB_SYNC_COMP_HIGH_ACT
)
1697 pos
+= sprintf( buf
+ pos
, "FB_SYNC_COMP_HIGH_ACT " );
1699 DEBUG_MSG( "mgafb_par ==============================DUMP BEGIN\n" );
1700 DEBUG_MSG( "Resolution: %dx%d\n", p
->xres
, p
->yres
);
1701 DEBUG_MSG( "Virtual resolution: %dx%d\n", p
->xres_virtual
, p
->yres_virtual
);
1702 DEBUG_MSG( "Offset: x %d y %d\n", p
->xoffset
, p
->yoffset
);
1703 DEBUG_MSG( "Bpp: %d\n", p
->bits_per_pixel
);
1704 DEBUG_MSG( "Pixclock: %d\n", p
->pixclock
);
1705 DEBUG_MSG( "Margins: left %d right %d upper %d lower %d\n",
1706 p
->left_margin
, p
->right_margin
, p
->upper_margin
, p
->lower_margin
);
1707 DEBUG_MSG( "Sync length: horizontal %d vertical %d\n",
1708 p
->hsync_len
, p
->vsync_len
);
1709 DEBUG_MSG( "%s\n", buf
);
1710 DEBUG_MSG( "mgafb_par ================================DUMP END\n" );
1714 void __dump_var( const struct fb_var_screeninfo
* var
)
1716 char buf
[256] = { 0, };
1718 if ( var
->sync
& FB_SYNC_HOR_HIGH_ACT
)
1719 pos
+= sprintf( buf
+ pos
, "FB_SYNC_HOR_HIGH_ACT " );
1720 if ( var
->sync
& FB_SYNC_VERT_HIGH_ACT
)
1721 pos
+= sprintf( buf
+ pos
, "FB_SYNC_VERT_HIGH_ACT " );
1722 if ( var
->sync
& FB_SYNC_COMP_HIGH_ACT
)
1723 pos
+= sprintf( buf
+ pos
, "FB_SYNC_COMP_HIGH_ACT " );
1725 DEBUG_MSG( "fb_var_screeninfo ======================DUMP BEGIN\n" );
1726 DEBUG_MSG( "Resolution: %dx%d\n", var
->xres
, var
->yres
);
1727 DEBUG_MSG( "Virtual resolution: %dx%d\n", var
->xres_virtual
, var
->yres_virtual
);
1728 DEBUG_MSG( "Offset: x %d y %d\n", var
->xoffset
, var
->yoffset
);
1729 DEBUG_MSG( "Bpp: %d, Grayscale: %d\n", var
->bits_per_pixel
, var
->grayscale
);
1730 DEBUG_MSG( "Bitfields: \n" );
1731 DEBUG_MSG( " color | offset | length | msb_right\n" );
1732 DEBUG_MSG( " red | %2d | %2d | %1d \n", var
->red
.offset
, var
->red
.length
, var
->red
.msb_right
);
1733 DEBUG_MSG( " green | %2d | %2d | %1d \n", var
->green
.offset
, var
->green
.length
, var
->green
.msb_right
);
1734 DEBUG_MSG( " blue | %2d | %2d | %1d \n", var
->blue
.offset
, var
->blue
.length
, var
->blue
.msb_right
);
1735 DEBUG_MSG( " transp | %2d | %2d | %1d \n", var
->transp
.offset
, var
->transp
.length
, var
->transp
.msb_right
);
1736 DEBUG_MSG( "Pixclock: %d\n", var
->pixclock
);
1737 DEBUG_MSG( "Margins: left %d right %d upper %d lower %d\n",
1738 var
->left_margin
, var
->right_margin
, var
->upper_margin
, var
->lower_margin
);
1739 DEBUG_MSG( "Sync length: horizontal %d vertical %d\n",
1740 var
->hsync_len
, var
->vsync_len
);
1741 DEBUG_MSG( "%s\n", buf
);
1742 DEBUG_MSG( "fb_var_screeninfo ========================DUMP END\n" );
1745 /*******************************************************************************
1747 *******************************************************************************
1750 #define PROC_FILENAME "mgam83_"
1751 #define PROC_INPUT_MAX_LEN 32
1752 #define CTRL_VBL_MASK (~(CTRL_VBL_1 | CTRL_VBL_2 | CTRL_VBL_4 | CTRL_VBL_8 | CTRL_VBL1024))
1754 char regs_buf
[4096];
1756 void spill_regs(struct mgam83fb_par
* p
){
1759 for (i
= 0; i
!= 4096; i
++){
1762 len
+= sprintf( regs_buf
+ len
, "CTRL: 0x%08x\n", MMIO_READ( p
, REG_CTRL
) );
1763 len
+= sprintf( regs_buf
+ len
, "STAT: 0x%08x\n", MMIO_READ( p
, REG_STAT
) );
1764 len
+= sprintf( regs_buf
+ len
, "HTIM: 0x%08x\n", MMIO_READ( p
, REG_HTIM
) );
1765 len
+= sprintf( regs_buf
+ len
, "VTIM: 0x%08x\n", MMIO_READ( p
, REG_VTIM
) );
1766 len
+= sprintf( regs_buf
+ len
, "HVLEN: 0x%08x\n", MMIO_READ( p
, REG_HVLEN
) );
1767 len
+= sprintf( regs_buf
+ len
, "VBARa: 0x%08x\n", MMIO_READ( p
, REG_VBARa
) );
1768 len
+= sprintf( regs_buf
+ len
, "VBARb: 0x%08x\n", MMIO_READ( p
, REG_VBARb
) );
1769 len
+= sprintf( regs_buf
+ len
, "C0XY: 0x%08x\n", MMIO_READ( p
, REG_C0XY
) );
1770 len
+= sprintf( regs_buf
+ len
, "C0BAR: 0x%08x\n", MMIO_READ( p
, REG_C0BAR
) );
1771 len
+= sprintf( regs_buf
+ len
, "C0CR: 0x%08x\n", MMIO_READ( p
, REG_C0CR
) );
1772 len
+= sprintf( regs_buf
+ len
, "C1XY: 0x%08x\n", MMIO_READ( p
, REG_C1XY
) );
1773 len
+= sprintf( regs_buf
+ len
, "C1BAR: 0x%08x\n", MMIO_READ( p
, REG_C1BAR
) );
1774 len
+= sprintf( regs_buf
+ len
, "C1CR: 0x%08x\n", MMIO_READ( p
, REG_C1CR
) );
1775 len
+= sprintf( regs_buf
+ len
, "TST_D: 0x%08x\n", MMIO_READ( p
, REG_TST_D
) );
1776 len
+= sprintf( regs_buf
+ len
, "BBR0: 0x%08x\n", MMIO_READ( p
, BBR0
) );
1777 len
+= sprintf( regs_buf
+ len
, "BBR1: 0x%08x\n", MMIO_READ( p
, BBR1
) );
1778 len
+= sprintf( regs_buf
+ len
, "BBR2: 0x%08x\n", MMIO_READ( p
, BBR2
) );
1779 len
+= sprintf( regs_buf
+ len
, "BBR3: 0x%08x\n", MMIO_READ( p
, BBR3
) );
1780 len
+= sprintf( regs_buf
+ len
, "BBR4: 0x%08x\n", MMIO_READ( p
, BBR4
) );
1781 len
+= sprintf( regs_buf
+ len
, "BBR5: 0x%08x\n", MMIO_READ( p
, BBR5
) );
1782 sprintf( regs_buf
+ len
, "BBR6: 0x%08x\n", MMIO_READ( p
, BBR6
) );
1785 int mgafb_proc_read(char *buf
, char **start
, off_t off
, int count
, int *eof
, void *data
)
1787 struct mgam83fb_par
* p
= (struct mgam83fb_par
* )data
;
1790 u32 bpp
= p
->info
->var
.bits_per_pixel
;
1791 size_t screen_length
;
1798 uint32_t vbl
= MMIO_READ( p
, REG_CTRL
) & ~CTRL_VBL_MASK
;
1800 len
+= sprintf( buf
+ len
, "CTRL: 0x%08x\n", MMIO_READ( p
, REG_CTRL
) );
1801 len
+= sprintf( buf
+ len
, "STAT: 0x%08x\n", MMIO_READ( p
, REG_STAT
) );
1802 len
+= sprintf( buf
+ len
, "HTIM: 0x%08x\n", MMIO_READ( p
, REG_HTIM
) );
1803 len
+= sprintf( buf
+ len
, "VTIM: 0x%08x\n", MMIO_READ( p
, REG_VTIM
) );
1804 len
+= sprintf( buf
+ len
, "HVLEN: 0x%08x\n", MMIO_READ( p
, REG_HVLEN
) );
1805 len
+= sprintf( buf
+ len
, "VBARa: 0x%08x\n", MMIO_READ( p
, REG_VBARa
) );
1806 len
+= sprintf( buf
+ len
, "VBARb: 0x%08x\n", MMIO_READ( p
, REG_VBARb
) );
1807 len
+= sprintf( buf
+ len
, "C0XY: 0x%08x\n", MMIO_READ( p
, REG_C0XY
) );
1808 len
+= sprintf( buf
+ len
, "C0BAR: 0x%08x\n", MMIO_READ( p
, REG_C0BAR
) );
1809 len
+= sprintf( buf
+ len
, "C0CR: 0x%08x\n", MMIO_READ( p
, REG_C0CR
) );
1810 len
+= sprintf( buf
+ len
, "C1XY: 0x%08x\n", MMIO_READ( p
, REG_C1XY
) );
1811 len
+= sprintf( buf
+ len
, "C1BAR: 0x%08x\n", MMIO_READ( p
, REG_C1BAR
) );
1812 len
+= sprintf( buf
+ len
, "C1CR: 0x%08x\n", MMIO_READ( p
, REG_C1CR
) );
1813 len
+= sprintf( buf
+ len
, "TST_D: 0x%08x\n", MMIO_READ( p
, REG_TST_D
) );
1815 len
+= sprintf( buf
+ len
, "\n" );
1819 len
+= sprintf( buf
+ len
, "VBL: 1\n" );
1822 len
+= sprintf( buf
+ len
, "VBL: 2\n" );
1825 len
+= sprintf( buf
+ len
, "VBL: 4\n" );
1828 len
+= sprintf( buf
+ len
, "VBL: 8\n" );
1831 len
+= sprintf( buf
+ len
, "VBL: 1024\n" );
1834 len
+= sprintf( buf
+ len
, "VBL: N/A\n" );
1838 clk_t clk
= __calc( p
->pixclock
);
1839 len
+= sprintf( buf
+ len
, "div: %d\n", clk
.div
);
1840 len
+= sprintf( buf
+ len
, "q: %d\n", clk
.q
);
1841 len
+= sprintf( buf
+ len
, "p: %d\n", clk
.p
);
1842 len
+= sprintf( buf
+ len
, "po: %d\n", clk
.po
);
1847 if (last_info
!= NULL
)
1848 cfb_copyarea(last_info
, &last_area
);
1850 if (last_info
!= NULL
)
1851 mgam83fb_copyarea(last_info
, &last_area
);
1854 for (i
= area_count
; i
!= 10; i
++){
1855 len
+= sprintf( buf
+ len
, "dx = %d\n", last_area
[i
].dx
);
1856 len
+= sprintf( buf
+ len
, "dy = %d\n", last_area
[i
].dy
);
1857 len
+= sprintf( buf
+ len
, "sx = %d\n", last_area
[i
].sx
);
1858 len
+= sprintf( buf
+ len
, "sy = %d\n", last_area
[i
].sy
);
1859 len
+= sprintf( buf
+ len
, "width = %d\n", last_area
[i
].width
);
1860 len
+= sprintf( buf
+ len
, "height = %d\n", last_area
[i
].height
);
1862 for (i
= 0; i
!= area_count
; i
++){
1863 len
+= sprintf( buf
+ len
, "dx = %d\n", last_area
[i
].dx
);
1864 len
+= sprintf( buf
+ len
, "dy = %d\n", last_area
[i
].dy
);
1865 len
+= sprintf( buf
+ len
, "sx = %d\n", last_area
[i
].sx
);
1866 len
+= sprintf( buf
+ len
, "sy = %d\n", last_area
[i
].sy
);
1867 len
+= sprintf( buf
+ len
, "width = %d\n", last_area
[i
].width
);
1868 len
+= sprintf( buf
+ len
, "height = %d\n", last_area
[i
].height
);
1871 #if 0 /* getting framebuffer into file */
1872 screen_length
= ((p
->info
->var
.yres_virtual
) *
1873 (p
->info
->var
.xres_virtual
) *
1874 (bpp
>> 3)); /* in bytes */
1875 s
= (u8
*)p
->info
->screen_base
;
1876 for (i
= 0; i
!= screen_length
; i
++)
1886 if (start
== 0x100){
1887 if (count
== 1) {rgval
= MMIO_READ(p
, REG_STAT
);}
1888 if (count
== 2) {rgval
= MMIO_READ(p
, REG_HTIM
);}
1889 if (count
== 3) {rgval
= MMIO_READ(p
, REG_VTIM
);}
1890 if (count
== 4) {rgval
= MMIO_READ(p
, REG_HVLEN
);}
1891 if (count
== 5) {rgval
= MMIO_READ(p
, REG_VBARa
);}
1892 if (count
== 6) {rgval
= MMIO_READ(p
, REG_VBARb
);}
1893 if (count
== 7) {rgval
= MMIO_READ(p
, REG_C0XY
);}
1894 if (count
== 8) {rgval
= MMIO_READ(p
, REG_C0BAR
);}
1895 if (count
== 9) {rgval
= MMIO_READ(p
, REG_C0CR
);}
1896 if (count
== 10) {rgval
= MMIO_READ(p
, REG_C1XY
);}
1897 if (count
== 11) {rgval
= MMIO_READ(p
, REG_C1BAR
);}
1898 if (count
== 12) {rgval
= MMIO_READ(p
, REG_C1CR
);}
1899 if (count
== 13) {rgval
= MMIO_READ(p
, REG_TST_D
);}
1900 if (count
== 14) {rgval
= MMIO_READ(p
, BBR0
);}
1901 if (count
== 15) {rgval
= MMIO_READ(p
, BBR1
);}
1902 if (count
== 16) {rgval
= MMIO_READ(p
, BBR2
);}
1903 if (count
== 17) {rgval
= MMIO_READ(p
, BBR3
);}
1904 if (count
== 18) {rgval
= MMIO_READ(p
, BBR4
);}
1905 if (count
== 19) {rgval
= MMIO_READ(p
, BBR5
);}
1906 if (count
== 20) {rgval
= MMIO_READ(p
, BBR6
);}
1911 *(u32
*)buf
= rgval
;
1915 /* getting all regs (last values before write) */
1917 if (start
== 0x1000){
1919 for (i
= 0; i
!= PAGE_SIZE
; i
++){
1928 /* getting all regs */
1931 if (start
== 0x1000){
1933 for (i
= 0; i
!= PAGE_SIZE
; i
++){
1943 /* getting framebuffer */
1944 screen_length
= ((p
->info
->var
.yres_virtual
) *
1945 (p
->info
->var
.xres_virtual
) *
1946 (bpp
>> 3)); /* in bytes */
1947 if (off
>= screen_length
)
1949 if (count
> (screen_length
- off
))
1950 count
= (screen_length
- off
);
1951 s
= (u8
*)((u8
*)p
->info
->screen_base
+ off
);
1952 for (i
= 0; i
!= count
; i
++)
1966 int mgafb_proc_write(struct file
*file
, const char *buffer
, unsigned long count
, void *data
)
1968 struct mgam83fb_par
* p
= (struct mgam83fb_par
*)data
;
1969 char kern_buf
[PROC_INPUT_MAX_LEN
] = { 0, };
1974 struct page
*map
, *mapend
;
1978 u32 bpp
= p
->info
->var
.bits_per_pixel
;
1979 size_t screen_length
, len
;
1985 #if 1 /* (writing register) */
1987 if (copy_from_user(&rgval
, buffer
, 4)) {
1988 ERROR_MSG( "Failed to copy from user\n" );
1993 if (count
== 1){ MMIO_WRITE(p
, REG_STAT
, rgval
); return 4;}
1994 if (count
== 2){ MMIO_WRITE( p
, REG_HTIM
, rgval
); return 4;}
1995 if (count
== 3){ MMIO_WRITE( p
, REG_VTIM
, rgval
); return 4;}
1996 if (count
== 4){ MMIO_WRITE( p
, REG_HVLEN
, rgval
);return 4;}
1997 if (count
== 5){ MMIO_WRITE( p
, REG_VBARa
, rgval
);return 4;}
1998 if (count
== 6){ MMIO_WRITE( p
, REG_VBARb
, rgval
);return 4;}
1999 if (count
== 7){ MMIO_WRITE( p
, REG_C0XY
, rgval
); return 4;}
2000 if (count
== 8){ MMIO_WRITE( p
, REG_C0BAR
, rgval
);return 4;}
2001 if (count
== 9){ MMIO_WRITE( p
, REG_C0CR
, rgval
); return 4;}
2002 if (count
== 10){ MMIO_WRITE( p
, REG_C1XY
, rgval
); return 4;}
2003 if (count
== 11){ MMIO_WRITE( p
, REG_C1BAR
, rgval
);return 4;}
2004 if (count
== 12){ MMIO_WRITE( p
, REG_C1CR
, rgval
); return 4;}
2005 if (count
== 13){ MMIO_WRITE( p
, REG_TST_D
, rgval
);return 4;}
2006 if (count
== 14){ MMIO_WRITE( p
, BBR0
, rgval
); return 4;}
2007 if (count
== 15){ MMIO_WRITE( p
, BBR1
, rgval
); return 4;}
2008 if (count
== 16){ MMIO_WRITE( p
, BBR2
, rgval
); return 4;}
2009 if (count
== 17){ MMIO_WRITE( p
, BBR3
, rgval
); return 4;}
2010 if (count
== 18){ MMIO_WRITE( p
, BBR4
, rgval
); return 4;}
2011 if (count
== 19){ MMIO_WRITE( p
, BBR5
, rgval
); return 4;}
2012 if (count
== 20){ MMIO_WRITE( p
, BBR6
, rgval
); return 4;}
2013 if (count
== 21){ MMIO_WRITE(p
, REG_CTRL
, rgval
);
2014 mdelay(1); return 4;}
2020 if ( !count
|| count
> PROC_INPUT_MAX_LEN
) {
2021 ERROR_MSG( "Command length is too big\n" );
2024 if ( copy_from_user( &kern_buf
, buffer
, count
) ) {
2025 ERROR_MSG( "Failed to copy from user\n" );
2029 if ( sscanf( kern_buf
, "CTRL=0x%x", ®
) == 1 || sscanf( kern_buf
, "CTRL=0x%x", ®
) == 1 ) {
2030 DEBUG_MSG( "CTRL <= 0x%x\n", reg
);
2031 MMIO_WRITE( p
, REG_CTRL
, reg
);
2032 // } else if ( sscanf( kern_buf, "FB=%d", &fb_cmd ) == 1 ) {
2033 // DEBUG_MSG( "Unregistering FB..." );
2034 // if ( unregister_framebuffer( &p->gen.info ) ) {
2035 // printk( "Failed\n" );
2037 // printk( "Ok\n" );
2038 // p->fb_registered = 0;
2041 int enabled
= MMIO_READ( p
, REG_CTRL
) & CTRL_VEN
;
2042 unsigned int offset
;
2044 MMIO_WRITE( p
, REG_CTRL
, MMIO_READ( p
, REG_CTRL
) & ~CTRL_VEN
);
2046 if ( sscanf( kern_buf
, "STAT=0x%x", ®
) == 1 || sscanf( kern_buf
, "STAT=%x", ®
) == 1 ) {
2047 DEBUG_MSG( "STAT <= 0x%x\n", reg
);
2048 MMIO_WRITE( p
, REG_STAT
, reg
);
2049 } else if ( sscanf( kern_buf
, "HTIM=0x%x", ®
) == 1 || sscanf( kern_buf
, "HTIM=%x", ®
) == 1 ) {
2050 DEBUG_MSG( "HTIM <= 0x%x\n", reg
);
2051 MMIO_WRITE( p
, REG_HTIM
, reg
);
2052 } else if ( sscanf( kern_buf
, "VTIM=0x%x", ®
) == 1 || sscanf( kern_buf
, "VTIM=%x", ®
) == 1 ) {
2053 DEBUG_MSG( "VTIM <= 0x%x\n", reg
);
2054 MMIO_WRITE( p
, REG_VTIM
, reg
);
2055 } else if ( sscanf( kern_buf
, "HVLEN=0x%x", ®
) == 1 || sscanf( kern_buf
, "HVLEN=%x", ®
) == 1 ) {
2056 DEBUG_MSG( "HVLEN <= 0x%x\n", reg
);
2057 MMIO_WRITE( p
, REG_HVLEN
, reg
);
2058 } else if ( sscanf( kern_buf
, "VBARa=0x%x", ®
) == 1 || sscanf( kern_buf
, "VBARa=%x", ®
) == 1 ) {
2059 DEBUG_MSG( "VBARa <= 0x%x\n", reg
);
2060 MMIO_WRITE( p
, REG_VBARa
, reg
);
2061 } else if ( sscanf( kern_buf
, "VBARb=0x%x", ®
) == 1 || sscanf( kern_buf
, "VBARb=%x", ®
) == 1 ) {
2062 DEBUG_MSG( "VBARb <= 0x%x\n", reg
);
2063 MMIO_WRITE( p
, REG_VBARb
, reg
);
2064 } else if ( sscanf( kern_buf
, "C0XY=0x%x", ®
) == 1 || sscanf( kern_buf
, "C0XY=%x", ®
) == 1 ) {
2065 DEBUG_MSG( "C0XY <= 0x%x\n", reg
);
2066 MMIO_WRITE( p
, REG_C0XY
, reg
);
2067 } else if ( sscanf( kern_buf
, "C0BAR=0x%x", ®
) == 1 || sscanf( kern_buf
, "C0BAR=%x", ®
) == 1 ) {
2068 DEBUG_MSG( "C0BAR <= 0x%x\n", reg
);
2069 MMIO_WRITE( p
, REG_C0BAR
, reg
);
2070 } else if ( sscanf( kern_buf
, "C0CR=0x%x", ®
) == 1 || sscanf( kern_buf
, "C0CR=%x", ®
) == 1 ) {
2071 DEBUG_MSG( "C0CR <= 0x%x\n", reg
);
2072 MMIO_WRITE( p
, REG_C0CR
, reg
);
2073 } else if ( sscanf( kern_buf
, "C1XY=0x%x", ®
) == 1 || sscanf( kern_buf
, "C1XY=%x", ®
) == 1 ) {
2074 DEBUG_MSG( "C1XY <= 0x%x\n", reg
);
2075 MMIO_WRITE( p
, REG_C1XY
, reg
);
2076 } else if ( sscanf( kern_buf
, "C1BAR=0x%x", ®
) == 1 || sscanf( kern_buf
, "C1BAR=%x", ®
) == 1 ) {
2077 DEBUG_MSG( "C1BAR <= 0x%x\n", reg
);
2078 MMIO_WRITE( p
, REG_C1BAR
, reg
);
2079 } else if ( sscanf( kern_buf
, "C1CR=0x%x", ®
) == 1 || sscanf( kern_buf
, "C1CR=%x", ®
) == 1 ) {
2080 DEBUG_MSG( "C1CR <= 0x%x\n", reg
);
2081 MMIO_WRITE( p
, REG_C1CR
, reg
);
2082 } else if ( sscanf( kern_buf
, "TST_D=0x%x", ®
) == 1 || sscanf( kern_buf
, "TST_D=%x", ®
) == 1 ) {
2083 DEBUG_MSG( "TST_D <= 0x%x\n", reg
);
2084 MMIO_WRITE( p
, REG_TST_D
, reg
);
2085 } else if ( sscanf( kern_buf
, "VBL=%d", &vbl
) == 1 ) {
2088 DEBUG_MSG( "VBL: 1\n" );
2092 DEBUG_MSG( "VBL: 2\n" );
2096 DEBUG_MSG( "VBL: 4\n" );
2100 DEBUG_MSG( "VBL: 8\n" );
2104 DEBUG_MSG( "VBL: 1024\n" );
2108 DEBUG_MSG( "Unknown VBL value. Using VBL1024\n" );
2111 MMIO_WRITE( p
, REG_CTRL
, ( MMIO_READ( p
, REG_CTRL
) & CTRL_VBL_MASK
) | vbl
);
2112 } else if ( sscanf( kern_buf
, "RS 0x%x=0x%x", &offset
, ®
) == 2 ) {
2113 DEBUG_MSG( "REG(0x%x) <= 0x%x\n", offset
, reg
);
2114 MMIO_WRITE( p
, offset
, reg
);
2115 } else if ( sscanf( kern_buf
, "RG 0x%x", &offset
) == 1 ) {
2116 DEBUG_MSG( "REG(0x%x) => 0x%x\n", offset
, MMIO_READ( p
, offset
) );
2118 ERROR_MSG( "Unknown command line: %s\n", kern_buf
);
2121 MMIO_WRITE( p
, REG_CTRL
, MMIO_READ( p
, REG_CTRL
) | enabled
);
2125 #if 0 /* no dma mode (buffer like in dma) (source is file) */
2126 screen_length
= (p
->info
->var
.yres_virtual
) *
2127 (p
->info
->var
.xres_virtual
)*(bpp
>> 3); /* in bytes */
2128 d_image
.size
= screen_length
;
2129 d_image
.virt_addr
= __get_free_pages(GFP_KERNEL
| GFP_DMA
,
2130 get_order(d_image
.size
));
2132 st
= (u8
*)d_image
.virt_addr
;
2135 if ( copy_from_user( st
, sf
, d_image
.size
) ) {
2136 ERROR_MSG( "Failed to copy from user\n" );
2139 st
= (u8
*)p
->info
->screen_base
;
2140 sf
= (u8
*)d_image
.virt_addr
;
2142 for (i
= 0; i
!= d_image
.size
; i
++)
2149 free_pages(d_image
.virt_addr
, get_order(d_image
.size
));
2151 #if 0 /* dma mode (source is file) */
2152 d_image
.size
= (p
->info
->var
.yres_virtual
) *
2153 (p
->info
->var
.xres_virtual
)*(bpp
>> 3); /* in bytes */
2154 d_image
.virt_addr
= __get_free_pages(GFP_KERNEL
| GFP_DMA
,
2155 get_order(d_image
.size
));
2156 mapend
= virt_to_page ((d_image
.virt_addr
) +
2157 (PAGE_SIZE
<< get_order(d_image
.size
)) - 1);
2158 for (map
= virt_to_page((d_image
.virt_addr
)); map
<= mapend
; map
++)
2159 SetPageReserved(map
);
2160 d_image
.dma_addr
= pci_map_single(p
->pdev
,
2161 (void *)d_image
.virt_addr
, d_image
.size
,
2162 PCI_DMA_FROMDEVICE
);
2164 st
= (u8
*)d_image
.virt_addr
;
2167 if ( copy_from_user( st
, sf
, d_image
.size
) ) {
2168 ERROR_MSG( "Failed to copy from user\n" );
2174 while (MMIO_READ(p
, BBR0
) & PROCESS
){
2176 dpitch
= (p
->info
->var
.xres_virtual
) * (bpp
>> 3);
2179 MMIO_WRITE(p
, BBR1
, ((p
->info
->var
.yres_virtual
<< 16) |
2180 ((p
->info
->var
.xres_virtual
) * (bpp
>> 3))));
2181 MMIO_WRITE(p
, BBR2
, d_image
.dma_addr
);
2182 MMIO_WRITE(p
, BBR3
, 0);
2183 MMIO_WRITE(p
, BBR4
, (dpitch
<< 16) | spitch
);
2184 command
|= ( ROP_05
| SDMA_EN
| START
);
2187 MMIO_WRITE(p
, BBR0
, command
);
2189 while ( MMIO_READ(p
, BBR0
) & PROCESS
) {
2191 pci_unmap_single(p
->pdev
, d_image
.dma_addr
,
2192 d_image
.size
, PCI_DMA_FROMDEVICE
);
2193 free_pages(d_image
.virt_addr
, get_order(d_image
.size
));
2195 #if 0 /* dma mode (source is framebuffer) */
2196 while (MMIO_READ(p
, BBR0
) & PROCESS
){
2198 dpitch
= (p
->info
->var
.xres_virtual
) * (bpp
>> 3);
2201 MMIO_WRITE(p
, BBR1
, ((p
->info
->var
.yres_virtual
<< 16) |
2202 ((p
->info
->var
.xres_virtual
) * (bpp
>> 3))));
2203 MMIO_WRITE(p
, BBR2
, p
->mem
.base
);
2204 MMIO_WRITE(p
, BBR3
, 0);
2205 MMIO_WRITE(p
, BBR4
, (dpitch
<< 16) | spitch
);
2206 command
|= ( ROP_05
| SDMA_EN
| START
);
2208 MMIO_WRITE(p
, BBR0
, command
);
2212 while ( MMIO_READ(p
, BBR0
) & PROCESS
) {
2214 pci_unmap_single(p
->pdev
, d_image
.dma_addr
,
2215 d_image
.size
, PCI_DMA_FROMDEVICE
);
2216 free_pages(d_image
.virt_addr
, get_order(d_image
.size
));
2218 #if 0 /* dma - dma mode (source is file) */
2219 d_image
.size
= (p
->info
->var
.yres_virtual
) *
2220 (p
->info
->var
.xres_virtual
)*(bpp
>> 3); /* in bytes */
2221 d_image
.virt_addr
= __get_free_pages(GFP_KERNEL
| GFP_DMA
,
2222 get_order(d_image
.size
));
2223 mapend
= virt_to_page ((d_image
.virt_addr
) +
2224 (PAGE_SIZE
<< get_order(d_image
.size
)) - 1);
2225 for (map
= virt_to_page((d_image
.virt_addr
)); map
<= mapend
; map
++)
2226 SetPageReserved(map
);
2227 d_image
.dma_addr
= pci_map_single(p
->pdev
,
2228 (void *)d_image
.virt_addr
, d_image
.size
,
2229 PCI_DMA_FROMDEVICE
);
2231 st
= (u8
*)d_image
.virt_addr
;
2234 if ( copy_from_user( st
, sf
, d_image
.size
) ) {
2235 ERROR_MSG( "Failed to copy from user\n" );
2241 while (MMIO_READ(p
, BBR0
) & PROCESS
){
2244 dpitch
= (p
->info
->var
.xres_virtual
) * (bpp
>> 3);
2247 MMIO_WRITE(p
, BBR1
, ((p
->info
->var
.yres_virtual
<< 16) |
2248 ((p
->info
->var
.xres_virtual
) * (bpp
>> 3))));
2249 MMIO_WRITE(p
, BBR2
, d_image
.dma_addr
);
2250 MMIO_WRITE(p
, BBR3
, p
->mem
.base
);
2251 MMIO_WRITE(p
, BBR4
, (dpitch
<< 16) | spitch
);
2252 command
|= ( ROP_05
| SDMA_EN
| DDMA_EN
| START
);
2255 MMIO_WRITE(p
, BBR0
, command
);
2257 while ( MMIO_READ(p
, BBR0
) & PROCESS
) {
2259 pci_unmap_single(p
->pdev
, d_image
.dma_addr
,
2260 d_image
.size
, PCI_DMA_FROMDEVICE
);
2261 free_pages(d_image
.virt_addr
, get_order(d_image
.size
));
2266 void __proc_init( struct mgam83fb_par
* p
)
2268 char buf
[256] = { 0, };
2269 struct proc_dir_entry
* entry
;
2271 // TODO not index but pci slot id
2272 sprintf( buf
, PROC_FILENAME
"%d", p
->index
);
2274 entry
= create_proc_entry( buf
, 0, &proc_root
);
2277 entry
->data
= (void*)p
;
2278 entry
->read_proc
= mgafb_proc_read
;
2279 entry
->write_proc
= mgafb_proc_write
;
2283 #endif /* End of MGA_DEBUG */