hi 
I am using linux-2.6.11 (uclibc) kernel with ati
framebuffer driver (RAGE XL).
 When i am using Xserver on my normaly it started and
works, but  it get crashed when moving  windows on it,
and we cannot predict when it crash.At the time of
crash always get the debug message

   debug atyfb: Mach64 non-shadow register values:

   debug atyfb:Mach64 PLL register values:

and print some register values  

on Xfree86 log message
 
Fatal server error caught signal 4 
(sometimes signal 11 or 10)

 ..Is it a  problem with ATI driver ?(I changed my
XFree86 version to check whether it is a problem of X
but again crashed thats why i suspect ATI driver).
my machine is a Xiaohu thinclient board ..and i could
see some 
referance in xlinit.c ..

regds 





Send instant messages to your online friends http://in.messenger.yahoo.com 

Attachment: XFree86.0.log
Description: 1065168681-XFree86.0.log

/*
 *  ATI Rage XL Initialization. Support for Xpert98 and Victoria
 *  PCI cards.
 *
 *  Copyright (C) 2002 MontaVista Software Inc.
 *  Author: MontaVista Software, Inc.
 *              [EMAIL PROTECTED] or [EMAIL PROTECTED]
 *
 *  This program is free software; you can redistribute  it and/or modify it
 *  under  the terms of  the GNU General  Public License as published by the
 *  Free Software Foundation;  either version 2 of the  License, or (at your
 *  option) any later version.
 *
 *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
 *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
 *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
 *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
 *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
 *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
 *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 *  You should have received a copy of the  GNU General Public License along
 *  with this program; if not, write  to the Free Software Foundation, Inc.,
 *  675 Mass Ave, Cambridge, MA 02139, USA.
 */
#include <linux/config.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/mm.h> 
#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <linux/delay.h>
#include <linux/fb.h>
#include <linux/init.h>
#include <linux/pci.h>
#include <asm/io.h>
#include <video/mach64.h>
#include "atyfb.h"

#define MPLL_GAIN       0xad
#define VPLL_GAIN       0xd5

enum {
        VICTORIA = 0,
        XPERT98,
        NUM_XL_CARDS
};

extern const struct aty_pll_ops aty_pll_ct;

#define DEFAULT_CARD XPERT98
static int xl_card = DEFAULT_CARD;

static const struct xl_card_cfg_t {
        int ref_crystal; // 10^4 Hz
        int mem_type;
        int mem_size;
        u32 mem_cntl;
        u32 ext_mem_cntl;
        u32 mem_addr_config;
        u32 bus_cntl;
        u32 dac_cntl;
        u32 hw_debug;
        u32 custom_macro_cntl;
        u8  dll2_cntl;
        u8  pll_yclk_cntl;
} card_cfg[NUM_XL_CARDS] = {
        // VICTORIA
        {       2700, SDRAM, 0x800000,
                0x10757A3B, 0x64000C81, 0x00110202, 0x7b33A040,
                0x82010102, 0x48803800, 0x005E0179,
                0x50, 0x25
        },
        // XPERT98
        {       1432,  WRAM, 0x800000,
                0x00165A2B, 0xE0000CF1, 0x00200213, 0x7333A001,
                0x8000000A, 0x48833800, 0x007F0779,
                0x10, 0x19
        }
};
          
typedef struct {
        u8 lcd_reg;
        u32 val;
} lcd_tbl_t;

static const lcd_tbl_t lcd_tbl[] = {
        { 0x01, 0x000520C0 },
        { 0x08, 0x02000408 },
        { 0x03, 0x00000F00 },
        { 0x00, 0x00000000 },
        { 0x02, 0x00000000 },
        { 0x04, 0x00000000 },
        { 0x05, 0x00000000 },
        { 0x06, 0x00000000 },
        { 0x33, 0x00000000 },
        { 0x34, 0x00000000 },
        { 0x35, 0x00000000 },
        { 0x36, 0x00000000 },
        { 0x37, 0x00000000 }
};

