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

📄 w100fb.c

📁 Linux环境下视频显示卡设备的驱动程序源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
	writew(0x00, (u16 *) remapped_base + cfgSTATUS);	udelay(100);}static void w100_update_disable(void){	union disp_db_buf_cntl_wr_u disp_db_buf_wr_cntl;	/* Prevent display updates */	disp_db_buf_wr_cntl.f.db_buf_cntl = 0x1e;	disp_db_buf_wr_cntl.f.update_db_buf = 0;	disp_db_buf_wr_cntl.f.en_db_buf = 0;	writel((u32) (disp_db_buf_wr_cntl.val), remapped_regs + mmDISP_DB_BUF_CNTL);}static void w100_update_enable(void){	union disp_db_buf_cntl_wr_u disp_db_buf_wr_cntl;	/* Enable display updates */	disp_db_buf_wr_cntl.f.db_buf_cntl = 0x1e;	disp_db_buf_wr_cntl.f.update_db_buf = 1;	disp_db_buf_wr_cntl.f.en_db_buf = 1;	writel((u32) (disp_db_buf_wr_cntl.val), remapped_regs + mmDISP_DB_BUF_CNTL);}unsigned long w100fb_gpio_read(int port){	unsigned long value;	if (port==W100_GPIO_PORT_A)		value = readl(remapped_regs + mmGPIO_DATA);	else		value = readl(remapped_regs + mmGPIO_DATA2);	return value;}void w100fb_gpio_write(int port, unsigned long value){	if (port==W100_GPIO_PORT_A)		value = writel(value, remapped_regs + mmGPIO_DATA);	else		value = writel(value, remapped_regs + mmGPIO_DATA2);}EXPORT_SYMBOL(w100fb_gpio_read);EXPORT_SYMBOL(w100fb_gpio_write);/* * Initialization of critical w100 hardware */static void w100_hw_init(struct w100fb_par *par){	u32 temp32;	union cif_cntl_u cif_cntl;	union intf_cntl_u intf_cntl;	union cfgreg_base_u cfgreg_base;	union wrap_top_dir_u wrap_top_dir;	union cif_read_dbg_u cif_read_dbg;	union cpu_defaults_u cpu_default;	union cif_write_dbg_u cif_write_dbg;	union wrap_start_dir_u wrap_start_dir;	union cif_io_u cif_io;	struct w100_gpio_regs *gpio = par->mach->gpio;	w100_soft_reset();	/* This is what the fpga_init code does on reset. May be wrong	   but there is little info available */	writel(0x31, remapped_regs + mmSCRATCH_UMSK);	for (temp32 = 0; temp32 < 10000; temp32++)		readl(remapped_regs + mmSCRATCH_UMSK);	writel(0x30, remapped_regs + mmSCRATCH_UMSK);	/* Set up CIF */	cif_io.val = defCIF_IO;	writel((u32)(cif_io.val), remapped_regs + mmCIF_IO);	cif_write_dbg.val = readl(remapped_regs + mmCIF_WRITE_DBG);	cif_write_dbg.f.dis_packer_ful_during_rbbm_timeout = 0;	cif_write_dbg.f.en_dword_split_to_rbbm = 1;	cif_write_dbg.f.dis_timeout_during_rbbm = 1;	writel((u32) (cif_write_dbg.val), remapped_regs + mmCIF_WRITE_DBG);	cif_read_dbg.val = readl(remapped_regs + mmCIF_READ_DBG);	cif_read_dbg.f.dis_rd_same_byte_to_trig_fetch = 1;	writel((u32) (cif_read_dbg.val), remapped_regs + mmCIF_READ_DBG);	cif_cntl.val = readl(remapped_regs + mmCIF_CNTL);	cif_cntl.f.dis_system_bits = 1;	cif_cntl.f.dis_mr = 1;	cif_cntl.f.en_wait_to_compensate_dq_prop_dly = 0;	cif_cntl.f.intb_oe = 1;	cif_cntl.f.interrupt_active_high = 1;	writel((u32) (cif_cntl.val), remapped_regs + mmCIF_CNTL);	/* Setup cfgINTF_CNTL and cfgCPU defaults */	intf_cntl.val = defINTF_CNTL;	intf_cntl.f.ad_inc_a = 1;	intf_cntl.f.ad_inc_b = 1;	intf_cntl.f.rd_data_rdy_a = 0;	intf_cntl.f.rd_data_rdy_b = 0;	writeb((u8) (intf_cntl.val), remapped_base + cfgINTF_CNTL);	cpu_default.val = defCPU_DEFAULTS;	cpu_default.f.access_ind_addr_a = 1;	cpu_default.f.access_ind_addr_b = 1;	cpu_default.f.access_scratch_reg = 1;	cpu_default.f.transition_size = 0;	writeb((u8) (cpu_default.val), remapped_base + cfgCPU_DEFAULTS);	/* set up the apertures */	writeb((u8) (W100_REG_BASE >> 16), remapped_base + cfgREG_BASE);	cfgreg_base.val = defCFGREG_BASE;	cfgreg_base.f.cfgreg_base = W100_CFG_BASE;	writel((u32) (cfgreg_base.val), remapped_regs + mmCFGREG_BASE);	wrap_start_dir.val = defWRAP_START_DIR;	wrap_start_dir.f.start_addr = WRAP_BUF_BASE_VALUE >> 1;	writel((u32) (wrap_start_dir.val), remapped_regs + mmWRAP_START_DIR);	wrap_top_dir.val = defWRAP_TOP_DIR;	wrap_top_dir.f.top_addr = WRAP_BUF_TOP_VALUE >> 1;	writel((u32) (wrap_top_dir.val), remapped_regs + mmWRAP_TOP_DIR);	writel((u32) 0x2440, remapped_regs + mmRBBM_CNTL);	/* Set the hardware to 565 colour */	temp32 = readl(remapped_regs + mmDISP_DEBUG2);	temp32 &= 0xff7fffff;	temp32 |= 0x00800000;	writel(temp32, remapped_regs + mmDISP_DEBUG2);	/* Initialise the GPIO lines */	if (gpio) {		writel(gpio->init_data1, remapped_regs + mmGPIO_DATA);		writel(gpio->init_data2, remapped_regs + mmGPIO_DATA2);		writel(gpio->gpio_dir1,  remapped_regs + mmGPIO_CNTL1);		writel(gpio->gpio_oe1,   remapped_regs + mmGPIO_CNTL2);		writel(gpio->gpio_dir2,  remapped_regs + mmGPIO_CNTL3);		writel(gpio->gpio_oe2,   remapped_regs + mmGPIO_CNTL4);	}}struct power_state {	union clk_pin_cntl_u clk_pin_cntl;	union pll_ref_fb_div_u pll_ref_fb_div;	union pll_cntl_u pll_cntl;	union sclk_cntl_u sclk_cntl;	union pclk_cntl_u pclk_cntl;	union pwrmgt_cntl_u pwrmgt_cntl;	int auto_mode;  /* system clock auto changing? */};static struct power_state w100_pwr_state;/* The PLL Fout is determined by (XtalFreq/(M+1)) * ((N_int+1) + (N_fac/8)) *//* 12.5MHz Crystal PLL Table */static struct w100_pll_info xtal_12500000[] = {	/*freq     M   N_int    N_fac  tfgoal  lock_time */	{ 50,      0,   1,       0,     0xe0,        56},  /*  50.00 MHz */	{ 75,      0,   5,       0,     0xde,        37},  /*  75.00 MHz */	{100,      0,   7,       0,     0xe0,        28},  /* 100.00 MHz */	{125,      0,   9,       0,     0xe0,        22},  /* 125.00 MHz */	{150,      0,   11,      0,     0xe0,        17},  /* 150.00 MHz */	{  0,      0,   0,       0,        0,         0},  /* Terminator */};/* 14.318MHz Crystal PLL Table */static struct w100_pll_info xtal_14318000[] = {	/*freq     M   N_int    N_fac  tfgoal  lock_time */	{ 40,      4,   13,      0,     0xe0,        80}, /* tfgoal guessed */	{ 50,      1,   6,       0,     0xe0,	     64}, /*  50.05 MHz */	{ 57,      2,   11,      0,     0xe0,        53}, /* tfgoal guessed */	{ 75,      0,   4,       3,     0xe0,	     43}, /*  75.08 MHz */	{100,      0,   6,       0,     0xe0,        32}, /* 100.10 MHz */	{  0,      0,   0,       0,        0,         0},};/* 16MHz Crystal PLL Table */static struct w100_pll_info xtal_16000000[] = {	/*freq     M   N_int    N_fac  tfgoal  lock_time */	{ 72,      1,   8,       0,     0xe0,        48}, /* tfgoal guessed */	{ 80,      1,   9,       0,     0xe0,        13}, /* tfgoal guessed */	{ 95,      1,   10,      7,     0xe0,        38}, /* tfgoal guessed */	{ 96,      1,   11,      0,     0xe0,        36}, /* tfgoal guessed */	{  0,      0,   0,       0,        0,         0},};static struct pll_entries {	int xtal_freq;	struct w100_pll_info *pll_table;} w100_pll_tables[] = {	{ 12500000, &xtal_12500000[0] },	{ 14318000, &xtal_14318000[0] },	{ 16000000, &xtal_16000000[0] },	{ 0 },};struct w100_pll_info *w100_get_xtal_table(unsigned int freq){	struct pll_entries *pll_entry = w100_pll_tables;	do {		if (freq == pll_entry->xtal_freq)			return pll_entry->pll_table;		pll_entry++;	} while (pll_entry->xtal_freq);	return 0;}static unsigned int w100_get_testcount(unsigned int testclk_sel){	union clk_test_cntl_u clk_test_cntl;	udelay(5);	/* Select the test clock source and reset */	clk_test_cntl.f.start_check_freq = 0x0;	clk_test_cntl.f.testclk_sel = testclk_sel;	clk_test_cntl.f.tstcount_rst = 0x1; /* set reset */	writel((u32) (clk_test_cntl.val), remapped_regs + mmCLK_TEST_CNTL);	clk_test_cntl.f.tstcount_rst = 0x0; /* clear reset */	writel((u32) (clk_test_cntl.val), remapped_regs + mmCLK_TEST_CNTL);	/* Run clock test */	clk_test_cntl.f.start_check_freq = 0x1;	writel((u32) (clk_test_cntl.val), remapped_regs + mmCLK_TEST_CNTL);	/* Give the test time to complete */	udelay(20);	/* Return the result */	clk_test_cntl.val = readl(remapped_regs + mmCLK_TEST_CNTL);	clk_test_cntl.f.start_check_freq = 0x0;	writel((u32) (clk_test_cntl.val), remapped_regs + mmCLK_TEST_CNTL);	return clk_test_cntl.f.test_count;}static int w100_pll_adjust(struct w100_pll_info *pll){	unsigned int tf80;	unsigned int tf20;	/* Initial Settings */	w100_pwr_state.pll_cntl.f.pll_pwdn = 0x0;     /* power down */	w100_pwr_state.pll_cntl.f.pll_reset = 0x0;    /* not reset */	w100_pwr_state.pll_cntl.f.pll_tcpoff = 0x1;   /* Hi-Z */	w100_pwr_state.pll_cntl.f.pll_pvg = 0x0;      /* VCO gain = 0 */	w100_pwr_state.pll_cntl.f.pll_vcofr = 0x0;    /* VCO frequency range control = off */	w100_pwr_state.pll_cntl.f.pll_ioffset = 0x0;  /* current offset inside VCO = 0 */	w100_pwr_state.pll_cntl.f.pll_ring_off = 0x0;	/* Wai Ming 80 percent of VDD 1.3V gives 1.04V, minimum operating voltage is 1.08V	 * therefore, commented out the following lines	 * tf80 meant tf100	 */	do {		/* set VCO input = 0.8 * VDD */		w100_pwr_state.pll_cntl.f.pll_dactal = 0xd;		writel((u32) (w100_pwr_state.pll_cntl.val), remapped_regs + mmPLL_CNTL);		tf80 = w100_get_testcount(TESTCLK_SRC_PLL);		if (tf80 >= (pll->tfgoal)) {			/* set VCO input = 0.2 * VDD */			w100_pwr_state.pll_cntl.f.pll_dactal = 0x7;			writel((u32) (w100_pwr_state.pll_cntl.val), remapped_regs + mmPLL_CNTL);			tf20 = w100_get_testcount(TESTCLK_SRC_PLL);			if (tf20 <= (pll->tfgoal))				return 1;  /* Success */			if ((w100_pwr_state.pll_cntl.f.pll_vcofr == 0x0) &&				((w100_pwr_state.pll_cntl.f.pll_pvg == 0x7) ||				(w100_pwr_state.pll_cntl.f.pll_ioffset == 0x0))) {				/* slow VCO config */				w100_pwr_state.pll_cntl.f.pll_vcofr = 0x1;				w100_pwr_state.pll_cntl.f.pll_pvg = 0x0;				w100_pwr_state.pll_cntl.f.pll_ioffset = 0x0;				continue;			}		}		if ((w100_pwr_state.pll_cntl.f.pll_ioffset) < 0x3) {			w100_pwr_state.pll_cntl.f.pll_ioffset += 0x1;		} else if ((w100_pwr_state.pll_cntl.f.pll_pvg) < 0x7) {			w100_pwr_state.pll_cntl.f.pll_ioffset = 0x0;			w100_pwr_state.pll_cntl.f.pll_pvg += 0x1;		} else {			return 0;  /* Error */		}	} while(1);}/* * w100_pll_calibration */static int w100_pll_calibration(struct w100_pll_info *pll){	int status;	status = w100_pll_adjust(pll);	/* PLL Reset And Lock */	/* set VCO input = 0.5 * VDD */	w100_pwr_state.pll_cntl.f.pll_dactal = 0xa;	writel((u32) (w100_pwr_state.pll_cntl.val), remapped_regs + mmPLL_CNTL);	udelay(1);  /* reset time */	/* enable charge pump */	w100_pwr_state.pll_cntl.f.pll_tcpoff = 0x0;  /* normal */	writel((u32) (w100_pwr_state.pll_cntl.val), remapped_regs + mmPLL_CNTL);	/* set VCO input = Hi-Z, disable DAC */	w100_pwr_state.pll_cntl.f.pll_dactal = 0x0;	writel((u32) (w100_pwr_state.pll_cntl.val), remapped_regs + mmPLL_CNTL);	udelay(400);  /* lock time */	/* PLL locked */	return status;}static int w100_pll_set_clk(struct w100_pll_info *pll){	int status;	if (w100_pwr_state.auto_mode == 1)  /* auto mode */	{		w100_pwr_state.pwrmgt_cntl.f.pwm_fast_noml_hw_en = 0x0;  /* disable fast to normal */		w100_pwr_state.pwrmgt_cntl.f.pwm_noml_fast_hw_en = 0x0;  /* disable normal to fast */		writel((u32) (w100_pwr_state.pwrmgt_cntl.val), remapped_regs + mmPWRMGT_CNTL);	}	/* Set system clock source to XTAL whilst adjusting the PLL! */	w100_pwr_state.sclk_cntl.f.sclk_src_sel = CLK_SRC_XTAL;	writel((u32) (w100_pwr_state.sclk_cntl.val), remapped_regs + mmSCLK_CNTL);	w100_pwr_state.pll_ref_fb_div.f.pll_ref_div = pll->M;	w100_pwr_state.pll_ref_fb_div.f.pll_fb_div_int = pll->N_int;	w100_pwr_state.pll_ref_fb_div.f.pll_fb_div_frac = pll->N_fac;	w100_pwr_state.pll_ref_fb_div.f.pll_lock_time = pll->lock_time;	writel((u32) (w100_pwr_state.pll_ref_fb_div.val), remapped_regs + mmPLL_REF_FB_DIV);	w100_pwr_state.pwrmgt_cntl.f.pwm_mode_req = 0;	writel((u32) (w100_pwr_state.pwrmgt_cntl.val), remapped_regs + mmPWRMGT_CNTL);	status = w100_pll_calibration(pll);	if (w100_pwr_state.auto_mode == 1)  /* auto mode */	{		w100_pwr_state.pwrmgt_cntl.f.pwm_fast_noml_hw_en = 0x1;  /* reenable fast to normal */		w100_pwr_state.pwrmgt_cntl.f.pwm_noml_fast_hw_en = 0x1;  /* reenable normal to fast  */		writel((u32) (w100_pwr_state.pwrmgt_cntl.val), remapped_regs + mmPWRMGT_CNTL);	}	return status;}/* freq = target frequency of the PLL */static int w100_set_pll_freq(struct w100fb_par *par, unsigned int freq){	struct w100_pll_info *pll = par->pll_table;	do {		if (freq == pll->freq) {			return w100_pll_set_clk(pll);		}		pll++;	} while(pll->freq);	return 0;}/* Set up an initial state.  Some values/fields set   here will be overwritten. */static void w100_pwm_setup(struct w100fb_par *par){	w100_pwr_state.clk_pin_cntl.f.osc_en = 0x1;	w100_pwr_state.clk_pin_cntl.f.osc_gain = 0x1f;	w100_pwr_state.clk_pin_cntl.f.dont_use_xtalin = 0x0;	w100_pwr_state.clk_pin_cntl.f.xtalin_pm_en = 0x0;	w100_pwr_state.clk_pin_cntl.f.xtalin_dbl_en = par->mach->xtal_dbl ? 1 : 0;	w100_pwr_state.clk_pin_cntl.f.cg_debug = 0x0;	writel((u32) (w100_pwr_state.clk_pin_cntl.val), remapped_regs + mmCLK_PIN_CNTL);	w100_pwr_state.sclk_cntl.f.sclk_src_sel = CLK_SRC_XTAL;	w100_pwr_state.sclk_cntl.f.sclk_post_div_fast = 0x0;  /* Pfast = 1 */	w100_pwr_state.sclk_cntl.f.sclk_clkon_hys = 0x3;	w100_pwr_state.sclk_cntl.f.sclk_post_div_slow = 0x0;  /* Pslow = 1 */	w100_pwr_state.sclk_cntl.f.disp_cg_ok2switch_en = 0x0;	w100_pwr_state.sclk_cntl.f.sclk_force_reg = 0x0;    /* Dynamic */	w100_pwr_state.sclk_cntl.f.sclk_force_disp = 0x0;   /* Dynamic */	w100_pwr_state.sclk_cntl.f.sclk_force_mc = 0x0;     /* Dynamic */	w100_pwr_state.sclk_cntl.f.sclk_force_extmc = 0x0;  /* Dynamic */	w100_pwr_state.sclk_cntl.f.sclk_force_cp = 0x0;     /* Dynamic */	w100_pwr_state.sclk_cntl.f.sclk_force_e2 = 0x0;     /* Dynamic */	w100_pwr_state.sclk_cntl.f.sclk_force_e3 = 0x0;     /* Dynamic */	w100_pwr_state.sclk_cntl.f.sclk_force_idct = 0x0;   /* Dynamic */	w100_pwr_state.sclk_cntl.f.sclk_force_bist = 0x0;   /* Dynamic */

⌨️ 快捷键说明

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