/*
* ATI Mach32. Some hope.
* No support for accelerator so can only do up to 1024x768.
*
* All ATI Extended Registers are addressed using the modified index
* index = (0x02<<6)|(index & 0x3F);
* so registers 0x00->0x3F map to 0x80->0xBF, but we will only ever
* look at a few in the range 0xA0->0xBF. In this way we can stash
* them in the vga->crt[] array.
*/
enum {
Advfunc = 0x4AE8, /* Advanced Function Control Register */
Clocksel = 0x4AEE, /* Clock Select Register */
Misc = 0x36EE, /* Miscellaneous Register */
Membndry = 0x42EE, /* Memory Boundary Register */
Memcfg = 0x5EEE, /* Memory Control Register */
};
/*
* There are a number of possible clock generator chips for these
* boards, and I don't know how to find out which is installed, other
* than by looking at the board. So, pick a subset that will work for
* all.
*/
typedef struct {
ulong frequency;
uchar b8; /* <6> - divide by 2 */
uchar b9; /* <1> - bit <3> of frequency index */
uchar be; /* <4> - bit <2> of frequency index */
uchar misc; /* <3:2> - bits <1:0> of frequency index */
} Clock;
/*
* We could try to read in a part of the BIOS and try to determine
* the extended register address, but since we can't determine the offset value,
* we'll just have to assume the defaults all round.
*/
atix = 0x1CE;
/*
* Unlock the ATI Extended Registers.
* We leave them unlocked from now on.
* Why does this chip have so many
* lock bits?
*/
if((b = atixi(0xB8)) & 0x3F)
atixo(0xB8, b & 0xC0);
b = atixi(0xAB);
atixo(0xAB, b & ~0x18);
atixo(0xB4, 0x00);
b = atixi(0xB9);
atixo(0xB9, b & ~0x80);
b = atixi(0xBE);
atixo(0xBE, b|0x09);
/*
* Make sure we are in VGA mode,
* and that we have access to all the video memory through
* the 64Kb VGA aperture by disabling and linear aperture
* and memory boundary.
*/
outportw(Clocksel, 0x0000);
x = inportw(Memcfg) & ~0x0003;
outportw(Memcfg, x);
outportw(Membndry, 0x0000);