HardwareInitCode

This is from http://lists.freedesktop.org/archives/xserver-commit/2004-June/001183.html

/****************************************************************************\
*                                                                            *
*                          RIVA Mode State Routines                          *
*                                                                            *
\****************************************************************************/

/*
 * Calculate the Video Clock parameters for the PLL.
 */
static int CalcVClock
(
    int           clockIn,
    int          *clockOut,
    int          *mOut,
    int          *nOut,
    int          *pOut,
    RIVA_HW_INST *chip
)
{
    unsigned lowM, highM, highP;
    unsigned DeltaNew, DeltaOld;
    unsigned VClk, Freq;
    unsigned M, N, P;
    
    DeltaOld = 0xFFFFFFFF;

    VClk     = (unsigned)clockIn;
    
    if (chip->CrystalFreqKHz == 13500)
    {
        lowM  = 7;
        highM = 12;
    }                      
    else
    {
        lowM  = 8;
        highM = 13;
    }

    highP = 3;
    for (P = 0; P <= highP; P ++)
    {
        Freq = VClk << P;
        if ((Freq >= 128000) && (Freq <= chip->MaxVClockFreqKHz))
        {
            for (M = lowM; M <= highM; M++)
            {
                N    = (VClk << P) * M / chip->CrystalFreqKHz;
                if(N <= 255) {
                    Freq = (chip->CrystalFreqKHz * N / M) >> P;
                    if (Freq > VClk)
                        DeltaNew = Freq - VClk;
                    else
                        DeltaNew = VClk - Freq;
                    if (DeltaNew < DeltaOld)
                    {
                        *mOut     = M;
                        *nOut     = N;
                        *pOut     = P;
                        *clockOut = Freq;
                        DeltaOld  = DeltaNew;
                    }
                }
            }
        }
    }
    return (DeltaOld != 0xFFFFFFFF);
}
/*
 * Calculate extended mode parameters (SVGA) and save in a 
 * mode state structure.
 */
static void CalcStateExt
(
    RIVA_HW_INST  *chip,
    RIVA_HW_STATE *state,
    int            bpp,
    int            width,
    int            hDisplaySize,
    int            height,
    int            dotClock,
    int            flags 
)
{
    int pixelDepth, VClk, m, n, p;
    /*
     * Save mode parameters.
     */
    state->bpp    = bpp;    /* this is not bitsPerPixel, it's 8,15,16,32 */
    state->width  = width;
    state->height = height;
    /*
     * Extended RIVA registers.
     */
    pixelDepth = (bpp + 1)/8;
    CalcVClock(dotClock, &VClk, &m, &n, &p, chip);

    nv3UpdateArbitrationSettings(VClk, 
                                 pixelDepth * 8, 
                                 &(state->arbitration0),
                                 &(state->arbitration1),
                                 chip);
    state->cursor0  = 0x00;
    state->cursor1  = 0x78;
    if (flags & V_DBLSCAN)
       state->cursor1 |= 2;
    state->cursor2  = 0x00000000;
    state->pllsel   = 0x10010100;
    state->config   = ((width + 31)/32)
                      | (((pixelDepth > 2) ? 3 : pixelDepth) << 8)
                      | 0x1000;
    state->general  = 0x00100100;
    state->repaint1 = hDisplaySize < 1280 ? 0x06 : 0x02;


    state->vpll     = (p << 16) | (n << 8) | m;
    state->repaint0 = (((width/8)*pixelDepth) & 0x700) >> 3;
    state->pixel    = pixelDepth > 2   ? 3    : pixelDepth;
    state->offset   = 0;
    state->pitch    = pixelDepth * width;
}
/*
 * Load fixed function state and pre-calculated/stored state.
 */