static void reset_gui(struct atyfb_par *par)
{    

        printk("debug xlinit: inside reset_gui\n");
        aty_st_8(GEN_TEST_CNTL+1, 0x01, par);
        aty_st_8(GEN_TEST_CNTL+1, 0x00, par);
        aty_st_8(GEN_TEST_CNTL+1, 0x02, par);
        mdelay(5);
        printk("debug xlinit: exit reset_gui\n");
}

static void reset_sdram(struct atyfb_par *par)
{
        u8 temp;
    
        printk("debug xlinit: inside reset_sdram\n");
        temp = aty_ld_8(EXT_MEM_CNTL, par);
        temp |= 0x02;
        aty_st_8(EXT_MEM_CNTL, temp, par); // MEM_SDRAM_RESET = 1b
        temp |= 0x08;
        aty_st_8(EXT_MEM_CNTL, temp, par); // MEM_CYC_TEST    = 10b
        temp |= 0x0c;
        aty_st_8(EXT_MEM_CNTL, temp, par); // MEM_CYC_TEST    = 11b
        mdelay(5);
        temp &= 0xf3;
        aty_st_8(EXT_MEM_CNTL, temp, par); // MEM_CYC_TEST    = 00b
        temp &= 0xfd;
        aty_st_8(EXT_MEM_CNTL, temp, par); // MEM_SDRAM_REST  = 0b
        mdelay(5);
        printk("debug xlinit: exit reset_sdram\n");
}

static void init_dll(struct atyfb_par *par)
{   
        printk("debug xlinit: inside init_dll\n");
        // enable DLL
        aty_st_pll_ct(PLL_GEN_CNTL,
                   aty_ld_pll_ct(PLL_GEN_CNTL, par) & 0x7f,
                   par);

        // reset DLL
        aty_st_pll_ct(DLL_CNTL, 0x82, par);
        aty_st_pll_ct(DLL_CNTL, 0xE2, par);
        mdelay(5);
        aty_st_pll_ct(DLL_CNTL, 0x82, par);
        mdelay(6);
        printk("debug xlinit: exit init_dll\n");
}

static void reset_clocks(struct atyfb_par *par, struct pll_ct *pll,
                         int hsync_enb)
{
        printk("debug xlinit: inside reset_clocks\n");
        reset_gui(par);
        aty_st_pll_ct(MCLK_FB_DIV, pll->mclk_fb_div, par);
        aty_st_pll_ct(SCLK_FB_DIV, pll->sclk_fb_div, par);

        mdelay(15);
        init_dll(par);
        aty_st_8(GEN_TEST_CNTL+1, 0x00, par);
        mdelay(5);
        aty_st_8(CRTC_GEN_CNTL+3, 0x04, par);
        mdelay(6);
        reset_sdram(par);
        aty_st_8(CRTC_GEN_CNTL+3,
                 hsync_enb ? 0x00 : 0x04, par);

        aty_st_pll_ct(SPLL_CNTL2, pll->spll_cntl2, par);
        aty_st_pll_ct(PLL_GEN_CNTL, pll->pll_gen_cntl, par);
        aty_st_pll_ct(PLL_VCLK_CNTL, pll->pll_vclk_cntl, par);
        printk("debug xlinit: exit reset_clocks\n");
}

#ifndef __i386__
/*
 * These 3 routines (init_valid_pll_ct, init_dsp_gt, init_calc_pll_ct)
 * are copied from the 2.4 initialization which properly initializes a
 * bios-less chip.
 *
 * The i386 version includes code which uses the bios init instead, so
 * these are unnecessary there.
 */

#define FAIL(x) do { printk(x "\n"); return -EINVAL; } while (0)

static int init_valid_pll_ct(const struct fb_info *info, u32 vclk_per,
                            struct pll_ct *pll)
{
#ifdef DEBUG
    int pllmclk, pllsclk;
#endif
    u32 q;


