Commit c14b0803 authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] fbdev: Neomagic driver update.

From: James Simmons <jsimmons@infradead.org>

Here is a updated driver for the neomagic.
parent 68f11205
...@@ -22,7 +22,7 @@ obj-$(CONFIG_FB_Q40) += q40fb.o cfbfillrect.o cfbcopyarea.o cfbimgb ...@@ -22,7 +22,7 @@ obj-$(CONFIG_FB_Q40) += q40fb.o cfbfillrect.o cfbcopyarea.o cfbimgb
obj-$(CONFIG_FB_ATARI) += atafb.o obj-$(CONFIG_FB_ATARI) += atafb.o
obj-$(CONFIG_FB_68328) += 68328fb.o obj-$(CONFIG_FB_68328) += 68328fb.o
obj-$(CONFIG_FB_RADEON_OLD) += radeonfb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o obj-$(CONFIG_FB_RADEON_OLD) += radeonfb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
obj-$(CONFIG_FB_NEOMAGIC) += neofb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o obj-$(CONFIG_FB_NEOMAGIC) += neofb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o vgastate.o
obj-$(CONFIG_FB_IGA) += igafb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o obj-$(CONFIG_FB_IGA) += igafb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
obj-$(CONFIG_FB_CONTROL) += controlfb.o macmodes.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o obj-$(CONFIG_FB_CONTROL) += controlfb.o macmodes.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
obj-$(CONFIG_FB_PLATINUM) += platinumfb.o macmodes.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o obj-$(CONFIG_FB_PLATINUM) += platinumfb.o macmodes.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
......
...@@ -81,13 +81,13 @@ extern int tosh_smm(SMMRegisters *regs); ...@@ -81,13 +81,13 @@ extern int tosh_smm(SMMRegisters *regs);
#include <asm/mtrr.h> #include <asm/mtrr.h>
#endif #endif
#include <video/vga.h>
#include <video/neomagic.h> #include <video/neomagic.h>
#define NEOFB_VERSION "0.4.1" #define NEOFB_VERSION "0.4.2"
/* --------------------------------------------------------------------- */ /* --------------------------------------------------------------------- */
static int disabled;
static int internal; static int internal;
static int external; static int external;
static int libretto; static int libretto;
...@@ -100,8 +100,6 @@ static int nopciburst; ...@@ -100,8 +100,6 @@ static int nopciburst;
MODULE_AUTHOR("(c) 2001-2002 Denis Oliver Kropp <dok@convergence.de>"); MODULE_AUTHOR("(c) 2001-2002 Denis Oliver Kropp <dok@convergence.de>");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("FBDev driver for NeoMagic PCI Chips"); MODULE_DESCRIPTION("FBDev driver for NeoMagic PCI Chips");
MODULE_PARM(disabled, "i");
MODULE_PARM_DESC(disabled, "Disable this driver's initialization.");
MODULE_PARM(internal, "i"); MODULE_PARM(internal, "i");
MODULE_PARM_DESC(internal, "Enable output on internal LCD Display."); MODULE_PARM_DESC(internal, "Enable output on internal LCD Display.");
MODULE_PARM(external, "i"); MODULE_PARM(external, "i");
...@@ -152,6 +150,16 @@ static biosMode bios32[] = { ...@@ -152,6 +150,16 @@ static biosMode bios32[] = {
}; };
#endif #endif
static inline u32 read_le32(int regindex, const struct neofb_par *par)
{
return readl(par->neo2200 + par->cursorOff + regindex);
}
static inline void write_le32(int regindex, u32 val, const struct neofb_par *par)
{
writel(val, par->neo2200 + par->cursorOff + regindex);
}
static int neoFindMode(int xres, int yres, int depth) static int neoFindMode(int xres, int yres, int depth)
{ {
int xres_s; int xres_s;
...@@ -363,44 +371,61 @@ static int vgaHWInit(const struct fb_var_screeninfo *var, ...@@ -363,44 +371,61 @@ static int vgaHWInit(const struct fb_var_screeninfo *var,
par->Attribute[18] = 0x0F; par->Attribute[18] = 0x0F;
par->Attribute[19] = 0x00; par->Attribute[19] = 0x00;
par->Attribute[20] = 0x00; par->Attribute[20] = 0x00;
return 0; return 0;
} }
static void vgaHWLock(void) static void vgaHWLock(struct vgastate *state)
{ {
/* Protect CRTC[0-7] */ /* Protect CRTC[0-7] */
VGAwCR(0x11, VGArCR(0x11) | 0x80); vga_wcrt(state->vgabase, 0x11, vga_rcrt(state->vgabase, 0x11) | 0x80);
} }
static void vgaHWUnlock(void) static void vgaHWUnlock(void)
{ {
/* Unprotect CRTC[0-7] */ /* Unprotect CRTC[0-7] */
VGAwCR(0x11, VGArCR(0x11) & ~0x80); vga_wcrt(NULL, 0x11, vga_rcrt(NULL, 0x11) & ~0x80);
} }
static void neoLock(void) static void neoLock(struct vgastate *state)
{ {
VGAwGR(0x09, 0x00); vga_wgfx(state->vgabase, 0x09, 0x00);
vgaHWLock(); vgaHWLock(state);
} }
static void neoUnlock(void) static void neoUnlock(void)
{ {
vgaHWUnlock(); vgaHWUnlock();
VGAwGR(0x09, 0x26); vga_wgfx(NULL, 0x09, 0x26);
} }
/* /*
* vgaHWSeqReset * VGA Palette management
* perform a sequencer reset.
*/ */
void vgaHWSeqReset(int start) static int paletteEnabled = 0;
inline void VGAenablePalette(void)
{ {
if (start) vga_r(NULL, VGA_IS1_RC);
VGAwSEQ(0x00, 0x01); /* Synchronous Reset */ vga_w(NULL, VGA_ATT_W, 0x00);
paletteEnabled = 1;
}
inline void VGAdisablePalette(void)
{
vga_r(NULL, VGA_IS1_RC);
vga_w(NULL, VGA_ATT_W, 0x20);
paletteEnabled = 0;
}
inline void VGAwATTR(u8 index, u8 value)
{
if (paletteEnabled)
index &= ~0x20;
else else
VGAwSEQ(0x00, 0x03); /* End Reset */ index |= 0x20;
vga_r(NULL, VGA_IS1_RC);
vga_wattr(NULL, index, value);
} }
void vgaHWProtect(int on) void vgaHWProtect(int on)
...@@ -411,21 +436,18 @@ void vgaHWProtect(int on) ...@@ -411,21 +436,18 @@ void vgaHWProtect(int on)
/* /*
* Turn off screen and disable sequencer. * Turn off screen and disable sequencer.
*/ */
tmp = VGArSEQ(0x01); tmp = vga_rseq(NULL, 0x01);
vga_wseq(NULL, 0x00, 0x01); /* Synchronous Reset */
vgaHWSeqReset(1); /* start synchronous reset */ vga_wseq(NULL, 0x01, tmp | 0x20); /* disable the display */
VGAwSEQ(0x01, tmp | 0x20); /* disable the display */
VGAenablePalette(); VGAenablePalette();
} else { } else {
/* /*
* Reenable sequencer, then turn on screen. * Reenable sequencer, then turn on screen.
*/ */
tmp = vga_rseq(NULL, 0x01);
tmp = VGArSEQ(0x01); vga_wseq(NULL, 0x01, tmp & ~0x20); /* reenable display */
vga_wseq(NULL, 0x00, 0x03); /* clear synchronousreset */
VGAwSEQ(0x01, tmp & ~0x20); /* reenable display */
vgaHWSeqReset(0); /* clear synchronousreset */
VGAdisablePalette(); VGAdisablePalette();
} }
...@@ -436,19 +458,19 @@ static void vgaHWRestore(const struct fb_info *info, ...@@ -436,19 +458,19 @@ static void vgaHWRestore(const struct fb_info *info,
{ {
int i; int i;
VGAwMISC(par->MiscOutReg); vga_w(NULL, VGA_MIS_W, par->MiscOutReg);
for (i = 1; i < 5; i++) for (i = 1; i < 5; i++)
VGAwSEQ(i, par->Sequencer[i]); vga_wseq(NULL, i, par->Sequencer[i]);
/* Ensure CRTC registers 0-7 are unlocked by clearing bit 7 or CRTC[17] */ /* Ensure CRTC registers 0-7 are unlocked by clearing bit 7 or CRTC[17] */
VGAwCR(17, par->CRTC[17] & ~0x80); vga_wcrt(NULL, 17, par->CRTC[17] & ~0x80);
for (i = 0; i < 25; i++) for (i = 0; i < 25; i++)
VGAwCR(i, par->CRTC[i]); vga_wcrt(NULL, i, par->CRTC[i]);
for (i = 0; i < 9; i++) for (i = 0; i < 9; i++)
VGAwGR(i, par->Graphics[i]); vga_wgfx(NULL, i, par->Graphics[i]);
VGAenablePalette(); VGAenablePalette();
...@@ -534,6 +556,36 @@ static inline void neo2200_accel_init(struct fb_info *info, ...@@ -534,6 +556,36 @@ static inline void neo2200_accel_init(struct fb_info *info,
/* --------------------------------------------------------------------- */ /* --------------------------------------------------------------------- */
static int
neofb_open(struct fb_info *info, int user)
{
struct neofb_par *par = (struct neofb_par *) info->par;
int cnt = atomic_read(&par->ref_count);
if (cnt) {
memset(&par->state, 0, sizeof(struct vgastate));
par->state.flags = VGA_SAVE_MODE | VGA_SAVE_FONTS;
save_vga(&par->state);
}
atomic_inc(&par->ref_count);
return 0;
}
static int
neofb_release(struct fb_info *info, int user)
{
struct neofb_par *par = (struct neofb_par *) info->par;
int cnt = atomic_read(&par->ref_count);
if (!cnt)
return -EINVAL;
if (cnt == 1) {
restore_vga(&par->state);
}
atomic_dec(&par->ref_count);
return 0;
}
static int static int
neofb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) neofb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
{ {
...@@ -672,15 +724,12 @@ neofb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) ...@@ -672,15 +724,12 @@ neofb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
if (var->xres_virtual < var->xres) if (var->xres_virtual < var->xres)
var->xres_virtual = var->xres; var->xres_virtual = var->xres;
memlen = memlen = var->xres_virtual * var->bits_per_pixel * var->yres_virtual >> 3;
var->xres_virtual * var->bits_per_pixel * var->yres_virtual /
8;
if (memlen > vramlen) { if (memlen > vramlen) {
var->yres_virtual = var->yres_virtual = vramlen * 8 / (var->xres_virtual *
vramlen * 8 / (var->xres_virtual *
var->bits_per_pixel); var->bits_per_pixel);
memlen = memlen = var->xres_virtual * var->bits_per_pixel *
var->xres_virtual * var->bits_per_pixel *
var->yres_virtual / 8; var->yres_virtual / 8;
} }
...@@ -981,13 +1030,13 @@ static int neofb_set_par(struct fb_info *info) ...@@ -981,13 +1030,13 @@ static int neofb_set_par(struct fb_info *info)
} }
/* alread unlocked above */ /* alread unlocked above */
/* BOGUS VGAwGR (0x09, 0x26); */ /* BOGUS vga_wgfx(NULL, 0x09, 0x26); */
/* don't know what this is, but it's 0 from bootup anyway */ /* don't know what this is, but it's 0 from bootup anyway */
VGAwGR(0x15, 0x00); vga_wgfx(NULL, 0x15, 0x00);
/* was set to 0x01 by my bios in text and vesa modes */ /* was set to 0x01 by my bios in text and vesa modes */
VGAwGR(0x0A, par->GeneralLockReg); vga_wgfx(NULL, 0x0A, par->GeneralLockReg);
/* /*
* The color mode needs to be set before calling vgaHWRestore * The color mode needs to be set before calling vgaHWRestore
...@@ -996,7 +1045,7 @@ static int neofb_set_par(struct fb_info *info) ...@@ -996,7 +1045,7 @@ static int neofb_set_par(struct fb_info *info)
* NOTE: Make sure we don't change bits make sure we don't change * NOTE: Make sure we don't change bits make sure we don't change
* any reserved bits. * any reserved bits.
*/ */
temp = VGArGR(0x90); temp = vga_rgfx(NULL, 0x90);
switch (info->fix.accel) { switch (info->fix.accel) {
case FB_ACCEL_NEOMAGIC_NM2070: case FB_ACCEL_NEOMAGIC_NM2070:
temp &= 0xF0; /* Save bits 7:4 */ temp &= 0xF0; /* Save bits 7:4 */
...@@ -1015,7 +1064,7 @@ static int neofb_set_par(struct fb_info *info) ...@@ -1015,7 +1064,7 @@ static int neofb_set_par(struct fb_info *info)
break; break;
} }
VGAwGR(0x90, temp); vga_wgfx(NULL, 0x90, temp);
/* /*
* In some rare cases a lockup might occur if we don't delay * In some rare cases a lockup might occur if we don't delay
...@@ -1027,9 +1076,9 @@ static int neofb_set_par(struct fb_info *info) ...@@ -1027,9 +1076,9 @@ static int neofb_set_par(struct fb_info *info)
* Disable horizontal and vertical graphics and text expansions so * Disable horizontal and vertical graphics and text expansions so
* that vgaHWRestore works properly. * that vgaHWRestore works properly.
*/ */
temp = VGArGR(0x25); temp = vga_rgfx(NULL, 0x25);
temp &= 0x39; temp &= 0x39;
VGAwGR(0x25, temp); vga_wgfx(NULL, 0x25, temp);
/* /*
* Sleep for 200ms to make sure that the two operations above have * Sleep for 200ms to make sure that the two operations above have
...@@ -1041,19 +1090,18 @@ static int neofb_set_par(struct fb_info *info) ...@@ -1041,19 +1090,18 @@ static int neofb_set_par(struct fb_info *info)
* This function handles restoring the generic VGA registers. */ * This function handles restoring the generic VGA registers. */
vgaHWRestore(info, par); vgaHWRestore(info, par);
vga_wgfx(NULL, 0x0E, par->ExtCRTDispAddr);
VGAwGR(0x0E, par->ExtCRTDispAddr); vga_wgfx(NULL, 0x0F, par->ExtCRTOffset);
VGAwGR(0x0F, par->ExtCRTOffset); temp = vga_rgfx(NULL, 0x10);
temp = VGArGR(0x10);
temp &= 0x0F; /* Save bits 3:0 */ temp &= 0x0F; /* Save bits 3:0 */
temp |= (par->SysIfaceCntl1 & ~0x0F); /* VESA Bios sets bit 1! */ temp |= (par->SysIfaceCntl1 & ~0x0F); /* VESA Bios sets bit 1! */
VGAwGR(0x10, temp); vga_wgfx(NULL, 0x10, temp);
VGAwGR(0x11, par->SysIfaceCntl2); vga_wgfx(NULL, 0x11, par->SysIfaceCntl2);
VGAwGR(0x15, 0 /*par->SingleAddrPage */ ); vga_wgfx(NULL, 0x15, 0 /*par->SingleAddrPage */ );
VGAwGR(0x16, 0 /*par->DualAddrPage */ ); vga_wgfx(NULL, 0x16, 0 /*par->DualAddrPage */ );
temp = VGArGR(0x20); temp = vga_rgfx(NULL, 0x20);
switch (info->fix.accel) { switch (info->fix.accel) {
case FB_ACCEL_NEOMAGIC_NM2070: case FB_ACCEL_NEOMAGIC_NM2070:
temp &= 0xFC; /* Save bits 7:2 */ temp &= 0xFC; /* Save bits 7:2 */
...@@ -1074,79 +1122,78 @@ static int neofb_set_par(struct fb_info *info) ...@@ -1074,79 +1122,78 @@ static int neofb_set_par(struct fb_info *info)
temp |= (par->PanelDispCntlReg1 & ~0x98); temp |= (par->PanelDispCntlReg1 & ~0x98);
break; break;
} }
VGAwGR(0x20, temp); vga_wgfx(NULL, 0x20, temp);
temp = VGArGR(0x25); temp = vga_rgfx(NULL, 0x25);
temp &= 0x38; /* Save bits 5:3 */ temp &= 0x38; /* Save bits 5:3 */
temp |= (par->PanelDispCntlReg2 & ~0x38); temp |= (par->PanelDispCntlReg2 & ~0x38);
VGAwGR(0x25, temp); vga_wgfx(NULL, 0x25, temp);
if (info->fix.accel != FB_ACCEL_NEOMAGIC_NM2070) { if (info->fix.accel != FB_ACCEL_NEOMAGIC_NM2070) {
temp = VGArGR(0x30); temp = vga_rgfx(NULL, 0x30);
temp &= 0xEF; /* Save bits 7:5 and bits 3:0 */ temp &= 0xEF; /* Save bits 7:5 and bits 3:0 */
temp |= (par->PanelDispCntlReg3 & ~0xEF); temp |= (par->PanelDispCntlReg3 & ~0xEF);
VGAwGR(0x30, temp); vga_wgfx(NULL, 0x30, temp);
} }
VGAwGR(0x28, par->PanelVertCenterReg1); vga_wgfx(NULL, 0x28, par->PanelVertCenterReg1);
VGAwGR(0x29, par->PanelVertCenterReg2); vga_wgfx(NULL, 0x29, par->PanelVertCenterReg2);
VGAwGR(0x2a, par->PanelVertCenterReg3); vga_wgfx(NULL, 0x2a, par->PanelVertCenterReg3);
if (info->fix.accel != FB_ACCEL_NEOMAGIC_NM2070) { if (info->fix.accel != FB_ACCEL_NEOMAGIC_NM2070) {
VGAwGR(0x32, par->PanelVertCenterReg4); vga_wgfx(NULL, 0x32, par->PanelVertCenterReg4);
VGAwGR(0x33, par->PanelHorizCenterReg1); vga_wgfx(NULL, 0x33, par->PanelHorizCenterReg1);
VGAwGR(0x34, par->PanelHorizCenterReg2); vga_wgfx(NULL, 0x34, par->PanelHorizCenterReg2);
VGAwGR(0x35, par->PanelHorizCenterReg3); vga_wgfx(NULL, 0x35, par->PanelHorizCenterReg3);
} }
if (info->fix.accel == FB_ACCEL_NEOMAGIC_NM2160) if (info->fix.accel == FB_ACCEL_NEOMAGIC_NM2160)
VGAwGR(0x36, par->PanelHorizCenterReg4); vga_wgfx(NULL, 0x36, par->PanelHorizCenterReg4);
if (info->fix.accel == FB_ACCEL_NEOMAGIC_NM2200 || if (info->fix.accel == FB_ACCEL_NEOMAGIC_NM2200 ||
info->fix.accel == FB_ACCEL_NEOMAGIC_NM2230 || info->fix.accel == FB_ACCEL_NEOMAGIC_NM2230 ||
info->fix.accel == FB_ACCEL_NEOMAGIC_NM2360 || info->fix.accel == FB_ACCEL_NEOMAGIC_NM2360 ||
info->fix.accel == FB_ACCEL_NEOMAGIC_NM2380) { info->fix.accel == FB_ACCEL_NEOMAGIC_NM2380) {
VGAwGR(0x36, par->PanelHorizCenterReg4); vga_wgfx(NULL, 0x36, par->PanelHorizCenterReg4);
VGAwGR(0x37, par->PanelVertCenterReg5); vga_wgfx(NULL, 0x37, par->PanelVertCenterReg5);
VGAwGR(0x38, par->PanelHorizCenterReg5); vga_wgfx(NULL, 0x38, par->PanelHorizCenterReg5);
clock_hi = 1; clock_hi = 1;
} }
/* Program VCLK3 if needed. */ /* Program VCLK3 if needed. */
if (par->ProgramVCLK && ((VGArGR(0x9B) != par->VCLK3NumeratorLow) if (par->ProgramVCLK && ((vga_rgfx(NULL, 0x9B) != par->VCLK3NumeratorLow)
|| (VGArGR(0x9F) != par->VCLK3Denominator) || (vga_rgfx(NULL, 0x9F) != par->VCLK3Denominator)
|| (clock_hi && ((VGArGR(0x8F) & ~0x0f) || (clock_hi && ((vga_rgfx(NULL, 0x8F) & ~0x0f)
!= (par-> != (par->VCLK3NumeratorHigh &
VCLK3NumeratorHigh &
~0x0F))))) { ~0x0F))))) {
VGAwGR(0x9B, par->VCLK3NumeratorLow); vga_wgfx(NULL, 0x9B, par->VCLK3NumeratorLow);
if (clock_hi) { if (clock_hi) {
temp = VGArGR(0x8F); temp = vga_rgfx(NULL, 0x8F);
temp &= 0x0F; /* Save bits 3:0 */ temp &= 0x0F; /* Save bits 3:0 */
temp |= (par->VCLK3NumeratorHigh & ~0x0F); temp |= (par->VCLK3NumeratorHigh & ~0x0F);
VGAwGR(0x8F, temp); vga_wgfx(NULL, 0x8F, temp);
} }
VGAwGR(0x9F, par->VCLK3Denominator); vga_wgfx(NULL, 0x9F, par->VCLK3Denominator);
} }
if (par->biosMode) if (par->biosMode)
VGAwCR(0x23, par->biosMode); vga_wcrt(NULL, 0x23, par->biosMode);
VGAwGR(0x93, 0xc0); /* Gives 5x faster framebuffer writes !!! */ vga_wgfx(NULL, 0x93, 0xc0); /* Gives 5x faster framebuffer writes !!! */
/* Program vertical extension register */ /* Program vertical extension register */
if (info->fix.accel == FB_ACCEL_NEOMAGIC_NM2200 || if (info->fix.accel == FB_ACCEL_NEOMAGIC_NM2200 ||
info->fix.accel == FB_ACCEL_NEOMAGIC_NM2230 || info->fix.accel == FB_ACCEL_NEOMAGIC_NM2230 ||
info->fix.accel == FB_ACCEL_NEOMAGIC_NM2360 || info->fix.accel == FB_ACCEL_NEOMAGIC_NM2360 ||
info->fix.accel == FB_ACCEL_NEOMAGIC_NM2380) { info->fix.accel == FB_ACCEL_NEOMAGIC_NM2380) {
VGAwCR(0x70, par->VerticalExt); vga_wcrt(NULL, 0x70, par->VerticalExt);
} }
vgaHWProtect(0); /* Turn on screen */ vgaHWProtect(0); /* Turn on screen */
/* Calling this also locks offset registers required in update_start */ /* Calling this also locks offset registers required in update_start */
neoLock(); neoLock(&par->state);
info->fix.line_length = info->fix.line_length =
info->var.xres_virtual * (info->var.bits_per_pixel >> 3); info->var.xres_virtual * (info->var.bits_per_pixel >> 3);
...@@ -1167,6 +1214,8 @@ static int neofb_set_par(struct fb_info *info) ...@@ -1167,6 +1214,8 @@ static int neofb_set_par(struct fb_info *info)
static void neofb_update_start(struct fb_info *info, static void neofb_update_start(struct fb_info *info,
struct fb_var_screeninfo *var) struct fb_var_screeninfo *var)
{ {
struct neofb_par *par = (struct neofb_par *) info->par;
struct vgastate *state = &par->state;
int oldExtCRTDispAddr; int oldExtCRTDispAddr;
int Base; int Base;
...@@ -1180,18 +1229,18 @@ static void neofb_update_start(struct fb_info *info, ...@@ -1180,18 +1229,18 @@ static void neofb_update_start(struct fb_info *info,
/* /*
* These are the generic starting address registers. * These are the generic starting address registers.
*/ */
VGAwCR(0x0C, (Base & 0x00FF00) >> 8); vga_wcrt(state->vgabase, 0x0C, (Base & 0x00FF00) >> 8);
VGAwCR(0x0D, (Base & 0x00FF)); vga_wcrt(state->vgabase, 0x0D, (Base & 0x00FF));
/* /*
* Make sure we don't clobber some other bits that might already * Make sure we don't clobber some other bits that might already
* have been set. NOTE: NM2200 has a writable bit 3, but it shouldn't * have been set. NOTE: NM2200 has a writable bit 3, but it shouldn't
* be needed. * be needed.
*/ */
oldExtCRTDispAddr = VGArGR(0x0E); oldExtCRTDispAddr = vga_rgfx(NULL, 0x0E);
VGAwGR(0x0E, (((Base >> 16) & 0x0f) | (oldExtCRTDispAddr & 0xf0))); vga_wgfx(state->vgabase, 0x0E, (((Base >> 16) & 0x0f) | (oldExtCRTDispAddr & 0xf0)));
neoLock(); neoLock(state);
} }
/* /*
...@@ -1227,7 +1276,7 @@ static int neofb_pan_display(struct fb_var_screeninfo *var, ...@@ -1227,7 +1276,7 @@ static int neofb_pan_display(struct fb_var_screeninfo *var,
static int neofb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, static int neofb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
u_int transp, struct fb_info *fb) u_int transp, struct fb_info *fb)
{ {
if (regno >= NR_PALETTE) if (regno >= 255)
return -EINVAL; return -EINVAL;
switch (fb->var.bits_per_pixel) { switch (fb->var.bits_per_pixel) {
...@@ -1353,7 +1402,7 @@ neo2200_fillrect(struct fb_info *info, const struct fb_fillrect *rect) ...@@ -1353,7 +1402,7 @@ neo2200_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
} }
par->neo2200->dstStart = par->neo2200->dstStart =
dst * ((info->var.bits_per_pixel + 7) / 8); dst * ((info->var.bits_per_pixel + 7) >> 3);
par->neo2200->xyExt = par->neo2200->xyExt =
(rect->height << 16) | (rect->width & 0xffff); (rect->height << 16) | (rect->width & 0xffff);
} }
...@@ -1361,24 +1410,20 @@ neo2200_fillrect(struct fb_info *info, const struct fb_fillrect *rect) ...@@ -1361,24 +1410,20 @@ neo2200_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
static void static void
neo2200_copyarea(struct fb_info *info, const struct fb_copyarea *area) neo2200_copyarea(struct fb_info *info, const struct fb_copyarea *area)
{ {
struct neofb_par *par = (struct neofb_par *) info->par;
u32 sx = area->sx, sy = area->sy, dx = area->dx, dy = area->dy; u32 sx = area->sx, sy = area->sy, dx = area->dx, dy = area->dy;
struct neofb_par *par = (struct neofb_par *) info->par;
u_long src, dst, bltCntl; u_long src, dst, bltCntl;
bltCntl = NEO_BC3_FIFO_EN | NEO_BC3_SKIP_MAPPING | 0x0C0000; bltCntl = NEO_BC3_FIFO_EN | NEO_BC3_SKIP_MAPPING | 0x0C0000;
if (sy < dy) { if ((dy > sy) || ((dy == sy) && (dx > sx))) {
/* Start with the lower right corner */
sy += (area->height - 1); sy += (area->height - 1);
dy += (area->height - 1); dy += (area->height - 1);
bltCntl |= NEO_BC0_DST_Y_DEC | NEO_BC0_SRC_Y_DEC;
}
if (area->sx < area->dx) {
sx += (area->width - 1); sx += (area->width - 1);
dx += (area->width - 1); dx += (area->width - 1);
bltCntl |= NEO_BC0_X_DEC; bltCntl |= NEO_BC0_X_DEC | NEO_BC0_DST_Y_DEC | NEO_BC0_SRC_Y_DEC;
} }
src = sx * (info->var.bits_per_pixel >> 3) + sy*info->fix.line_length; src = sx * (info->var.bits_per_pixel >> 3) + sy*info->fix.line_length;
...@@ -1395,6 +1440,7 @@ neo2200_copyarea(struct fb_info *info, const struct fb_copyarea *area) ...@@ -1395,6 +1440,7 @@ neo2200_copyarea(struct fb_info *info, const struct fb_copyarea *area)
(area->height << 16) | (area->width & 0xffff); (area->height << 16) | (area->width & 0xffff);
} }
/*
static void static void
neo2200_imageblit(struct fb_info *info, const struct fb_image *image) neo2200_imageblit(struct fb_info *info, const struct fb_image *image)
{ {
...@@ -1431,6 +1477,7 @@ neo2200_imageblit(struct fb_info *info, const struct fb_image *image) ...@@ -1431,6 +1477,7 @@ neo2200_imageblit(struct fb_info *info, const struct fb_image *image)
memcpy(par->mmio_vbase + 0x100000, image->data, memcpy(par->mmio_vbase + 0x100000, image->data,
(image->width * image->height) >> 3); (image->width * image->height) >> 3);
} }
*/
static void static void
neofb_fillrect(struct fb_info *info, const struct fb_fillrect *rect) neofb_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
...@@ -1467,6 +1514,8 @@ neofb_copyarea(struct fb_info *info, const struct fb_copyarea *area) ...@@ -1467,6 +1514,8 @@ neofb_copyarea(struct fb_info *info, const struct fb_copyarea *area)
static void static void
neofb_imageblit(struct fb_info *info, const struct fb_image *image) neofb_imageblit(struct fb_info *info, const struct fb_image *image)
{ {
/*
if (image->depth == 1) {
switch (info->fix.accel) { switch (info->fix.accel) {
case FB_ACCEL_NEOMAGIC_NM2200: case FB_ACCEL_NEOMAGIC_NM2200:
case FB_ACCEL_NEOMAGIC_NM2230: case FB_ACCEL_NEOMAGIC_NM2230:
...@@ -1478,6 +1527,9 @@ neofb_imageblit(struct fb_info *info, const struct fb_image *image) ...@@ -1478,6 +1527,9 @@ neofb_imageblit(struct fb_info *info, const struct fb_image *image)
cfb_imageblit(info, image); cfb_imageblit(info, image);
break; break;
} }
} else
*/
cfb_imageblit(info, image);
} }
static int static int
...@@ -1496,8 +1548,67 @@ neofb_sync(struct fb_info *info) ...@@ -1496,8 +1548,67 @@ neofb_sync(struct fb_info *info)
return 0; return 0;
} }
/*
static void
neofb_draw_cursor(struct fb_info *info, u8 *dst, u8 *src, unsigned int width)
{
//memset_io(info->sprite.addr, 0xff, 1);
}
static int
neofb_cursor(struct fb_info *info, struct fb_cursor *cursor)
{
struct neofb_par *par = (struct neofb_par *) info->par;
* Disable cursor *
write_le32(NEOREG_CURSCNTL, ~NEO_CURS_ENABLE, par);
if (cursor->set & FB_CUR_SETPOS) {
u32 x = cursor->image.dx;
u32 y = cursor->image.dy;
info->cursor.image.dx = x;
info->cursor.image.dy = y;
write_le32(NEOREG_CURSX, x, par);
write_le32(NEOREG_CURSY, y, par);
}
if (cursor->set & FB_CUR_SETSIZE) {
info->cursor.image.height = cursor->image.height;
info->cursor.image.width = cursor->image.width;
}
if (cursor->set & FB_CUR_SETHOT)
info->cursor.hot = cursor->hot;
if (cursor->set & FB_CUR_SETCMAP) {
if (cursor->image.depth == 1) {
u32 fg = cursor->image.fg_color;
u32 bg = cursor->image.bg_color;
info->cursor.image.fg_color = fg;
info->cursor.image.bg_color = bg;
fg = ((fg & 0xff0000) >> 16) | ((fg & 0xff) << 16) | (fg & 0xff00);
bg = ((bg & 0xff0000) >> 16) | ((bg & 0xff) << 16) | (bg & 0xff00);
write_le32(NEOREG_CURSFGCOLOR, fg, par);
write_le32(NEOREG_CURSBGCOLOR, bg, par);
}
}
if (cursor->set & FB_CUR_SETSHAPE)
fb_load_cursor_image(info);
if (info->cursor.enable)
write_le32(NEOREG_CURSCNTL, NEO_CURS_ENABLE, par);
return 0;
}
*/
static struct fb_ops neofb_ops = { static struct fb_ops neofb_ops = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.fb_open = neofb_open,
.fb_release = neofb_release,
.fb_check_var = neofb_check_var, .fb_check_var = neofb_check_var,
.fb_set_par = neofb_set_par, .fb_set_par = neofb_set_par,
.fb_setcolreg = neofb_setcolreg, .fb_setcolreg = neofb_setcolreg,
...@@ -1631,31 +1742,31 @@ static int __devinit neo_map_mmio(struct fb_info *info, ...@@ -1631,31 +1742,31 @@ static int __devinit neo_map_mmio(struct fb_info *info,
return 0; return 0;
} }
static void __devinit neo_unmap_mmio(struct fb_info *info) static void neo_unmap_mmio(struct fb_info *info)
{ {
struct neofb_par *par = (struct neofb_par *) info->par; struct neofb_par *par = (struct neofb_par *) info->par;
DBG("neo_unmap_mmio"); DBG("neo_unmap_mmio");
if (par->mmio_vbase) {
iounmap(par->mmio_vbase); iounmap(par->mmio_vbase);
par->mmio_vbase = NULL; par->mmio_vbase = NULL;
release_mem_region(info->fix.mmio_start, release_mem_region(info->fix.mmio_start,
info->fix.mmio_len); info->fix.mmio_len);
}
} }
static int __devinit neo_map_video(struct fb_info *info, static int __devinit neo_map_video(struct fb_info *info,
struct pci_dev *dev, int video_len) struct pci_dev *dev, int video_len)
{ {
//unsigned long addr;
DBG("neo_map_video"); DBG("neo_map_video");
info->fix.smem_start = pci_resource_start(dev, 0); info->fix.smem_start = pci_resource_start(dev, 0);
info->fix.smem_len = video_len; info->fix.smem_len = video_len;
if (!request_mem_region if (!request_mem_region(info->fix.smem_start, info->fix.smem_len,
(info->fix.smem_start, info->fix.smem_len, "frame buffer")) { "frame buffer")) {
printk("neofb: frame buffer in use\n"); printk("neofb: frame buffer in use\n");
return -EBUSY; return -EBUSY;
} }
...@@ -1679,27 +1790,30 @@ static int __devinit neo_map_video(struct fb_info *info, ...@@ -1679,27 +1790,30 @@ static int __devinit neo_map_video(struct fb_info *info,
/* Clear framebuffer, it's all white in memory after boot */ /* Clear framebuffer, it's all white in memory after boot */
memset(info->screen_base, 0, info->fix.smem_len); memset(info->screen_base, 0, info->fix.smem_len);
/* Allocate Cursor drawing pad.
info->fix.smem_len -= PAGE_SIZE;
addr = info->fix.smem_start + info->fix.smem_len;
write_le32(NEOREG_CURSMEMPOS, ((0x000f & (addr >> 10)) << 8) |
((0x0ff0 & (addr >> 10)) >> 4), par);
addr = (unsigned long) info->screen_base + info->fix.smem_len;
info->sprite.addr = (u8 *) addr; */
return 0; return 0;
} }
static void __devinit neo_unmap_video(struct fb_info *info) static void neo_unmap_video(struct fb_info *info)
{ {
DBG("neo_unmap_video");
if (info->screen_base) {
#ifdef CONFIG_MTRR #ifdef CONFIG_MTRR
struct neofb_par *par = (struct neofb_par *) info->par; struct neofb_par *par = (struct neofb_par *) info->par;
mtrr_del(par->mtrr, info->fix.smem_start, mtrr_del(par->mtrr, info->fix.smem_start,
info->fix.smem_len); info->fix.smem_len);
#endif #endif
iounmap(info->screen_base); iounmap(info->screen_base);
info->screen_base = NULL; info->screen_base = NULL;
release_mem_region(info->fix.smem_start, release_mem_region(info->fix.smem_start,
info->fix.smem_len); info->fix.smem_len);
}
} }
static int __devinit neo_init_hw(struct fb_info *info) static int __devinit neo_init_hw(struct fb_info *info)
...@@ -1723,16 +1837,16 @@ static int __devinit neo_init_hw(struct fb_info *info) ...@@ -1723,16 +1837,16 @@ static int __devinit neo_init_hw(struct fb_info *info)
printk(KERN_DEBUG "--- Neo extended register dump ---\n"); printk(KERN_DEBUG "--- Neo extended register dump ---\n");
for (w = 0; w < 0x85; w++) for (w = 0; w < 0x85; w++)
printk(KERN_DEBUG "CR %p: %p\n", (void *) w, printk(KERN_DEBUG "CR %p: %p\n", (void *) w,
(void *) VGArCR(w)); (void *) vga_rcrt(NULL, w);
for (w = 0; w < 0xC7; w++) for (w = 0; w < 0xC7; w++)
printk(KERN_DEBUG "GR %p: %p\n", (void *) w, printk(KERN_DEBUG "GR %p: %p\n", (void *) w,
(void *) VGArGR(w)); (void *) vga_rgfx(NULL, w));
#endif #endif
/* Determine the panel type */ /* Determine the panel type */
VGAwGR(0x09, 0x26); vga_wgfx(NULL, 0x09, 0x26);
type = VGArGR(0x21); type = vga_rgfx(NULL, 0x21);
display = VGArGR(0x20); display = vga_rgfx(NULL, 0x20);
if (!par->internal_display && !par->external_display) { if (!par->internal_display && !par->external_display) {
par->internal_display = display & 2 || !(display & 3) ? 1 : 0; par->internal_display = display & 2 || !(display & 3) ? 1 : 0;
par->external_display = display & 1; par->external_display = display & 1;
...@@ -1742,8 +1856,8 @@ static int __devinit neo_init_hw(struct fb_info *info) ...@@ -1742,8 +1856,8 @@ static int __devinit neo_init_hw(struct fb_info *info)
} }
/* Determine panel width -- used in NeoValidMode. */ /* Determine panel width -- used in NeoValidMode. */
w = VGArGR(0x20); w = vga_rgfx(NULL, 0x20);
VGAwGR(0x09, 0x00); vga_wgfx(NULL, 0x09, 0x00);
switch ((w & 0x18) >> 3) { switch ((w & 0x18) >> 3) {
case 0x00: case 0x00:
par->NeoPanelWidth = 640; par->NeoPanelWidth = 640;
...@@ -1868,10 +1982,16 @@ static int __devinit neo_init_hw(struct fb_info *info) ...@@ -1868,10 +1982,16 @@ static int __devinit neo_init_hw(struct fb_info *info)
par->neo2200 = (Neo2200 *) par->mmio_vbase; par->neo2200 = (Neo2200 *) par->mmio_vbase;
break; break;
} }
/*
info->sprite.size = CursorMem;
info->sprite.scan_align = 1;
info->sprite.buf_align = 1;
info->sprite.flags = FB_PIXMAP_IO;
info->sprite.outbuf = neofb_draw_cursor;
*/
par->maxClock = maxClock; par->maxClock = maxClock;
par->cursorOff = CursorOff;
return videoRam * 1024; return ((videoRam * 1024));
} }
...@@ -1881,15 +2001,12 @@ static struct fb_info *__devinit neo_alloc_fb_info(struct pci_dev *dev, const st ...@@ -1881,15 +2001,12 @@ static struct fb_info *__devinit neo_alloc_fb_info(struct pci_dev *dev, const st
struct fb_info *info; struct fb_info *info;
struct neofb_par *par; struct neofb_par *par;
info = kmalloc(sizeof(struct fb_info) + sizeof(struct neofb_par) + info = framebuffer_alloc(sizeof(struct neofb_par) + sizeof(u32) * 256, &dev->dev);
sizeof(u32) * 17, GFP_KERNEL);
if (!info) if (!info)
return NULL; return NULL;
memset(info, 0, sizeof(struct fb_info) + sizeof(struct neofb_par) + sizeof(u32) * 17); par = info->par;
par = (struct neofb_par *) (info + 1);
info->fix.accel = id->driver_data; info->fix.accel = id->driver_data;
...@@ -1939,23 +2056,18 @@ static struct fb_info *__devinit neo_alloc_fb_info(struct pci_dev *dev, const st ...@@ -1939,23 +2056,18 @@ static struct fb_info *__devinit neo_alloc_fb_info(struct pci_dev *dev, const st
info->fbops = &neofb_ops; info->fbops = &neofb_ops;
info->flags = FBINFO_FLAG_DEFAULT; info->flags = FBINFO_FLAG_DEFAULT;
info->par = par;
info->pseudo_palette = (void *) (par + 1); info->pseudo_palette = (void *) (par + 1);
fb_alloc_cmap(&info->cmap, NR_PALETTE, 0);
return info; return info;
} }
static void __devinit neo_free_fb_info(struct fb_info *info) static void neo_free_fb_info(struct fb_info *info)
{ {
if (info) { if (info) {
/* /*
* Free the colourmap * Free the colourmap
*/ */
fb_alloc_cmap(&info->cmap, 0, 0); fb_dealloc_cmap(&info->cmap);
framebuffer_release(info);
kfree(info);
} }
} }
...@@ -1978,21 +2090,24 @@ static int __devinit neofb_probe(struct pci_dev *dev, ...@@ -1978,21 +2090,24 @@ static int __devinit neofb_probe(struct pci_dev *dev,
err = -ENOMEM; err = -ENOMEM;
info = neo_alloc_fb_info(dev, id); info = neo_alloc_fb_info(dev, id);
if (!info) if (!info)
goto failed; return err;
err = neo_map_mmio(info, dev); err = neo_map_mmio(info, dev);
if (err) if (err)
goto failed; goto err_map_mmio;
video_len = neo_init_hw(info); video_len = neo_init_hw(info);
if (video_len < 0) { if (video_len < 0) {
err = video_len; err = video_len;
goto failed; goto err_init_hw;
} }
err = neo_map_video(info, dev, video_len); err = neo_map_video(info, dev, video_len);
if (err) if (err)
goto failed; goto err_init_hw;
if (neofb_check_var(&info->var, info))
goto err_map_video;
/* /*
* Calculate the hsync and vsync frequencies. Note that * Calculate the hsync and vsync frequencies. Note that
...@@ -2013,10 +2128,12 @@ static int __devinit neofb_probe(struct pci_dev *dev, ...@@ -2013,10 +2128,12 @@ static int __devinit neofb_probe(struct pci_dev *dev,
info->fix.smem_len >> 10, info->var.xres, info->fix.smem_len >> 10, info->var.xres,
info->var.yres, h_sync / 1000, h_sync % 1000, v_sync); info->var.yres, h_sync / 1000, h_sync % 1000, v_sync);
if (fb_alloc_cmap(&info->cmap, 256, 0) < 0)
goto err_map_video;
err = register_framebuffer(info); err = register_framebuffer(info);
if (err < 0) if (err < 0)
goto failed; goto err_reg_fb;
printk(KERN_INFO "fb%d: %s frame buffer device\n", printk(KERN_INFO "fb%d: %s frame buffer device\n",
info->node, info->fix.id); info->node, info->fix.id);
...@@ -2027,11 +2144,14 @@ static int __devinit neofb_probe(struct pci_dev *dev, ...@@ -2027,11 +2144,14 @@ static int __devinit neofb_probe(struct pci_dev *dev,
pci_set_drvdata(dev, info); pci_set_drvdata(dev, info);
return 0; return 0;
failed: err_reg_fb:
fb_dealloc_cmap(&info->cmap);
err_map_video:
neo_unmap_video(info); neo_unmap_video(info);
err_init_hw:
neo_unmap_mmio(info); neo_unmap_mmio(info);
err_map_mmio:
neo_free_fb_info(info); neo_free_fb_info(info);
return err; return err;
} }
...@@ -2103,24 +2223,6 @@ static struct pci_driver neofb_driver = { ...@@ -2103,24 +2223,6 @@ static struct pci_driver neofb_driver = {
.remove = __devexit_p(neofb_remove) .remove = __devexit_p(neofb_remove)
}; };
/* **************************** init-time only **************************** */
static void __init neo_init(void)
{
DBG("neo_init");
pci_register_driver(&neofb_driver);
}
/* **************************** exit-time only **************************** */
static void __exit neo_done(void)
{
DBG("neo_done");
pci_unregister_driver(&neofb_driver);
}
#ifndef MODULE
/* ************************* init in-kernel code ************************** */ /* ************************* init in-kernel code ************************** */
int __init neofb_setup(char *options) int __init neofb_setup(char *options)
...@@ -2136,8 +2238,6 @@ int __init neofb_setup(char *options) ...@@ -2136,8 +2238,6 @@ int __init neofb_setup(char *options)
if (!*this_opt) if (!*this_opt)
continue; continue;
if (!strncmp(this_opt, "disabled", 8))
disabled = 1;
if (!strncmp(this_opt, "internal", 8)) if (!strncmp(this_opt, "internal", 8))
internal = 1; internal = 1;
if (!strncmp(this_opt, "external", 8)) if (!strncmp(this_opt, "external", 8))
...@@ -2153,41 +2253,18 @@ int __init neofb_setup(char *options) ...@@ -2153,41 +2253,18 @@ int __init neofb_setup(char *options)
return 0; return 0;
} }
static int __initdata initialized = 0;
int __init neofb_init(void) int __init neofb_init(void)
{ {
DBG("neofb_init"); return pci_register_driver(&neofb_driver);
if (disabled)
return -ENXIO;
if (!initialized) {
initialized = 1;
neo_init();
}
/* never return failure, user can hotplug card later... */
return 0;
} }
#else #ifdef MODULE
/* *************************** init module code **************************** */
int __init init_module(void) static void __exit neofb_exit(void)
{ {
DBG("init_module"); pci_unregister_driver(&neofb_driver);
if (disabled)
return -ENXIO;
neo_init();
/* never return failure; user can hotplug card later... */
return 0;
} }
module_init(neofb_init);
module_exit(neofb_exit);
#endif /* MODULE */ #endif /* MODULE */
module_exit(neo_done);
...@@ -55,6 +55,20 @@ ...@@ -55,6 +55,20 @@
#define NEO_MODE1_X_1600 0x1c00 #define NEO_MODE1_X_1600 0x1c00
#define NEO_MODE1_BLT_ON_ADDR 0x2000 #define NEO_MODE1_BLT_ON_ADDR 0x2000
/* These are offseted in MMIO space by par->CursorOff */
#define NEOREG_CURSCNTL 0x00
#define NEOREG_CURSX 0x04
#define NEOREG_CURSY 0x08
#define NEOREG_CURSBGCOLOR 0x0C
#define NEOREG_CURSFGCOLOR 0x10
#define NEOREG_CURSMEMPOS 0x14
#define NEO_CURS_DISABLE 0x00000000
#define NEO_CURS_ENABLE 0x00000001
#define NEO_ICON64_ENABLE 0x00000008
#define NEO_ICON128_ENABLE 0x0000000C
#define NEO_ICON_BLANK 0x00000010
#ifdef __KERNEL__ #ifdef __KERNEL__
#ifdef NEOFB_DEBUG #ifdef NEOFB_DEBUG
...@@ -116,14 +130,14 @@ typedef volatile struct { ...@@ -116,14 +130,14 @@ typedef volatile struct {
__u32 dataPtr; __u32 dataPtr;
} Neo2200; } Neo2200;
#define NR_PALETTE 256
#define MMIO_SIZE 0x200000 #define MMIO_SIZE 0x200000
#define NEO_EXT_CR_MAX 0x85 #define NEO_EXT_CR_MAX 0x85
#define NEO_EXT_GR_MAX 0xC7 #define NEO_EXT_GR_MAX 0xC7
struct neofb_par { struct neofb_par {
struct vgastate state;
atomic_t ref_count;
unsigned char MiscOutReg; /* Misc */ unsigned char MiscOutReg; /* Misc */
unsigned char CRTC[25]; /* Crtc Controller */ unsigned char CRTC[25]; /* Crtc Controller */
...@@ -163,6 +177,8 @@ struct neofb_par { ...@@ -163,6 +177,8 @@ struct neofb_par {
int mtrr; int mtrr;
#endif #endif
u8 *mmio_vbase; u8 *mmio_vbase;
u8 cursorOff;
u8 *cursorPad; /* Must die !! */
Neo2200 *neo2200; Neo2200 *neo2200;
...@@ -185,81 +201,4 @@ typedef struct { ...@@ -185,81 +201,4 @@ typedef struct {
int mode; int mode;
} biosMode; } biosMode;
/* vga IO functions */
static inline u8 VGArCR (u8 index)
{
outb (index, 0x3d4);
return inb (0x3d5);
}
static inline void VGAwCR (u8 index, u8 val)
{
outb (index, 0x3d4);
outb (val, 0x3d5);
}
static inline u8 VGArGR (u8 index)
{
outb (index, 0x3ce);
return inb (0x3cf);
}
static inline void VGAwGR (u8 index, u8 val)
{
outb (index, 0x3ce);
outb (val, 0x3cf);
}
static inline u8 VGArSEQ (u8 index)
{
outb (index, 0x3c4);
return inb (0x3c5);
}
static inline void VGAwSEQ (u8 index, u8 val)
{
outb (index, 0x3c4);
outb (val, 0x3c5);
}
static int paletteEnabled = 0;
static inline void VGAenablePalette (void)
{
u8 tmp;
tmp = inb (0x3da);
outb (0x00, 0x3c0);
paletteEnabled = 1;
}
static inline void VGAdisablePalette (void)
{
u8 tmp;
tmp = inb (0x3da);
outb (0x20, 0x3c0);
paletteEnabled = 0;
}
static inline void VGAwATTR (u8 index, u8 value)
{
u8 tmp;
if (paletteEnabled)
index &= ~0x20;
else
index |= 0x20;
tmp = inb (0x3da);
outb (index, 0x3c0);
outb (value, 0x3c0);
}
static inline void VGAwMISC (u8 value)
{
outb (value, 0x3c2);
}
#endif #endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment