patch-2.2.11 linux/drivers/video/atyfb.c
Next file: linux/drivers/video/controlfb.c
Previous file: linux/drivers/video/Makefile
Back to the patch index
Back to the overall index
- Lines: 229
- Date:
Mon Aug 9 12:05:10 1999
- Orig file:
v2.2.10/linux/drivers/video/atyfb.c
- Orig date:
Thu Apr 22 19:30:08 1999
diff -u --recursive --new-file v2.2.10/linux/drivers/video/atyfb.c linux/drivers/video/atyfb.c
@@ -1,4 +1,4 @@
-/* $Id: atyfb.c,v 1.106 1999/04/16 11:20:49 geert Exp $
+/* $Id: atyfb.c,v 1.106.2.2 1999/08/07 10:49:25 davem Exp $
* linux/drivers/video/atyfb.c -- Frame buffer device for ATI Mach64
*
* Copyright (C) 1997-1998 Geert Uytterhoeven
@@ -200,6 +200,7 @@
struct atyfb_par default_par;
struct atyfb_par current_par;
u32 total_vram;
+ u32 ref_clk_per;
u32 pll_per;
u32 mclk_per;
u16 chip_type;
@@ -326,9 +327,7 @@
static void init_engine(const struct atyfb_par *par, struct fb_info_aty *info);
static void aty_st_514(int offset, u8 val, const struct fb_info_aty *info);
static void aty_st_pll(int offset, u8 val, const struct fb_info_aty *info);
-#if defined(__sparc__) || defined(DEBUG)
static u8 aty_ld_pll(int offset, const struct fb_info_aty *info);
-#endif
static void aty_set_crtc(const struct fb_info_aty *info,
const struct crtc *crtc);
static int aty_var_to_crtc(const struct fb_info_aty *info,
@@ -341,7 +340,8 @@
const struct pll_gx *pll);
static int aty_var_to_pll_18818(u32 vclk_per, struct pll_gx *pll);
static int aty_var_to_pll_514(u32 vclk_per, struct pll_gx *pll);
-static int aty_pll_gx_to_var(const struct pll_gx *pll, u32 *vclk_per);
+static int aty_pll_gx_to_var(const struct pll_gx *pll, u32 *vclk_per,
+ const struct fb_info_aty *info);
static void aty_set_pll_ct(const struct fb_info_aty *info,
const struct pll_ct *pll);
static int aty_dsp_gt(const struct fb_info_aty *info, u8 mclk_fb_div,
@@ -349,7 +349,8 @@
u8 bpp, struct pll_ct *pll);
static int aty_var_to_pll_ct(const struct fb_info_aty *info, u32 vclk_per,
u8 bpp, struct pll_ct *pll);
-static int aty_pll_ct_to_var(const struct pll_ct *pll, u32 *vclk_per);
+static int aty_pll_ct_to_var(const struct pll_ct *pll, u32 *vclk_per,
+ const struct fb_info_aty *info);
static void atyfb_set_par(const struct atyfb_par *par,
struct fb_info_aty *info);
static int atyfb_decode_var(const struct fb_var_screeninfo *var,
@@ -405,8 +406,6 @@
static int default_pll __initdata = 0;
static int default_mclk __initdata = 0;
-static const u32 ref_clk_per = 1000000000000ULL/14318180;
-
#if defined(CONFIG_PPC)
static int default_vmode __initdata = VMODE_NVRAM;
static int default_cmode __initdata = CMODE_NVRAM;
@@ -474,7 +473,7 @@
#if defined(__powerpc__)
temp = info->ati_regbase;
- asm("lwbrx %0,%1,%2" : "=r"(val) : "r" (regindex), "r" (temp));
+ asm("lwbrx %0,%1,%2" : "=r"(val) : "b" (regindex), "r" (temp));
#elif defined(__sparc_v9__)
temp = info->ati_regbase + regindex;
asm("lduwa [%1] %2, %0" : "=r" (val) : "r" (temp), "i" (ASI_PL));
@@ -492,7 +491,7 @@
#if defined(__powerpc__)
temp = info->ati_regbase;
- asm("stwbrx %0,%1,%2" : : "r" (val), "r" (regindex), "r" (temp) :
+ asm("stwbrx %0,%1,%2" : : "r" (val), "b" (regindex), "r" (temp) :
"memory");
#elif defined(__sparc_v9__)
temp = info->ati_regbase + regindex;
@@ -689,7 +688,6 @@
aty_st_8(CLOCK_CNTL + 1, (offset << 2) & ~PLL_WR_EN, info);
}
-#if defined(__sparc__) || defined(DEBUG)
static u8 aty_ld_pll(int offset, const struct fb_info_aty *info)
{
u8 res;
@@ -702,7 +700,6 @@
eieio();
return res;
}
-#endif
#if defined(CONFIG_PPC)
@@ -1455,7 +1452,8 @@
/* FIXME: ATI18818?? */
-static int aty_pll_gx_to_var(const struct pll_gx *pll, u32 *vclk_per)
+static int aty_pll_gx_to_var(const struct pll_gx *pll, u32 *vclk_per,
+ const struct fb_info_aty *info)
{
u8 df, vco_div_count, ref_div_count;
@@ -1463,7 +1461,7 @@
vco_div_count = pll->m & 0x3f;
ref_div_count = pll->n;
- *vclk_per = ((ref_clk_per*ref_div_count)<<(3-df))/(vco_div_count+65);
+ *vclk_per = ((info->ref_clk_per*ref_div_count)<<(3-df))/(vco_div_count+65);
return 0;
}
@@ -1526,7 +1524,7 @@
}
dsp_precision -= 5;
/* fifo_off<<6 */
- fifo_off = ((xclks_per_row*(fifo_size-1))>>5)+(1<<6);
+ fifo_off = ((xclks_per_row*(fifo_size-1))>>5)+(3<<6);
if (info->total_vram > 1*1024*1024) {
if (info->ram_type >= SDRAM) {
@@ -1553,7 +1551,7 @@
if (xclks_per_row >= (page_size<<11))
fifo_on = ((2*page_size+1)<<6)+(xclks_per_row>>5);
else
- fifo_on = (3*page_size)<<6;
+ fifo_on = (3*page_size+2)<<6;
dsp_xclks_per_row = xclks_per_row>>dsp_precision;
dsp_on = fifo_on>>dsp_precision;
@@ -1579,10 +1577,10 @@
pll->pll_vclk_cntl = 0x03; /* VCLK = PLL_VCLK/VCLKx_POST */
- pll_ref_div = info->pll_per*2*255/ref_clk_per;
+ pll_ref_div = info->pll_per*2*255/info->ref_clk_per;
/* FIXME: use the VTB/GTB /3 post divider if it's better suited */
- q = ref_clk_per*pll_ref_div*4/info->mclk_per; /* actually 8*q */
+ q = info->ref_clk_per*pll_ref_div*4/info->mclk_per; /* actually 8*q */
if (q < 16*8 || q > 255*8)
FAIL("mclk out of range");
else if (q < 32*8)
@@ -1596,7 +1594,7 @@
mclk_fb_div = q*mclk_post_div/8;
/* FIXME: use the VTB/GTB /{3,6,12} post dividers if they're better suited */
- q = ref_clk_per*pll_ref_div*4/vclk_per; /* actually 8*q */
+ q = info->ref_clk_per*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)
@@ -1677,7 +1675,8 @@
return 0;
}
-static int aty_pll_ct_to_var(const struct pll_ct *pll, u32 *vclk_per)
+static int aty_pll_ct_to_var(const struct pll_ct *pll, u32 *vclk_per,
+ const struct fb_info_aty *info)
{
u8 pll_ref_div = pll->pll_ref_div;
u8 vclk_fb_div = pll->vclk_fb_div;
@@ -1691,7 +1690,7 @@
(vclk_post_div & 3)];
if (vpostdiv == 0)
return -EINVAL;
- *vclk_per = pll_ref_div*vpostdiv*ref_clk_per/vclk_fb_div/2;
+ *vclk_per = pll_ref_div*vpostdiv*info->ref_clk_per/vclk_fb_div/2;
return 0;
}
@@ -1845,9 +1844,9 @@
if ((err = aty_crtc_to_var(&par->crtc, var)))
return err;
if ((Gx == GX_CHIP_ID) || (Gx == CX_CHIP_ID))
- err = aty_pll_gx_to_var(&par->pll.gx, &var->pixclock);
+ err = aty_pll_gx_to_var(&par->pll.gx, &var->pixclock, info);
else
- err = aty_pll_ct_to_var(&par->pll.ct, &var->pixclock);
+ err = aty_pll_ct_to_var(&par->pll.ct, &var->pixclock, info);
if (err)
return err;
@@ -2432,11 +2431,12 @@
int j, k;
struct fb_var_screeninfo var;
struct display *disp;
- const char *chipname = NULL, *ramname = NULL;
+ const char *chipname = NULL, *ramname = NULL, *xtal;
int pll, mclk, gtb_memsize;
#if defined(CONFIG_PPC)
int sense;
#endif
+ u8 pll_ref_div;
info->aty_cmap_regs = (struct aty_cmap_regs *)(info->ati_regbase+0xc0);
chip_id = aty_ld_le32(CONFIG_CHIP_ID, info);
@@ -2524,6 +2524,25 @@
}
}
+ info->ref_clk_per = 1000000000000ULL/14318180;
+ xtal = "14.31818";
+ if (!(Gx == GX_CHIP_ID || Gx == CX_CHIP_ID || Gx == CT_CHIP_ID ||
+ Gx == ET_CHIP_ID ||
+ ((Gx == VT_CHIP_ID || Gx == GT_CHIP_ID) && !(Rev & 0x07))) &&
+ (pll_ref_div = aty_ld_pll(PLL_REF_DIV, info))) {
+ int diff1, diff2;
+ diff1 = 510*14/pll_ref_div-pll;
+ diff2 = 510*29/pll_ref_div-pll;
+ if (diff1 < 0)
+ diff1 = -diff1;
+ if (diff2 < 0)
+ diff2 = -diff2;
+ if (diff2 < diff1) {
+ info->ref_clk_per = 1000000000000ULL/29498928;
+ xtal = "29.498928";
+ }
+ }
+
i = aty_ld_le32(MEM_CNTL, info);
gtb_memsize = !(Gx == GX_CHIP_ID || Gx == CX_CHIP_ID || Gx == CT_CHIP_ID ||
Gx == ET_CHIP_ID ||
@@ -2602,9 +2621,9 @@
if (default_mclk)
mclk = default_mclk;
- printk("%d%c %s, %d MHz PLL, %d Mhz MCLK\n",
+ printk("%d%c %s, %s MHz XTAL, %d MHz PLL, %d Mhz MCLK\n",
info->total_vram == 0x80000 ? 512 : (info->total_vram >> 20),
- info->total_vram == 0x80000 ? 'K' : 'M', ramname, pll, mclk);
+ info->total_vram == 0x80000 ? 'K' : 'M', ramname, xtal, pll, mclk);
if (mclk < 44)
info->mem_refresh_rate = 0; /* 000 = 10 Mhz - 43 Mhz */
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)