/* The registers in these structs are in NuBus slot space */ struct mdc_cmap_regs { char pad1[0x200200]; unsignedchar addr; char pad2[6]; unsignedchar lut;
};
/* *fbdevwillsetanentirecolourmap,butXwon't.Hopefully *thisshouldaccommodatebothofthem
*/ if (regno != lastreg + 1) { int i;
/* Stab in the dark trying to reset the CLUT pointer */
nubus_writel(0, &dafb_cmap_regs->reset);
nop();
/* Loop until we get to the register we want */ for (i = 0; i < regno; i++) {
nubus_writeb(info->cmap.red[i] >> 8,
&dafb_cmap_regs->lut);
nop();
nubus_writeb(info->cmap.green[i] >> 8,
&dafb_cmap_regs->lut);
nop();
nubus_writeb(info->cmap.blue[i] >> 8,
&dafb_cmap_regs->lut);
nop();
}
}
/* V8 and Brazil seem to use the same DAC. Sonora does as well. */ staticint v8_brazil_setpalette(unsignedint regno, unsignedint red, unsignedint green, unsignedint blue, struct fb_info *info)
{ unsignedint bpp = info->var.bits_per_pixel; unsignedlong flags;
local_irq_save(flags);
/* On these chips, the CLUT register numbers are spread out *acrosstheregisterspace.Thus: *In8bpp,allregnosarevalid. *In4bpp,theregnosare0x0f,0x1f,0x2f,etc,etc *In2bpp,theregnosare0x3f,0x7f,0xbf,0xff
*/
regno = (regno << (8 - bpp)) | (0xFF >> bpp);
nubus_writeb(regno, &v8_brazil_cmap_regs->addr);
nop();
/* send one color channel at a time */
nubus_writeb(red, &v8_brazil_cmap_regs->lut);
nop();
nubus_writeb(green, &v8_brazil_cmap_regs->lut);
nop();
nubus_writeb(blue, &v8_brazil_cmap_regs->lut);
/* From the VideoToolbox driver. Seems to be saying that *regno#254and#255aretheimportantonesfor1-bitcolor, *regno#252-255aretheimportantonesfor2-bitcolor,etc.
*/
regno += 256 - (1 << info->var.bits_per_pixel);
/* tell clut which address to use. */
nubus_writeb(regno, &rbv_cmap_regs->addr);
nop();
/* send one color channel at a time. */
nubus_writeb(red, &rbv_cmap_regs->lut);
nop();
nubus_writeb(green, &rbv_cmap_regs->lut);
nop();
nubus_writeb(blue, &rbv_cmap_regs->lut);
/* the nop's are there to order writes. */
nubus_writeb(regno, &cmap_regs->addr);
nop();
nubus_writeb(red, &cmap_regs->lut);
nop();
nubus_writeb(green, &cmap_regs->lut);
nop();
nubus_writeb(blue, &cmap_regs->lut);
while ((this_opt = strsep(&options, ",")) != NULL) { if (!*this_opt) continue;
if (!strcmp(this_opt, "inverse"))
fb_invert_cmaps(); else if (!strcmp(this_opt, "vidtest"))
vidtest = 1; /* enable experimental CLUT code */
}
}
staticvoid __init iounmap_macfb(void)
{ if (dafb_cmap_regs)
iounmap(dafb_cmap_regs); if (v8_brazil_cmap_regs)
iounmap(v8_brazil_cmap_regs); if (rbv_cmap_regs)
iounmap(rbv_cmap_regs); if (civic_cmap_regs)
iounmap(civic_cmap_regs); if (csc_cmap_regs)
iounmap(csc_cmap_regs);
}
staticint __init macfb_init(void)
{ int video_cmap_len, video_is_nubus = 0; struct nubus_rsrc *ndev = NULL; char *option = NULL; int err;
if (fb_get_options("macfb", &option)) return -ENODEV;
macfb_setup(option);
if (!MACH_IS_MAC) return -ENODEV;
if (mac_bi_data.id == MAC_MODEL_Q630 ||
mac_bi_data.id == MAC_MODEL_P588) return -ENODEV; /* See valkyriefb.c */
pr_info("macfb: framebuffer at 0x%08lx, mapped to 0x%p, size %dk\n",
macfb_fix.smem_start, fb_info.screen_base,
macfb_fix.smem_len / 1024);
pr_info("macfb: mode is %dx%dx%d, linelength=%d\n",
macfb_defined.xres, macfb_defined.yres,
macfb_defined.bits_per_pixel, macfb_fix.line_length);
/* Fill in the available video resolution */
macfb_defined.xres_virtual = macfb_defined.xres;
macfb_defined.yres_virtual = macfb_defined.yres;
macfb_defined.height = PIXEL_TO_MM(macfb_defined.yres);
macfb_defined.width = PIXEL_TO_MM(macfb_defined.xres);
/* Some dummy values for timing to make fbset happy */
macfb_defined.pixclock = 10000000 / macfb_defined.xres * 1000 / macfb_defined.yres;
macfb_defined.left_margin = (macfb_defined.xres / 8) & 0xf8;
macfb_defined.hsync_len = (macfb_defined.xres / 8) & 0xf8;
/* If it's not a NuBus card, it must be internal video */ if (!video_is_nubus) switch (mac_bi_data.id) { /* *DAFBQuadras *Note:thesefirstfourhavethev7DAFB,whichis *knowntoberatherunliketheonesusedinthe *othermodels
*/ case MAC_MODEL_P475: case MAC_MODEL_P475F: case MAC_MODEL_P575: case MAC_MODEL_Q605:
case MAC_MODEL_Q800: case MAC_MODEL_Q650: case MAC_MODEL_Q610: case MAC_MODEL_C650: case MAC_MODEL_C610: case MAC_MODEL_Q700: case MAC_MODEL_Q900: case MAC_MODEL_Q950:
strcpy(macfb_fix.id, "DAFB");
macfb_setpalette = dafb_setpalette;
dafb_cmap_regs = ioremap(DAFB_BASE, 0x1000); break;
/* *Slot0ROMsaysTIM.Noexternalvideo.B&W.
*/ case MAC_MODEL_PB140: case MAC_MODEL_PB145: case MAC_MODEL_PB170:
strcpy(macfb_fix.id, "DDC"); break;
/* *InternalisGSC,External(ifpresent)isViSC
*/ case MAC_MODEL_PB150: /* no external video */ case MAC_MODEL_PB160: case MAC_MODEL_PB165: case MAC_MODEL_PB180: case MAC_MODEL_PB210: case MAC_MODEL_PB230:
strcpy(macfb_fix.id, "GSC"); break;
/* *InternalisTIM,ExternalisViSC
*/ case MAC_MODEL_PB165C: case MAC_MODEL_PB180C:
strcpy(macfb_fix.id, "TIM"); break;
/* *InternalisCSC,ExternalisKeystone+Ariel.
*/ case MAC_MODEL_PB190: /* external video is optional */ case MAC_MODEL_PB520: case MAC_MODEL_PB250: case MAC_MODEL_PB270C: case MAC_MODEL_PB280: case MAC_MODEL_PB280C:
strcpy(macfb_fix.id, "CSC");
macfb_setpalette = csc_setpalette;
csc_cmap_regs = ioremap(CSC_BASE, 0x1000); break;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.