/* * platinumfb.c -- frame buffer device for the PowerMac 'platinum' display * * Copyright (C) 1998 Franz Sirl * * Frame buffer structure from: * drivers/video/controlfb.c -- frame buffer device for * Apple 'control' display chip. * Copyright (C) 1998 Dan Jacobowitz * * Hardware information from: * platinum.c: Console support for PowerMac "platinum" display adaptor. * Copyright (C) 1996 Paul Mackerras and Mark Abene * * This file is subject to the terms and conditions of the GNU General Public * License. See the file COPYING in the main directory of this archive for * more details.
*/
staticint platinumfb_blank(int blank, struct fb_info *fb)
{ /* * Blank the screen if blank_mode != 0, else unblank. If blank == NULL * then the caller blanks by setting the CLUT (Color Look Up Table) to all * black. Return 0 if blanking succeeded, != 0 if un-/blanking failed due * to e.g. a video mode which doesn't support it. Implements VESA suspend * and powerdown modes on hardware that supports disabling hsync/vsync: * blank_mode == 2: suspend vsync * blank_mode == 3: suspend hsync * blank_mode == 4: powerdown
*/ /* [danj] I think there's something fishy about those constants... */ /* struct fb_info_platinum *info = (struct fb_info_platinum *) fb; int ctrl;
ctrl = le32_to_cpup(&info->platinum_regs->ctrl.r) | 0x33; if (blank) --blank_mode; if (blank & VESA_VSYNC_SUSPEND) ctrl &= ~3; if (blank & VESA_HSYNC_SUSPEND) ctrl &= ~0x30; out_le32(&info->platinum_regs->ctrl.r, ctrl);
*/ /* TODO: Figure out how the heck to powerdown this thing! */ return 0;
}
out_8(&cmap_regs->addr, regno); /* tell clut what addr to fill */
out_8(&cmap_regs->lut, red); /* send one color channel at */
out_8(&cmap_regs->lut, green); /* a time... */
out_8(&cmap_regs->lut, blue);
if (regno < 16) { int i;
u32 *pal = info->pseudo_palette; switch (pinfo->cmode) { case CMODE_16:
pal[regno] = (regno << 10) | (regno << 5) | regno; break; case CMODE_32:
i = (regno << 8) | regno;
pal[regno] = (i << 16) | i; break;
}
}
return 0;
}
staticinlineint platinum_vram_reqd(int video_mode, int color_mode)
{ int baseval = vmode_attrs[video_mode-1].hres * (1<<color_mode);
/* Now how about actually saying, Make it so! */ /* Some things in here probably don't need to be done each time. */ staticvoid platinum_set_hardware(struct fb_info_platinum *pinfo)
{ volatilestruct platinum_regs __iomem *platinum_regs = pinfo->platinum_regs; volatilestruct cmap_regs __iomem *cmap_regs = pinfo->cmap_regs; struct platinum_regvals *init; int i; int vmode, cmode;
/* * Get the monitor sense value. * Note that this can be called before calibrate_delay, * so we can't use udelay.
*/ staticint read_platinum_sense(struct fb_info_platinum *info)
{ volatilestruct platinum_regs __iomem *platinum_regs = info->platinum_regs; int sense;
out_be32(&platinum_regs->reg[23].r, 7); /* turn off drivers */
__delay(2000);
sense = (~in_be32(&platinum_regs->reg[23].r) & 7) << 8;
/* drive each sense line low in turn and collect the other 2 */
out_be32(&platinum_regs->reg[23].r, 3); /* drive A low */
__delay(2000);
sense |= (~in_be32(&platinum_regs->reg[23].r) & 3) << 4;
out_be32(&platinum_regs->reg[23].r, 5); /* drive B low */
__delay(2000);
sense |= (~in_be32(&platinum_regs->reg[23].r) & 4) << 1;
sense |= (~in_be32(&platinum_regs->reg[23].r) & 1) << 2;
out_be32(&platinum_regs->reg[23].r, 6); /* drive C low */
__delay(2000);
sense |= (~in_be32(&platinum_regs->reg[23].r) & 6) >> 1;
out_be32(&platinum_regs->reg[23].r, 7); /* turn off drivers */
return sense;
}
/* * This routine takes a user-supplied var, and picks the best vmode/cmode from it. * It also updates the var structure to the actual mode data obtained
*/ staticint platinum_var_to_par(struct fb_var_screeninfo *var, struct fb_info_platinum *pinfo, int check_only)
{ int vmode, cmode;
/* Do not try to request register space, they overlap with the * northbridge and that can fail. Only request framebuffer
*/ if (!request_mem_region(pinfo->rsrc_fb.start,
resource_size(&pinfo->rsrc_fb), "platinumfb framebuffer")) {
printk(KERN_ERR "platinumfb: Can't request framebuffer !\n");
framebuffer_release(info); return -ENXIO;
}
/* * Try to determine whether we have an old or a new DACula.
*/
out_8(&pinfo->cmap_regs->addr, 0x40);
pinfo->dactype = in_8(&pinfo->cmap_regs->d2); switch (pinfo->dactype) { case 0x3c:
pinfo->clktype = 1;
printk(KERN_INFO "platinumfb: DACula type 0x3c\n"); break; case 0x84:
pinfo->clktype = 0;
printk(KERN_INFO "platinumfb: DACula type 0x84\n"); break; default:
pinfo->clktype = 0;
printk(KERN_INFO "platinumfb: Unknown DACula type: %x\n", pinfo->dactype); break;
}
dev_set_drvdata(&odev->dev, info);
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.