    struct atyfb_par *par = (struct atyfb_par *) info->par;

        printk("debug xlinit: inside init_valid_pll_ct\n");
    pll->pll_ref_div = par->pll_per * 2 * 255 / par->ref_clk_per;

    /* FIXME: use the VTB/GTB /3 post divider if it's better suited */

    /* actually 8*q */
    q = par->ref_clk_per*pll->pll_ref_div*4/par->mclk_per;

    if (q < 16*8 || q > 255*8)
        FAIL("mclk out of range");
    else if (q < 32*8)
        pll->mclk_post_div_real = 8;
    else if (q < 64*8)
        pll->mclk_post_div_real = 4;
    else if (q < 128*8)
        pll->mclk_post_div_real = 2;
    else
        pll->mclk_post_div_real = 1;
    pll->sclk_fb_div = q*pll->mclk_post_div_real/8;

#ifdef DEBUG
    pllsclk = (1000000 * 2 * pll->sclk_fb_div) /
            (par->ref_clk_per * pll->pll_ref_div);
    printk(__FUNCTION__ ": pllsclk=%d MHz, mclk=%d MHz\n",
           pllsclk, pllsclk / pll->mclk_post_div_real);
#endif

    pll->mclk_fb_mult = M64_HAS(MFB_FORCE_4) ? 4 : 2;

    /* actually 8*q */
    q = par->ref_clk_per * pll->pll_ref_div * 8 /
            (pll->mclk_fb_mult * par->xclk_per);

    if (q < 16*8 || q > 255*8)
        FAIL("mclk out of range");
    else if (q < 32*8)
        pll->xclk_post_div_real = 8;
    else if (q < 64*8)
        pll->xclk_post_div_real = 4;
    else if (q < 128*8)
        pll->xclk_post_div_real = 2;
    else
        pll->xclk_post_div_real = 1;
    pll->mclk_fb_div = q*pll->xclk_post_div_real/8;

#ifdef DEBUG
    pllmclk = (1000000 * pll->mclk_fb_mult * pll->mclk_fb_div) /
            (par->ref_clk_per * pll->pll_ref_div);
    printk(__FUNCTION__ ": pllmclk=%d MHz, xclk=%d MHz\n",
           pllmclk, pllmclk / pll->xclk_post_div_real);
#endif

    /* FIXME: use the VTB/GTB /{3,6,12} post dividers if they're better suited 
*/
    q = par->ref_clk_per*pll->pll_ref_div*4/vclk_per;  /* actually 8*q */
    if (q < 16*8 || q > 255*8)
        FAIL("vclk out of range");
    else if (q < 32*8)
        pll->vclk_post_div_real = 8;
    else if (q < 64*8)
        pll->vclk_post_div_real = 4;
    else if (q < 128*8)
        pll->vclk_post_div_real = 2;
    else
        pll->vclk_post_div_real = 1;
    pll->vclk_fb_div = q*pll->vclk_post_div_real/8;
        printk("debug xlinit: exit init_valid_pll_ct\n");
    return 0;
}

static int init_dsp_gt(const struct fb_info *info, u32 bpp,
                      struct pll_ct *pll)
{
    struct atyfb_par *par = (struct atyfb_par *) info->par;
    u32 dsp_xclks_per_row, dsp_loop_latency, dsp_precision, dsp_off, dsp_on;
    u32 xclks_per_row, fifo_off, fifo_on, y, fifo_size;
    u32 memcntl, n, t_pfc, t_rp, t_ras, t_rcd, t_crd, t_rcc, t_lat;

#ifdef DEBUG
    printk(__FUNCTION__ ": mclk_fb_mult=%d\n", pll->mclk_fb_mult);
#endif
        printk("debug xlinit: inside init_dsp_gt\n");

