⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mach64_ct.c

📁 这个linux源代码是很全面的~基本完整了~使用c编译的~由于时间问题我没有亲自测试~但就算用来做参考资料也是非常好的
💻 C
字号:
/* *  ATI Mach64 CT/VT/GT/LT Support */#include <linux/fb.h>#include <asm/io.h>#include <video/fbcon.h>#include "mach64.h"#include "atyfb.h"/* FIXME: remove the FAIL definition */#define FAIL(x) do { printk(x "\n"); return -EINVAL; } while (0)static void aty_st_pll(int offset, u8 val, const struct fb_info_aty *info);static int aty_valid_pll_ct(const struct fb_info_aty *info, u32 vclk_per,			    struct pll_ct *pll);static int aty_dsp_gt(const struct fb_info_aty *info, u8 bpp,		      struct pll_ct *pll);static int aty_var_to_pll_ct(const struct fb_info_aty *info, u32 vclk_per,			     u8 bpp, union aty_pll *pll);static u32 aty_pll_ct_to_var(const struct fb_info_aty *info,			     const union aty_pll *pll);static void aty_st_pll(int offset, u8 val, const struct fb_info_aty *info){    /* write addr byte */    aty_st_8(CLOCK_CNTL + 1, (offset << 2) | PLL_WR_EN, info);    /* write the register value */    aty_st_8(CLOCK_CNTL + 2, val, info);    aty_st_8(CLOCK_CNTL + 1, (offset << 2) & ~PLL_WR_EN, info);}/* ------------------------------------------------------------------------- */    /*     *  PLL programming (Mach64 CT family)     */static int aty_dsp_gt(const struct fb_info_aty *info, u8 bpp,		      struct pll_ct *pll){    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, page_size;    /* xclocks_per_row<<11 */    xclks_per_row = (pll->mclk_fb_div*pll->vclk_post_div_real*64<<11)/		    (pll->vclk_fb_div*pll->mclk_post_div_real*bpp);    if (xclks_per_row < (1<<11))	FAIL("Dotclock to high");    if (M64_HAS(FIFO_24)) {	fifo_size = 24;	dsp_loop_latency = 0;    } else {	fifo_size = 32;	dsp_loop_latency = 2;    }    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->total_vram > 1*1024*1024) {	if (info->ram_type >= SDRAM) {	    /* >1 MB SDRAM */	    dsp_loop_latency += 8;	    page_size = 8;	} else {	    /* >1 MB DRAM */	    dsp_loop_latency += 6;	    page_size = 9;	}    } else {	if (info->ram_type >= SDRAM) {	    /* <2 MB SDRAM */	    dsp_loop_latency += 9;	    page_size = 10;	} else {	    /* <2 MB DRAM */	    dsp_loop_latency += 8;	    page_size = 10;	}    }    /* fifo_on<<6 */    if (xclks_per_row >= (page_size<<11))	fifo_on = ((2*page_size+1)<<6)+(xclks_per_row>>5);    else	fifo_on = (3*page_size+2)<<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_on & 0x7ff) | ((dsp_off & 0x7ff)<<16);    return 0;}static int aty_valid_pll_ct(const struct fb_info_aty *info, u32 vclk_per,			    struct pll_ct *pll){    u32 q, x;			/* x is a workaround for sparc64-linux-gcc */    x = x;			/* x is a workaround for sparc64-linux-gcc */    pll->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 = info->ref_clk_per*pll->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)	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->mclk_fb_div = q*pll->mclk_post_div_real/8;    /* FIXME: use the VTB/GTB /{3,6,12} post dividers if they're better suited */    q = info->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;    return 0;}void aty_calc_pll_ct(const struct fb_info_aty *info, struct pll_ct *pll){    u8 mpostdiv = 0;    u8 vpostdiv = 0;    if (M64_HAS(SDRAM_MAGIC_PLL) && (info->ram_type >= SDRAM))	pll->pll_gen_cntl = 0x04;    else	pll->pll_gen_cntl = 0x84;    switch (pll->mclk_post_div_real) {	case 1:	    mpostdiv = 0;	    break;	case 2:	    mpostdiv = 1;	    break;	case 3:	    mpostdiv = 4;	    break;	case 4:	    mpostdiv = 2;	    break;	case 8:	    mpostdiv = 3;	    break;    }    pll->pll_gen_cntl |= mpostdiv<<4;	/* mclk */#if defined(CONFIG_FB_ATY_CT_VAIO_LCD)    	pll->pll_ext_cntl = mpostdiv;	/* xclk == mclk */#else	if ( M64_HAS(MAGIC_POSTDIV) )		pll->pll_ext_cntl = 0;	else    		pll->pll_ext_cntl = mpostdiv;	/* xclk == mclk */#endif     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;}static int aty_var_to_pll_ct(const struct fb_info_aty *info, u32 vclk_per,			     u8 bpp, union aty_pll *pll){    int err;    if ((err = aty_valid_pll_ct(info, vclk_per, &pll->ct)))	return err;    if (M64_HAS(GTB_DSP) && (err = aty_dsp_gt(info, bpp, &pll->ct)))	return err;    aty_calc_pll_ct(info, &pll->ct);    return 0;}static u32 aty_pll_ct_to_var(const struct fb_info_aty *info,			     const union aty_pll *pll){    u32 ref_clk_per = info->ref_clk_per;    u8 pll_ref_div = pll->ct.pll_ref_div;    u8 vclk_fb_div = pll->ct.vclk_fb_div;    u8 vclk_post_div = pll->ct.vclk_post_div_real;    return ref_clk_per*pll_ref_div*vclk_post_div/vclk_fb_div/2;}void aty_set_pll_ct(const struct fb_info_aty *info, const union aty_pll *pll){    aty_st_pll(PLL_REF_DIV, pll->ct.pll_ref_div, info);    aty_st_pll(PLL_GEN_CNTL, pll->ct.pll_gen_cntl, info);    aty_st_pll(MCLK_FB_DIV, pll->ct.mclk_fb_div, info);    aty_st_pll(PLL_VCLK_CNTL, pll->ct.pll_vclk_cntl, info);    aty_st_pll(VCLK_POST_DIV, pll->ct.vclk_post_div, info);    aty_st_pll(VCLK0_FB_DIV, pll->ct.vclk_fb_div, info);    aty_st_pll(PLL_EXT_CNTL, pll->ct.pll_ext_cntl, info);    if (M64_HAS(GTB_DSP)) {	if (M64_HAS(XL_DLL))	    aty_st_pll(DLL_CNTL, 0x80, info);	else if (info->ram_type >= SDRAM)	    aty_st_pll(DLL_CNTL, 0xa6, info);	else	    aty_st_pll(DLL_CNTL, 0xa0, info);	aty_st_pll(VFC_CNTL, 0x1b, info);	aty_st_le32(DSP_CONFIG, pll->ct.dsp_config, info);	aty_st_le32(DSP_ON_OFF, pll->ct.dsp_on_off, info);    }}static int dummy(void){    return 0;}const struct aty_dac_ops aty_dac_ct = {    set_dac:	(void *)dummy,};const struct aty_pll_ops aty_pll_ct = {    var_to_pll:	aty_var_to_pll_ct,    pll_to_var:	aty_pll_ct_to_var,    set_pll:	aty_set_pll_ct,};

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -