18 #include <linux/slab.h>
23 static int mem = 8192;
30 static int matroxfb_dh_setcolreg(
unsigned regno,
unsigned red,
unsigned green,
33 #define m2info (container_of(info, struct matroxfb_dh_fb_info, fbcon))
37 if (
m2info->fbcon.var.grayscale) {
39 red = green = blue = (red * 77 + green * 151 + blue * 28) >> 8;
46 col = (red <<
m2info->fbcon.var.red.offset) |
47 (green <<
m2info->fbcon.var.green.offset) |
48 (blue <<
m2info->fbcon.var.blue.offset) |
49 (transp <<
m2info->fbcon.var.transp.offset);
51 switch (
m2info->fbcon.var.bits_per_pixel) {
53 m2info->cmap[regno] = col | (col << 16);
111 if ((mt->
HTotal & 7) == 2) {
112 datactl |= 0x00000010;
122 u_int32_t linelen = m2info->
fbcon.var.xres_virtual * (m2info->
fbcon.var.bits_per_pixel >> 3);
123 if (tmp & 0x02000000) {
136 if (tmp & 0x02000000) {
139 mga_outl(0x3C10, tmp & ~0x02000000);
140 for (i = 0; i < 2; i++) {
142 unsigned int lastl = 0;
144 while ((nl =
mga_inl(0x3C48) & 0xFFF) >= lastl) {
150 minfo->
hw.crtc2.ctl =
tmp;
164 minfo->
hw.crtc2.ctl = 0x00000004;
170 unsigned int linelen;
171 unsigned int pixelsize;
176 pixelsize = m2info->
fbcon.var.bits_per_pixel >> 3;
177 linelen = m2info->
fbcon.var.xres_virtual * pixelsize;
178 pos = m2info->
fbcon.var.yoffset * linelen + m2info->
fbcon.var.xoffset * pixelsize;
179 pos += m2info->
video.offbase;
195 unsigned int vramlen;
198 case 16: mask = 0x1F;
200 case 32: mask = 0x0F;
204 vramlen = m2info->
video.len_usable;
213 if (memlen > vramlen)
227 if (var->
green.length == 5) {
228 var->
red.offset = 10;
230 var->
green.offset = 5;
231 var->
green.length = 5;
232 var->
blue.offset = 0;
233 var->
blue.length = 5;
238 var->
red.offset = 11;
240 var->
green.offset = 5;
241 var->
green.length = 6;
242 var->
blue.offset = 0;
243 var->
blue.length = 5;
248 var->
red.offset = 16;
250 var->
green.offset = 8;
251 var->
green.length = 8;
252 var->
blue.offset = 0;
253 var->
blue.length = 8;
258 *video_cmap_len = 16;
262 static int matroxfb_dh_open(
struct fb_info* info,
int user) {
263 #define m2info (container_of(info, struct matroxfb_dh_fb_info, fbcon))
272 err = minfo->
fbops.fb_open(&minfo->
fbcon, user);
281 static int matroxfb_dh_release(
struct fb_info* info,
int user) {
282 #define m2info (container_of(info, struct matroxfb_dh_fb_info, fbcon))
287 err = minfo->
fbops.fb_release(&minfo->
fbcon, user);
314 #define m2info (container_of(info, struct matroxfb_dh_fb_info, fbcon))
319 return matroxfb_dh_decode_var(m2info, var, &visual, &cmap_len, &mode);
323 static int matroxfb_dh_set_par(
struct fb_info* info) {
324 #define m2info (container_of(info, struct matroxfb_dh_fb_info, fbcon))
332 if ((err = matroxfb_dh_decode_var(m2info, var, &visual, &cmap_len, &mode)) != 0)
336 m2info->
fbcon.screen_base = vaddr_va(m2info->
video.vbase);
337 m2info->
fbcon.fix.visual = visual;
339 m2info->
fbcon.fix.type_aux = 0;
353 pos = (m2info->
fbcon.var.yoffset * m2info->
fbcon.var.xres_virtual + m2info->
fbcon.var.xoffset) * m2info->
fbcon.var.bits_per_pixel >> 3;
354 pos += m2info->
video.offbase;
360 if (minfo->
outputs[out].output->compute) {
369 matroxfb_dh_restore(m2info, &mt, mode, pos);
371 matroxfb_dh_disable(m2info);
373 DAC1064_global_init(minfo);
374 DAC1064_global_restore(minfo);
378 minfo->
outputs[out].output->program) {
384 minfo->
outputs[out].output->start) {
396 #define m2info (container_of(info, struct matroxfb_dh_fb_info, fbcon))
397 matroxfb_dh_pan_var(m2info, var);
406 memset(vblank, 0,
sizeof(*vblank));
422 static int matroxfb_dh_ioctl(
struct fb_info *info,
426 #define m2info (container_of(info, struct matroxfb_dh_fb_info, fbcon))
437 err = matroxfb_dh_get_vblank(m2info, &vblank);
440 if (
copy_to_user((
void __user *)arg, &vblank,
sizeof(vblank)))
459 return minfo->
fbcon.fbops->fb_ioctl(&minfo->
fbcon, cmd, arg);
469 for (out = 0; out < 32; out++) {
470 if (tmp & (1 << out)) {
471 if (out >= MATROXFB_MAX_OUTPUTS)
473 if (!minfo->
outputs[out].output)
475 switch (minfo->
outputs[out].src) {
492 if (tmp & (1 << out)) {
504 matroxfb_dh_set_par(info);
527 if (minfo->
outputs[out].output) {
528 switch (minfo->
outputs[out].src) {
537 tmp &= ~MATROXFB_OUTPUT_CONN_DFP;
551 static int matroxfb_dh_blank(
int blank,
struct fb_info* info) {
552 #define m2info (container_of(info, struct matroxfb_dh_fb_info, fbcon))
565 static struct fb_ops matroxfb_dh_ops = {
567 .fb_open = matroxfb_dh_open,
568 .fb_release = matroxfb_dh_release,
569 .fb_check_var = matroxfb_dh_check_var,
570 .fb_set_par = matroxfb_dh_set_par,
571 .fb_setcolreg = matroxfb_dh_setcolreg,
572 .fb_pan_display =matroxfb_dh_pan_display,
573 .fb_blank = matroxfb_dh_blank,
574 .fb_ioctl = matroxfb_dh_ioctl,
593 39721
L,48L,16L,33L,10L,
601 #define minfo (m2info->primary_dev)
604 m2info->
fbcon.fbops = &matroxfb_dh_ops;
608 m2info->
fbcon.pseudo_palette = m2info->
cmap;
623 m2info->
video.offbase = minfo->
video.len_usable;
627 m2info->
video.vbase.vaddr = vaddr_va(minfo->
video.vbase) + m2info->
video.offbase;
628 m2info->
mmio.base = minfo->
mmio.base;
629 m2info->
mmio.vbase = minfo->
mmio.vbase;
632 matroxfb_dh_init_fix(m2info);
639 oldcrtc2 = minfo->
crtc2.info;
640 minfo->
crtc2.info = m2info;
643 printk(
KERN_ERR "matroxfb_crtc2: Internal consistency check failed: crtc2 already present: %p\n",
653 #define minfo (m2info->primary_dev)
654 if (matroxfb_dh_regit(minfo, m2info)) {
655 printk(
KERN_ERR "matroxfb_crtc2: secondary head failed to register\n");
658 printk(
KERN_INFO "matroxfb_crtc2: secondary head of fb%u was registered as fb%u\n",
666 #define minfo (m2info->primary_dev)
672 crtc2 = minfo->
crtc2.info;
676 if (crtc2 != m2info) {
677 printk(
KERN_ERR "matroxfb_crtc2: Internal consistency check failed: crtc2 mismatch at unload: %p != %p\n",
679 printk(
KERN_ERR "matroxfb_crtc2: Expect kernel crash after module unload.\n");
682 id = m2info->
fbcon.node;
685 minfo->
video.len_usable += m2info->
video.borrowed;
698 m2info = kzalloc(
sizeof(*m2info),
GFP_KERNEL);
700 printk(
KERN_ERR "matroxfb_crtc2: Not enough memory for CRTC2 control structs\n");
704 if (matroxfb_dh_registerfb(m2info)) {
706 printk(
KERN_ERR "matroxfb_crtc2: CRTC2 framebuffer failed to register\n");
712 static void matroxfb_crtc2_remove(
struct matrox_fb_info* minfo,
void* crtc2) {
713 matroxfb_dh_deregisterfb(crtc2);
718 .name =
"Matrox G400 CRTC2",
719 .probe = matroxfb_crtc2_probe,
720 .remove = matroxfb_crtc2_remove };
722 static int matroxfb_crtc2_init(
void) {
730 static void matroxfb_crtc2_exit(
void) {