    /* (64*xclk/vclk/bpp)<<11 = xclocks_per_row<<11 */
    xclks_per_row = ((u32)pll->mclk_fb_mult * (u32)pll->mclk_fb_div *
                     (u32)pll->vclk_post_div_real * 64) << 11;
    xclks_per_row /=
            (2 * (u32)pll->vclk_fb_div * (u32)pll->xclk_post_div_real * bpp);

    if (xclks_per_row < (1<<11))
        FAIL("Dotclock too high");
    if (M64_HAS(FIFO_32)) {
        fifo_size = 32;
        dsp_loop_latency = 2;
    } else {
        fifo_size = 24;
        dsp_loop_latency = 0;
    }
    dsp_precision = 0;
    y = (xclks_per_row*fifo_size)>>11;
    while (y) {
        y >>= 1;
        dsp_precision++;
    }
    dsp_precision -= 5;

    /* fifo_off<<6 */
    fifo_off = ((xclks_per_row*(fifo_size-1))>>5); // + (3<<6);

    if (info->fix.smem_len > 1*1024*1024) {
        switch (par->ram_type) {
        case WRAM:
            /* >1 MB WRAM */
            dsp_loop_latency += 9;
            n = 4;
            break;
        case SDRAM:
        case SGRAM:
            /* >1 MB SDRAM */
            dsp_loop_latency += 8;
            n = 2;
            break;
        default:
            /* >1 MB DRAM */
            dsp_loop_latency += 6;
            n = 3;
            break;
        }
    } else {
        if (par->ram_type >= SDRAM) {
            /* <2 MB SDRAM */
            dsp_loop_latency += 9;
            n = 2;
        } else {
            /* <2 MB DRAM */
            dsp_loop_latency += 8;
            n = 3;
        }
    }

    memcntl = aty_ld_le32(MEM_CNTL, par);
    t_rcd = ((memcntl >> 10) & 0x03) + 1;
    t_crd = ((memcntl >> 12) & 0x01);
    t_rp  = ((memcntl >>  8) & 0x03) + 1;
    t_ras = ((memcntl >> 16) & 0x07) + 1;
    t_lat =  (memcntl >>  4) & 0x03;

    t_pfc = t_rp + t_rcd + t_crd;

    t_rcc = max(t_rp + t_ras, t_pfc + n);

    /* fifo_on<<6 */
    fifo_on = (2 * t_rcc + t_pfc + n - 1) << 6;

    dsp_xclks_per_row = xclks_per_row>>dsp_precision;
    dsp_on = fifo_on>>dsp_precision;
    dsp_off = fifo_off>>dsp_precision;

    pll->dsp_config = (dsp_xclks_per_row & 0x3fff) |
                      ((dsp_loop_latency & 0xf)<<16) |
                      ((dsp_precision & 7)<<20);
    pll->dsp_on_off = (dsp_off & 0x7ff) | ((dsp_on & 0x7ff)<<16);
        printk("debug xlinit: exit init_dsp_gt\n");
    return 0;
}