#define LOAD_FIXED_STATE(tbl,dev)                                       \
    for (i = 0; i < sizeof(tbl##Table##dev)/8; i++)                 \
        chip->dev[tbl##Table##dev[i][0]] = tbl##Table##dev[i][1]
#define LOAD_FIXED_STATE_8BPP(tbl,dev)                                  \
    for (i = 0; i < sizeof(tbl##Table##dev##_8BPP)/8; i++)            \
        chip->dev[tbl##Table##dev##_8BPP[i][0]] = tbl##Table##dev##_8BPP[i][1]
#define LOAD_FIXED_STATE_15BPP(tbl,dev)                                 \
    for (i = 0; i < sizeof(tbl##Table##dev##_15BPP)/8; i++)           \
        chip->dev[tbl##Table##dev##_15BPP[i][0]] = tbl##Table##dev##_15BPP[i][1]
#define LOAD_FIXED_STATE_16BPP(tbl,dev)                                 \
    for (i = 0; i < sizeof(tbl##Table##dev##_16BPP)/8; i++)           \
        chip->dev[tbl##Table##dev##_16BPP[i][0]] = tbl##Table##dev##_16BPP[i][1]
#define LOAD_FIXED_STATE_32BPP(tbl,dev)                                 \
    for (i = 0; i < sizeof(tbl##Table##dev##_32BPP)/8; i++)           \
        chip->dev[tbl##Table##dev##_32BPP[i][0]] = tbl##Table##dev##_32BPP[i][1]
static void UpdateFifoState
(
    RIVA_HW_INST  *chip
)
{
}
static void LoadStateExt
(
    RIVA_HW_INST  *chip,
    RIVA_HW_STATE *state
)
{
    int i;

    /*
     * Load HW fixed function state.
     */
    LOAD_FIXED_STATE(Riva,PMC);
    LOAD_FIXED_STATE(Riva,PTIMER);
     /*
      * Make sure frame buffer config gets set before loading PRAMIN.
      */
    chip->PFB[0x00000200/4] = state->config;
    LOAD_FIXED_STATE(nv3,PFIFO);
    LOAD_FIXED_STATE(nv3,PRAMIN);
    LOAD_FIXED_STATE(nv3,PGRAPH);
    switch (state->bpp)
    {
     case 15:
     case 16:
         LOAD_FIXED_STATE_15BPP(nv3,PRAMIN);
         LOAD_FIXED_STATE_15BPP(nv3,PGRAPH);
         break;
     case 24:
     case 32:
         LOAD_FIXED_STATE_32BPP(nv3,PRAMIN);
         LOAD_FIXED_STATE_32BPP(nv3,PGRAPH);
         break;
     case 8:
     default:
         LOAD_FIXED_STATE_8BPP(nv3,PRAMIN);
        LOAD_FIXED_STATE_8BPP(nv3,PGRAPH);
        break;
    }
    for (i = 0x00000; i < 0x00800; i++)
        chip->PRAMIN[0x00000502 + i] = (i << 12) | 0x03;
    chip->PGRAPH[0x00000630/4] = state->offset;
    chip->PGRAPH[0x00000634/4] = state->offset;
    chip->PGRAPH[0x00000638/4] = state->offset;
    chip->PGRAPH[0x0000063C/4] = state->offset;
    chip->PGRAPH[0x00000650/4] = state->pitch;
    chip->PGRAPH[0x00000654/4] = state->pitch;
    chip->PGRAPH[0x00000658/4] = state->pitch;
    chip->PGRAPH[0x0000065C/4] = state->pitch;

    LOAD_FIXED_STATE(Riva,FIFO);
    UpdateFifoState(chip);

    /*
     * Load HW mode state.
     */
    VGA_WR08(chip->PCIO, 0x03D4, 0x19);
    VGA_WR08(chip->PCIO, 0x03D5, state->repaint0);
    VGA_WR08(chip->PCIO, 0x03D4, 0x1A);
    VGA_WR08(chip->PCIO, 0x03D5, state->repaint1);
    VGA_WR08(chip->PCIO, 0x03D4, 0x25);
    VGA_WR08(chip->PCIO, 0x03D5, state->screen);
    VGA_WR08(chip->PCIO, 0x03D4, 0x28);
    VGA_WR08(chip->PCIO, 0x03D5, state->pixel);
    VGA_WR08(chip->PCIO, 0x03D4, 0x2D);
    VGA_WR08(chip->PCIO, 0x03D5, state->horiz);
    VGA_WR08(chip->PCIO, 0x03D4, 0x1B);
    VGA_WR08(chip->PCIO, 0x03D5, state->arbitration0);
    VGA_WR08(chip->PCIO, 0x03D4, 0x20);
    VGA_WR08(chip->PCIO, 0x03D5, state->arbitration1);
    VGA_WR08(chip->PCIO, 0x03D4, 0x30);
    VGA_WR08(chip->PCIO, 0x03D5, state->cursor0);
    VGA_WR08(chip->PCIO, 0x03D4, 0x31);
    VGA_WR08(chip->PCIO, 0x03D5, state->cursor1);
    VGA_WR08(chip->PCIO, 0x03D4, 0x2F);
    VGA_WR08(chip->PCIO, 0x03D5, state->cursor2);
    VGA_WR08(chip->PCIO, 0x03D4, 0x39);
    VGA_WR08(chip->PCIO, 0x03D5, state->interlace);

    chip->PRAMDAC[0x00000508/4] = state->vpll;
    chip->PRAMDAC[0x0000050C/4] = state->pllsel;
    chip->PRAMDAC[0x00000600/4]  = state->general;

    /*
     * Turn off VBlank enable and reset.
     */
    chip->PCRTC[0x00000140/4] = 0;
    chip->PCRTC[0x00000100/4] = chip->VBlankBit;
    /*
     * Set interrupt enable.
     */    
    chip->PMC[0x00000140/4]  = chip->EnableIRQ & 0x01;
    /*
     * Set current state pointer.
     */
    chip->CurrentState = state;
    /*
     * Reset FIFO free and empty counts.
     */
    chip->FifoFreeCount  = 0;
    /* Free count from first subchannel */
    chip->FifoEmptyCount = chip->Rop->FifoFree; 
}