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

📄 w100fb.c

📁 Linux环境下视频显示卡设备的驱动程序源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
	w100_pwr_state.sclk_cntl.f.busy_extend_cp = 0x0;	w100_pwr_state.sclk_cntl.f.busy_extend_e2 = 0x0;	w100_pwr_state.sclk_cntl.f.busy_extend_e3 = 0x0;	w100_pwr_state.sclk_cntl.f.busy_extend_idct = 0x0;	writel((u32) (w100_pwr_state.sclk_cntl.val), remapped_regs + mmSCLK_CNTL);	w100_pwr_state.pclk_cntl.f.pclk_src_sel = CLK_SRC_XTAL;	w100_pwr_state.pclk_cntl.f.pclk_post_div = 0x1;    /* P = 2 */	w100_pwr_state.pclk_cntl.f.pclk_force_disp = 0x0;  /* Dynamic */	writel((u32) (w100_pwr_state.pclk_cntl.val), remapped_regs + mmPCLK_CNTL);	w100_pwr_state.pll_ref_fb_div.f.pll_ref_div = 0x0;     /* M = 1 */	w100_pwr_state.pll_ref_fb_div.f.pll_fb_div_int = 0x0;  /* N = 1.0 */	w100_pwr_state.pll_ref_fb_div.f.pll_fb_div_frac = 0x0;	w100_pwr_state.pll_ref_fb_div.f.pll_reset_time = 0x5;	w100_pwr_state.pll_ref_fb_div.f.pll_lock_time = 0xff;	writel((u32) (w100_pwr_state.pll_ref_fb_div.val), remapped_regs + mmPLL_REF_FB_DIV);	w100_pwr_state.pll_cntl.f.pll_pwdn = 0x1;	w100_pwr_state.pll_cntl.f.pll_reset = 0x1;	w100_pwr_state.pll_cntl.f.pll_pm_en = 0x0;	w100_pwr_state.pll_cntl.f.pll_mode = 0x0;  /* uses VCO clock */	w100_pwr_state.pll_cntl.f.pll_refclk_sel = 0x0;	w100_pwr_state.pll_cntl.f.pll_fbclk_sel = 0x0;	w100_pwr_state.pll_cntl.f.pll_tcpoff = 0x0;	w100_pwr_state.pll_cntl.f.pll_pcp = 0x4;	w100_pwr_state.pll_cntl.f.pll_pvg = 0x0;	w100_pwr_state.pll_cntl.f.pll_vcofr = 0x0;	w100_pwr_state.pll_cntl.f.pll_ioffset = 0x0;	w100_pwr_state.pll_cntl.f.pll_pecc_mode = 0x0;	w100_pwr_state.pll_cntl.f.pll_pecc_scon = 0x0;	w100_pwr_state.pll_cntl.f.pll_dactal = 0x0;  /* Hi-Z */	w100_pwr_state.pll_cntl.f.pll_cp_clip = 0x3;	w100_pwr_state.pll_cntl.f.pll_conf = 0x2;	w100_pwr_state.pll_cntl.f.pll_mbctrl = 0x2;	w100_pwr_state.pll_cntl.f.pll_ring_off = 0x0;	writel((u32) (w100_pwr_state.pll_cntl.val), remapped_regs + mmPLL_CNTL);	w100_pwr_state.pwrmgt_cntl.f.pwm_enable = 0x0;	w100_pwr_state.pwrmgt_cntl.f.pwm_mode_req = 0x1;  /* normal mode (0, 1, 3) */	w100_pwr_state.pwrmgt_cntl.f.pwm_wakeup_cond = 0x0;	w100_pwr_state.pwrmgt_cntl.f.pwm_fast_noml_hw_en = 0x0;	w100_pwr_state.pwrmgt_cntl.f.pwm_noml_fast_hw_en = 0x0;	w100_pwr_state.pwrmgt_cntl.f.pwm_fast_noml_cond = 0x1;  /* PM4,ENG */	w100_pwr_state.pwrmgt_cntl.f.pwm_noml_fast_cond = 0x1;  /* PM4,ENG */	w100_pwr_state.pwrmgt_cntl.f.pwm_idle_timer = 0xFF;	w100_pwr_state.pwrmgt_cntl.f.pwm_busy_timer = 0xFF;	writel((u32) (w100_pwr_state.pwrmgt_cntl.val), remapped_regs + mmPWRMGT_CNTL);	w100_pwr_state.auto_mode = 0;  /* manual mode */}/* * Setup the w100 clocks for the specified mode */static void w100_init_clocks(struct w100fb_par *par){	struct w100_mode *mode = par->mode;	if (mode->pixclk_src == CLK_SRC_PLL || mode->sysclk_src == CLK_SRC_PLL)		w100_set_pll_freq(par, (par->fastpll_mode && mode->fast_pll_freq) ? mode->fast_pll_freq : mode->pll_freq);	w100_pwr_state.sclk_cntl.f.sclk_src_sel = mode->sysclk_src;	w100_pwr_state.sclk_cntl.f.sclk_post_div_fast = mode->sysclk_divider;	w100_pwr_state.sclk_cntl.f.sclk_post_div_slow = mode->sysclk_divider;	writel((u32) (w100_pwr_state.sclk_cntl.val), remapped_regs + mmSCLK_CNTL);}static void w100_init_lcd(struct w100fb_par *par){	u32 temp32;	struct w100_mode *mode = par->mode;	struct w100_gen_regs *regs = par->mach->regs;	union active_h_disp_u active_h_disp;	union active_v_disp_u active_v_disp;	union graphic_h_disp_u graphic_h_disp;	union graphic_v_disp_u graphic_v_disp;	union crtc_total_u crtc_total;	/* w3200 doesnt like undefined bits being set so zero register values first */	active_h_disp.val = 0;	active_h_disp.f.active_h_start=mode->left_margin;	active_h_disp.f.active_h_end=mode->left_margin + mode->xres;	writel(active_h_disp.val, remapped_regs + mmACTIVE_H_DISP);	active_v_disp.val = 0;	active_v_disp.f.active_v_start=mode->upper_margin;	active_v_disp.f.active_v_end=mode->upper_margin + mode->yres;	writel(active_v_disp.val, remapped_regs + mmACTIVE_V_DISP);	graphic_h_disp.val = 0;	graphic_h_disp.f.graphic_h_start=mode->left_margin;	graphic_h_disp.f.graphic_h_end=mode->left_margin + mode->xres;	writel(graphic_h_disp.val, remapped_regs + mmGRAPHIC_H_DISP);	graphic_v_disp.val = 0;	graphic_v_disp.f.graphic_v_start=mode->upper_margin;	graphic_v_disp.f.graphic_v_end=mode->upper_margin + mode->yres;	writel(graphic_v_disp.val, remapped_regs + mmGRAPHIC_V_DISP);	crtc_total.val = 0;	crtc_total.f.crtc_h_total=mode->left_margin  + mode->xres + mode->right_margin;	crtc_total.f.crtc_v_total=mode->upper_margin + mode->yres + mode->lower_margin;	writel(crtc_total.val, remapped_regs + mmCRTC_TOTAL);	writel(mode->crtc_ss, remapped_regs + mmCRTC_SS);	writel(mode->crtc_ls, remapped_regs + mmCRTC_LS);	writel(mode->crtc_gs, remapped_regs + mmCRTC_GS);	writel(mode->crtc_vpos_gs, remapped_regs + mmCRTC_VPOS_GS);	writel(mode->crtc_rev, remapped_regs + mmCRTC_REV);	writel(mode->crtc_dclk, remapped_regs + mmCRTC_DCLK);	writel(mode->crtc_gclk, remapped_regs + mmCRTC_GCLK);	writel(mode->crtc_goe, remapped_regs + mmCRTC_GOE);	writel(mode->crtc_ps1_active, remapped_regs + mmCRTC_PS1_ACTIVE);	writel(regs->lcd_format, remapped_regs + mmLCD_FORMAT);	writel(regs->lcdd_cntl1, remapped_regs + mmLCDD_CNTL1);	writel(regs->lcdd_cntl2, remapped_regs + mmLCDD_CNTL2);	writel(regs->genlcd_cntl1, remapped_regs + mmGENLCD_CNTL1);	writel(regs->genlcd_cntl2, remapped_regs + mmGENLCD_CNTL2);	writel(regs->genlcd_cntl3, remapped_regs + mmGENLCD_CNTL3);	writel(0x00000000, remapped_regs + mmCRTC_FRAME);	writel(0x00000000, remapped_regs + mmCRTC_FRAME_VPOS);	writel(0x00000000, remapped_regs + mmCRTC_DEFAULT_COUNT);	writel(0x0000FF00, remapped_regs + mmLCD_BACKGROUND_COLOR);	/* Hack for overlay in ext memory */	temp32 = readl(remapped_regs + mmDISP_DEBUG2);	temp32 |= 0xc0000000;	writel(temp32, remapped_regs + mmDISP_DEBUG2);}static void w100_setup_memory(struct w100fb_par *par){	union mc_ext_mem_location_u extmem_location;	union mc_fb_location_u intmem_location;	struct w100_mem_info *mem = par->mach->mem;	struct w100_bm_mem_info *bm_mem = par->mach->bm_mem;	if (!par->extmem_active) {		w100_suspend(W100_SUSPEND_EXTMEM);		/* Map Internal Memory at FB Base */		intmem_location.f.mc_fb_start = W100_FB_BASE >> 8;		intmem_location.f.mc_fb_top = (W100_FB_BASE+MEM_INT_SIZE) >> 8;		writel((u32) (intmem_location.val), remapped_regs + mmMC_FB_LOCATION);		/* Unmap External Memory - value is *probably* irrelevant but may have meaning		   to acceleration libraries */		extmem_location.f.mc_ext_mem_start = MEM_EXT_BASE_VALUE >> 8;		extmem_location.f.mc_ext_mem_top = (MEM_EXT_BASE_VALUE-1) >> 8;		writel((u32) (extmem_location.val), remapped_regs + mmMC_EXT_MEM_LOCATION);	} else {		/* Map Internal Memory to its default location */		intmem_location.f.mc_fb_start = MEM_INT_BASE_VALUE >> 8;		intmem_location.f.mc_fb_top = (MEM_INT_BASE_VALUE+MEM_INT_SIZE) >> 8;		writel((u32) (intmem_location.val), remapped_regs + mmMC_FB_LOCATION);		/* Map External Memory at FB Base */		extmem_location.f.mc_ext_mem_start = W100_FB_BASE >> 8;		extmem_location.f.mc_ext_mem_top = (W100_FB_BASE+par->mach->mem->size) >> 8;		writel((u32) (extmem_location.val), remapped_regs + mmMC_EXT_MEM_LOCATION);		writel(0x00007800, remapped_regs + mmMC_BIST_CTRL);		writel(mem->ext_cntl, remapped_regs + mmMEM_EXT_CNTL);		writel(0x00200021, remapped_regs + mmMEM_SDRAM_MODE_REG);		udelay(100);		writel(0x80200021, remapped_regs + mmMEM_SDRAM_MODE_REG);		udelay(100);		writel(mem->sdram_mode_reg, remapped_regs + mmMEM_SDRAM_MODE_REG);		udelay(100);		writel(mem->ext_timing_cntl, remapped_regs + mmMEM_EXT_TIMING_CNTL);		writel(mem->io_cntl, remapped_regs + mmMEM_IO_CNTL);		if (bm_mem) {			writel(bm_mem->ext_mem_bw, remapped_regs + mmBM_EXT_MEM_BANDWIDTH);			writel(bm_mem->offset, remapped_regs + mmBM_OFFSET);			writel(bm_mem->ext_timing_ctl, remapped_regs + mmBM_MEM_EXT_TIMING_CNTL);			writel(bm_mem->ext_cntl, remapped_regs + mmBM_MEM_EXT_CNTL);			writel(bm_mem->mode_reg, remapped_regs + mmBM_MEM_MODE_REG);			writel(bm_mem->io_cntl, remapped_regs + mmBM_MEM_IO_CNTL);			writel(bm_mem->config, remapped_regs + mmBM_CONFIG);		}	}}static void w100_set_dispregs(struct w100fb_par *par){	unsigned long rot=0, divider, offset=0;	union graphic_ctrl_u graphic_ctrl;	/* See if the mode has been rotated */	if (par->xres == par->mode->xres) {		if (par->flip) {			rot=3; /* 180 degree */			offset=(par->xres * par->yres) - 1;		} /* else 0 degree */		divider = par->mode->pixclk_divider;	} else {		if (par->flip) {			rot=2; /* 270 degree */			offset=par->xres - 1;		} else {			rot=1; /* 90 degree */			offset=par->xres * (par->yres - 1);		}		divider = par->mode->pixclk_divider_rotated;	}	graphic_ctrl.val = 0; /* w32xx doesn't like undefined bits */	switch (par->chip_id) {		case CHIP_ID_W100:			graphic_ctrl.f_w100.color_depth=6;			graphic_ctrl.f_w100.en_crtc=1;			graphic_ctrl.f_w100.en_graphic_req=1;			graphic_ctrl.f_w100.en_graphic_crtc=1;			graphic_ctrl.f_w100.lcd_pclk_on=1;			graphic_ctrl.f_w100.lcd_sclk_on=1;			graphic_ctrl.f_w100.low_power_on=0;			graphic_ctrl.f_w100.req_freq=0;			graphic_ctrl.f_w100.portrait_mode=rot;			/* Zaurus needs this */			switch(par->xres) {				case 240:				case 320:				default:					graphic_ctrl.f_w100.total_req_graphic=0xa0;					break;				case 480:				case 640:					switch(rot) {						case 0:  /* 0 */						case 3:  /* 180 */							graphic_ctrl.f_w100.low_power_on=1;							graphic_ctrl.f_w100.req_freq=5;						break;						case 1:  /* 90 */						case 2:  /* 270 */							graphic_ctrl.f_w100.req_freq=4;							break;						default:							break;					}					graphic_ctrl.f_w100.total_req_graphic=0xf0;					break;			}			break;		case CHIP_ID_W3200:		case CHIP_ID_W3220:			graphic_ctrl.f_w32xx.color_depth=6;			graphic_ctrl.f_w32xx.en_crtc=1;			graphic_ctrl.f_w32xx.en_graphic_req=1;			graphic_ctrl.f_w32xx.en_graphic_crtc=1;			graphic_ctrl.f_w32xx.lcd_pclk_on=1;			graphic_ctrl.f_w32xx.lcd_sclk_on=1;			graphic_ctrl.f_w32xx.low_power_on=0;			graphic_ctrl.f_w32xx.req_freq=0;			graphic_ctrl.f_w32xx.total_req_graphic=par->mode->xres >> 1; /* panel xres, not mode */			graphic_ctrl.f_w32xx.portrait_mode=rot;			break;	}	/* Set the pixel clock source and divider */	w100_pwr_state.pclk_cntl.f.pclk_src_sel = par->mode->pixclk_src;	w100_pwr_state.pclk_cntl.f.pclk_post_div = divider;	writel((u32) (w100_pwr_state.pclk_cntl.val), remapped_regs + mmPCLK_CNTL);	writel(graphic_ctrl.val, remapped_regs + mmGRAPHIC_CTRL);	writel(W100_FB_BASE + ((offset * BITS_PER_PIXEL/8)&~0x03UL), remapped_regs + mmGRAPHIC_OFFSET);	writel((par->xres*BITS_PER_PIXEL/8), remapped_regs + mmGRAPHIC_PITCH);}/* * Work out how long the sync pulse lasts * Value is 1/(time in seconds) */static void calc_hsync(struct w100fb_par *par){	unsigned long hsync;	struct w100_mode *mode = par->mode;	union crtc_ss_u crtc_ss;	if (mode->pixclk_src == CLK_SRC_XTAL)		hsync=par->mach->xtal_freq;	else		hsync=((par->fastpll_mode && mode->fast_pll_freq) ? mode->fast_pll_freq : mode->pll_freq)*100000;	hsync /= (w100_pwr_state.pclk_cntl.f.pclk_post_div + 1);	crtc_ss.val = readl(remapped_regs + mmCRTC_SS);	if (crtc_ss.val)		par->hsync_len = hsync / (crtc_ss.f.ss_end-crtc_ss.f.ss_start);	else		par->hsync_len = 0;}static void w100_suspend(u32 mode){	u32 val;	writel(0x7FFF8000, remapped_regs + mmMC_EXT_MEM_LOCATION);	writel(0x00FF0000, remapped_regs + mmMC_PERF_MON_CNTL);	val = readl(remapped_regs + mmMEM_EXT_TIMING_CNTL);	val &= ~(0x00100000);  /* bit20=0 */	val |= 0xFF000000;     /* bit31:24=0xff */	writel(val, remapped_regs + mmMEM_EXT_TIMING_CNTL);	val = readl(remapped_regs + mmMEM_EXT_CNTL);	val &= ~(0x00040000);  /* bit18=0 */	val |= 0x00080000;     /* bit19=1 */	writel(val, remapped_regs + mmMEM_EXT_CNTL);	udelay(1);  /* wait 1us */	if (mode == W100_SUSPEND_EXTMEM) {		/* CKE: Tri-State */		val = readl(remapped_regs + mmMEM_EXT_CNTL);		val |= 0x40000000;  /* bit30=1 */		writel(val, remapped_regs + mmMEM_EXT_CNTL);		/* CLK: Stop */		val = readl(remapped_regs + mmMEM_EXT_CNTL);		val &= ~(0x00000001);  /* bit0=0 */		writel(val, remapped_regs + mmMEM_EXT_CNTL);	} else {		writel(0x00000000, remapped_regs + mmSCLK_CNTL);		writel(0x000000BF, remapped_regs + mmCLK_PIN_CNTL);		writel(0x00000015, remapped_regs + mmPWRMGT_CNTL);		udelay(5);		val = readl(remapped_regs + mmPLL_CNTL);		val |= 0x00000004;  /* bit2=1 */		writel(val, remapped_regs + mmPLL_CNTL);		writel(0x0000001d, remapped_regs + mmPWRMGT_CNTL);	}}static void w100_vsync(void){	u32 tmp;	int timeout = 30000;  /* VSync timeout = 30[ms] > 16.8[ms] */	tmp = readl(remapped_regs + mmACTIVE_V_DISP);	/* set vline pos  */	writel((tmp >> 16) & 0x3ff, remapped_regs + mmDISP_INT_CNTL);	/* disable vline irq */	tmp = readl(remapped_regs + mmGEN_INT_CNTL);	tmp &= ~0x00000002;	writel(tmp, remapped_regs + mmGEN_INT_CNTL);	/* clear vline irq status */	writel(0x00000002, remapped_regs + mmGEN_INT_STATUS);	/* enable vline irq */	writel((tmp | 0x00000002), remapped_regs + mmGEN_INT_CNTL);	/* clear vline irq status */	writel(0x00000002, remapped_regs + mmGEN_INT_STATUS);	while(timeout > 0) {		if (readl(remapped_regs + mmGEN_INT_STATUS) & 0x00000002)			break;		udelay(1);		timeout--;	}	/* disable vline irq */	writel(tmp, remapped_regs + mmGEN_INT_CNTL);	/* clear vline irq status */	writel(0x00000002, remapped_regs + mmGEN_INT_STATUS);}static struct platform_driver w100fb_driver = {	.probe		= w100fb_probe,	.remove		= w100fb_remove,	.suspend	= w100fb_suspend,	.resume		= w100fb_resume,	.driver		= {		.name	= "w100fb",	},};int __devinit w100fb_init(void){	return platform_driver_register(&w100fb_driver);}void __exit w100fb_cleanup(void){	platform_driver_unregister(&w100fb_driver);}module_init(w100fb_init);module_exit(w100fb_cleanup);MODULE_DESCRIPTION("ATI Imageon w100 framebuffer driver");MODULE_LICENSE("GPL");

⌨️ 快捷键说明

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