void init_calc_pll_ct(const struct fb_info *info, struct pll_ct *pll)
{
    struct atyfb_par *par = (struct atyfb_par *) info->par;
    u8 xpostdiv = 0;
    u8 mpostdiv = 0;  
    u8 vpostdiv = 0;  
    
        printk("debug xlinit: inside init_calc_pll_ct\n");
    if (M64_HAS(SDRAM_MAGIC_PLL) && (par->ram_type >= SDRAM))
            pll->pll_gen_cntl = 0x64; /* mclk = sclk */
    else
        pll->pll_gen_cntl = 0xe4; /* mclk = sclk */

    switch (pll->mclk_post_div_real) {
        case 1:
            mpostdiv = 0;
            break;
        case 2:
            mpostdiv = 1;
            break;
        case 4:
            mpostdiv = 2;
            break;
        case 8:
            mpostdiv = 3;
            break;
    }       
    
    pll->spll_cntl2 = mpostdiv << 4; /* sclk == pllsclk / mpostdiv */
    
    switch (pll->xclk_post_div_real) {
        case 1:
            xpostdiv = 0;
            break;
        case 2:
            xpostdiv = 1;
            break;
        case 3:
            xpostdiv = 4;
            break;
        case 4:
            xpostdiv = 2;
            break;
        case 8:
            xpostdiv = 3;
            break;
    }

    if (M64_HAS(MAGIC_POSTDIV))
        pll->pll_ext_cntl = 0;
    else
        pll->pll_ext_cntl = xpostdiv;   /* xclk == pllmclk / xpostdiv */

    if (pll->mclk_fb_mult == 4)
            pll->pll_ext_cntl |= 0x08;

    switch (pll->vclk_post_div_real) {
        case 2:
            vpostdiv = 1;
            break;
        case 3:
            pll->pll_ext_cntl |= 0x10;
        case 1:
            vpostdiv = 0;
            break;
        case 6:
            pll->pll_ext_cntl |= 0x10;
        case 4:
            vpostdiv = 2;
            break;
        case 12:
            pll->pll_ext_cntl |= 0x10;
        case 8:
            vpostdiv = 3;
            break;
    }

    pll->pll_vclk_cntl = 0x03;  /* VCLK = PLL_VCLK/VCLKx_POST */
    pll->vclk_post_div = vpostdiv;
        printk("debug xlinit: exit init_calc_pll_ct\n");
}
#endif // __i386__

