📄 w100fb.c
字号:
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 + -