int atyfb_xl_init(struct fb_info *info)
{
        const struct xl_card_cfg_t * card = &card_cfg[xl_card];
        struct atyfb_par *par = (struct atyfb_par *) info->par;
        union aty_pll pll;
        int err;
        u32 temp;


        printk("debug xlinit: inside atyfb_xl_init\n");
        // For the XiaoHu, at least, the STAT0 register is 0x95 at boot
        // ONLY.  On power-button reset, we do NOT want to do this init.
        if( (aty_ld_8(CONFIG_STAT0, par) & 0xff) != 0x95 ){
                printk("debug xlinit: exit  atyfb_xl_init xiaohu STAT0 register 
is not 0x95\n");
                return 0;

        aty_st_8(CONFIG_STAT0, 0x85, par);
        mdelay(10);

        /*
         * The following needs to be set before the call
         * to var_to_pll() below. They'll be re-set again
         * to the same values in aty_init().
         */
        par->ref_clk_per = 100000000UL/card->ref_crystal;
        par->ram_type = card->mem_type;
        info->fix.smem_len = card->mem_size;
        if (xl_card == VICTORIA) {
                // the MCLK, XCLK are 120MHz on victoria card
                par->mclk_per = 1000000/120;
                par->xclk_per = 1000000/120;
                par->features &= ~M64F_MFB_FORCE_4;
        }

        /*
         * Calculate mclk and xclk dividers, etc. The passed
         * pixclock and bpp values don't matter yet, the vclk
         * isn't programmed until later.
         */
#ifndef __i386__
        // These were stolen from the working 2.4 kernel xlinit.c
        // This is what 'var_to_pll' used to do.
        if( (err = init_valid_pll_ct( info, 39726, &(pll.ct) ) ) )
                return err;
        if( M64_HAS(GTB_DSP) && (err = init_dsp_gt( info, 8, &(pll.ct) ) ) )
                return err;
        init_calc_pll_ct( info, &(pll.ct) );
#else
        // The current 'var_to_pll' assumes you have already called
        // 'init_from_bios' which only occurrs for __i386__
        if ((err = aty_pll_ct.var_to_pll(info, 39726, 8, &pll)))
                return err;
#endif

        aty_st_pll_ct(LVDS_CNTL0, 0x00, par);
        aty_st_pll_ct(DLL2_CNTL, card->dll2_cntl, par);
        aty_st_pll_ct(V2PLL_CNTL, 0x10, par);
        aty_st_pll_ct(MPLL_CNTL, MPLL_GAIN, par);
        aty_st_pll_ct(VPLL_CNTL, VPLL_GAIN, par);
        aty_st_pll_ct(PLL_VCLK_CNTL, 0x00, par);
        aty_st_pll_ct(VFC_CNTL, 0x1B, par);
        aty_st_pll_ct(PLL_REF_DIV, pll.ct.pll_ref_div, par);
        aty_st_pll_ct(PLL_EXT_CNTL, pll.ct.pll_ext_cntl, par);
        aty_st_pll_ct(SPLL_CNTL2, 0x03, par);
        aty_st_pll_ct(PLL_GEN_CNTL, 0x44, par);

        reset_clocks(par, &pll.ct, 0);
        mdelay(10);

        aty_st_pll_ct(VCLK_POST_DIV, 0x03, par);
        aty_st_pll_ct(VCLK0_FB_DIV, 0xDA, par);
        aty_st_pll_ct(VCLK_POST_DIV, 0x0F, par);
        aty_st_pll_ct(VCLK1_FB_DIV, 0xF5, par);
        aty_st_pll_ct(VCLK_POST_DIV, 0x3F, par);
        aty_st_pll_ct(PLL_EXT_CNTL, 0x40 | pll.ct.pll_ext_cntl, par);
        aty_st_pll_ct(VCLK2_FB_DIV, 0x00, par);
        aty_st_pll_ct(VCLK_POST_DIV, 0xFF, par);
        aty_st_pll_ct(PLL_EXT_CNTL, 0xC0 | pll.ct.pll_ext_cntl, par);
        aty_st_pll_ct(VCLK3_FB_DIV, 0x00, par);

        aty_st_8(BUS_CNTL, 0x01, par);
        aty_st_le32(BUS_CNTL, card->bus_cntl | 0x08000000, par);

        aty_st_le32(CRTC_GEN_CNTL, 0x04000200, par);
        aty_st_le16(CONFIG_STAT0, 0x0020, par);
        aty_st_le32(MEM_CNTL, 0x10151A33, par);
        aty_st_le32(EXT_MEM_CNTL, 0xE0000C01, par);
        aty_st_le16(CRTC_GEN_CNTL+2, 0x0000, par);
        aty_st_le32(DAC_CNTL, card->dac_cntl, par);
        aty_st_le16(GEN_TEST_CNTL, 0x0100, par);
        aty_st_le32(CUSTOM_MACRO_CNTL, 0x003C0171, par);
        aty_st_le32(MEM_BUF_CNTL, 0x00382848, par);

        aty_st_le32(HW_DEBUG, card->hw_debug, par);
        aty_st_le16(MEM_ADDR_CONFIG, 0x0000, par);
        aty_st_le16(GP_IO+2, 0x0000, par);
        aty_st_le16(GEN_TEST_CNTL, 0x0000, par);
        aty_st_le16(EXT_DAC_REGS+2, 0x0000, par);
        aty_st_le32(CRTC_INT_CNTL, 0x00000000, par);
        aty_st_le32(TIMER_CONFIG, 0x00000000, par);
        aty_st_le32(0xEC, 0x00000000, par);
        aty_st_le32(0xFC, 0x00000000, par);

#if defined(CONFIG_PM) || defined(CONFIG_PMAC_BACKLIGHT) || defined 
(CONFIG_FB_ATY_GENERIC_LCD)
        {
        int i;
        for (i=0; i<sizeof(lcd_tbl)/sizeof(lcd_tbl_t); i++) {
                aty_st_lcd(lcd_tbl[i].lcd_reg, lcd_tbl[i].val, par);
        }
        }
#endif

        aty_st_le16(CONFIG_STAT0, 0x00A4, par);
        mdelay(10);

        aty_st_8(BUS_CNTL+1, 0xA0, par);
        mdelay(10);
        
        reset_clocks(par, &pll.ct, 1);
        mdelay(10);

        // something about power management
        aty_st_8(LCD_INDEX, 0x08, par);
        aty_st_8(LCD_DATA, 0x0A, par);
        aty_st_8(LCD_INDEX, 0x08, par);
        aty_st_8(LCD_DATA+3, 0x02, par);
        aty_st_8(LCD_INDEX, 0x08, par);
        aty_st_8(LCD_DATA, 0x0B, par);
        mdelay(2);
        
        // enable display requests, enable CRTC
        aty_st_8(CRTC_GEN_CNTL+3, 0x02, par);
        // disable display
        aty_st_8(CRTC_GEN_CNTL, 0x40, par);
        // disable display requests, disable CRTC
        aty_st_8(CRTC_GEN_CNTL+3, 0x04, par);
        mdelay(10);

        aty_st_pll_ct(PLL_YCLK_CNTL, 0x25, par);

        aty_st_le16(CUSTOM_MACRO_CNTL, 0x0179, par);
        aty_st_le16(CUSTOM_MACRO_CNTL+2, 0x005E, par);
        aty_st_le16(CUSTOM_MACRO_CNTL+2, card->custom_macro_cntl>>16, par);
        aty_st_8(CUSTOM_MACRO_CNTL+1,
                 (card->custom_macro_cntl>>8) & 0xff, par);

        aty_st_le32(MEM_ADDR_CONFIG, card->mem_addr_config, par);
        aty_st_le32(MEM_CNTL, card->mem_cntl, par);
        aty_st_le32(EXT_MEM_CNTL, card->ext_mem_cntl, par);

        aty_st_8(CONFIG_STAT0, 0xA0 | card->mem_type, par);

        aty_st_pll_ct(PLL_YCLK_CNTL, 0x01, par);
        mdelay(15);
        aty_st_pll_ct(PLL_YCLK_CNTL, card->pll_yclk_cntl, par);
        mdelay(1);
        
        reset_clocks(par, &pll.ct, 0);
        mdelay(50);
        reset_clocks(par, &pll.ct, 0);
        mdelay(50);

        // enable extended register block
        aty_st_8(BUS_CNTL+3, 0x7B, par);
        mdelay(1);
        // disable extended register block
        aty_st_8(BUS_CNTL+3, 0x73, par);

        aty_st_8(CONFIG_STAT0, 0x80 | card->mem_type, par);

        // disable display requests, disable CRTC
        aty_st_8(CRTC_GEN_CNTL+3, 0x04, par);
        // disable mapping registers in VGA aperture
        aty_st_8(CONFIG_CNTL, aty_ld_8(CONFIG_CNTL, par) & ~0x04, par);
        mdelay(50);
        // enable display requests, enable CRTC
        aty_st_8(CRTC_GEN_CNTL+3, 0x02, par);

        // make GPIO's 14,15,16 all inputs
        aty_st_8(LCD_INDEX, 0x07, par);
        aty_st_8(LCD_DATA+3, 0x00, par);

        // enable the display
        aty_st_8(CRTC_GEN_CNTL, 0x00, par);
        mdelay(17);
        // reset the memory controller
        aty_st_8(GEN_TEST_CNTL+1, 0x02, par);
        mdelay(15);
        aty_st_8(GEN_TEST_CNTL+1, 0x00, par);
        mdelay(30);

        // enable extended register block
        aty_st_8(BUS_CNTL+3,
                 (u8)(aty_ld_8(BUS_CNTL+3, par) | 0x08),
                 par);
        // set FIFO size to 512 (PIO)
        aty_st_le32(GUI_CNTL,
                    aty_ld_le32(GUI_CNTL, par) & ~0x3,
                    par);

        // enable CRT and disable lcd
        aty_st_8(LCD_INDEX, 0x01, par);
        temp = aty_ld_le32(LCD_DATA, par);
        temp = (temp | 0x01) & ~0x02;
        aty_st_le32(LCD_DATA, temp, par);
        printk("debug xlinit: exit success atyfb_xl_init\n");
        return 0;
}

Reply via email to