📄 pm3fb.c
字号:
t_3DLabsOxygenVX1 }, { "3DLabs Oxygen VX1 AGP", PCI_VENDOR_ID_3DLABS, 0x0125, 0, NULL, NULL }, { "3DLabs Oxygen VX1-16 AGP", PCI_VENDOR_ID_3DLABS, 0x0140, 0, NULL, NULL }, { "3DLabs Oxygen VX1-1600SW PCI", PCI_VENDOR_ID_3DLABS, 0x0800, 0, NULL, NULL }, { "\0", 0x0, 0x0, 0, NULL, NULL }};/* ********************************** *//* ***** card-specific function ***** *//* ********************************** */static void pm3fb_j2000_setup(struct pm3fb_info *l_fb_info){ /* the appian j2000 require more initialization of the second head */ /* l_fb_info must point to the _second_ head of the J2000 */ DTRACE; l_fb_info->memt = t_AppianJeronimo2000[0].memt; /* 32 MB, first and only j2000 ? */ pm3fb_write_memory_timings(l_fb_info);}/* *************************************** *//* ***** permedia3-specific function ***** *//* *************************************** */static pm3fb_timing_result pm3fb_preserve_memory_timings(struct pm3fb_info *l_fb_info){ l_fb_info->memt.caps = PM3_READ_REG(PM3LocalMemCaps); l_fb_info->memt.timings = PM3_READ_REG(PM3LocalMemTimings); l_fb_info->memt.control = PM3_READ_REG(PM3LocalMemControl); l_fb_info->memt.refresh = PM3_READ_REG(PM3LocalMemRefresh); l_fb_info->memt.powerdown = PM3_READ_REG(PM3LocalMemPowerDown); if ((l_fb_info->memt.caps == PM3FB_UNKNOWN_TIMING_VALUE) || (l_fb_info->memt.timings == PM3FB_UNKNOWN_TIMING_VALUE) || (l_fb_info->memt.control == PM3FB_UNKNOWN_TIMING_VALUE) || (l_fb_info->memt.refresh == PM3FB_UNKNOWN_TIMING_VALUE) || (l_fb_info->memt.powerdown == PM3FB_UNKNOWN_TIMING_VALUE)) { printk(KERN_ERR "pm3fb: invalid memory timings in permedia3 board #%ld\n", l_fb_info->board_num); return(pm3fb_try_memory_timings(l_fb_info)); } return(pm3fb_timing_ok);}static pm3fb_timing_result pm3fb_try_memory_timings(struct pm3fb_info *l_fb_info){ if (cardbase[l_fb_info->board_type].c_memt) { int i = 0, done = 0; while (!done) { if ((cardbase[l_fb_info->board_type].c_memt[i].memsize == l_fb_info->fb_size) || !(cardbase[l_fb_info->board_type].c_memt[i].memsize)) { /* will use the 0-sized timings by default */ done = 1; l_fb_info->memt = cardbase[l_fb_info->board_type].c_memt[i].memt; printk(KERN_WARNING "pm3fb: trying to use predefined memory timings for permedia3 board #%ld (%s, %ld MB)\n", l_fb_info->board_num, cardbase[l_fb_info->board_type].cardname, cardbase[l_fb_info->board_type].c_memt[i].memsize); pm3fb_write_memory_timings(l_fb_info); return(pm3fb_timing_retry); } i++; } } else return(pm3fb_timing_problem); return(pm3fb_timing_ok);}static void pm3fb_write_memory_timings(struct pm3fb_info *l_fb_info){ unsigned char m, n, p; unsigned long clockused; PM3_SLOW_WRITE_REG(PM3LocalMemCaps, l_fb_info->memt.caps); PM3_SLOW_WRITE_REG(PM3LocalMemTimings, l_fb_info->memt.timings); PM3_SLOW_WRITE_REG(PM3LocalMemControl, l_fb_info->memt.control); PM3_SLOW_WRITE_REG(PM3LocalMemRefresh, l_fb_info->memt.refresh); PM3_SLOW_WRITE_REG(PM3LocalMemPowerDown, l_fb_info->memt.powerdown); clockused = pm3fb_CalculateClock(l_fb_info, 2 * 105000, PM3_REF_CLOCK, &m, &n, &p); PM3_WRITE_DAC_REG(PM3RD_KClkPreScale, m); PM3_WRITE_DAC_REG(PM3RD_KClkFeedbackScale, n); PM3_WRITE_DAC_REG(PM3RD_KClkPostScale, p); PM3_WRITE_DAC_REG(PM3RD_KClkControl, PM3RD_KClkControl_STATE_RUN | PM3RD_KClkControl_SOURCE_PLL | PM3RD_KClkControl_ENABLE); PM3_WRITE_DAC_REG(PM3RD_MClkControl, PM3RD_MClkControl_STATE_RUN | PM3RD_MClkControl_SOURCE_KCLK | PM3RD_MClkControl_ENABLE); PM3_WRITE_DAC_REG(PM3RD_SClkControl, PM3RD_SClkControl_STATE_RUN | PM3RD_SClkControl_SOURCE_PCLK | PM3RD_SClkControl_ENABLE);}static unsigned long pm3fb_read_dac_reg(struct pm3fb_info *l_fb_info, unsigned long r){ DASSERT((l_fb_info->vIOBase != (unsigned char *) (-1)), "l_fb_info->vIOBase mapped in read dac reg\n"); PM3_SET_INDEX(r); mb(); return (PM3_READ_REG(PM3RD_IndexedData));}/* Calculating various clock parameter */static unsigned long pm3fb_CalculateClock(struct pm3fb_info *l_fb_info, unsigned long reqclock, /* In kHz units */ unsigned long refclock, /* In kHz units */ unsigned char *prescale, /* ClkPreScale */ unsigned char *feedback, /* ClkFeedBackScale */ unsigned char *postscale /* ClkPostScale */ ){ int f, pre, post; unsigned long freq; long freqerr = 1000; unsigned long actualclock = 0; DTRACE; for (f = 1; f < 256; f++) { for (pre = 1; pre < 256; pre++) { for (post = 0; post < 5; post++) { freq = ((2 * refclock * f) / (pre * (1 << post))); if ((reqclock > freq - freqerr) && (reqclock < freq + freqerr)) { freqerr = (reqclock > freq) ? reqclock - freq : freq - reqclock; *feedback = f; *prescale = pre; *postscale = post; actualclock = freq; } } } } return (actualclock);}static int pm3fb_Shiftbpp(struct pm3fb_info *l_fb_info, unsigned long depth, int v){ DTRACE; switch (depth) { case 8: return (v >> 4); case 12: case 15: case 16: return (v >> 3); case 32: return (v >> 2); } DPRINTK(1, "Unsupported depth %ld\n", depth); return (0);}static int pm3fb_Unshiftbpp(struct pm3fb_info *l_fb_info, unsigned long depth, int v){ DTRACE; switch (depth) { case 8: return (v << 4); case 12: case 15: case 16: return (v << 3); case 32: return (v << 2); } DPRINTK(1, "Unsupported depth %ld\n", depth); return (0);}static void pm3fb_mapIO(struct pm3fb_info *l_fb_info){ DTRACE; l_fb_info->vIOBase = ioremap((unsigned long) l_fb_info->pIOBase, PM3_REGS_SIZE); l_fb_info->v_fb = ioremap((unsigned long) l_fb_info->p_fb, l_fb_info->fb_size); DPRINTK(2, "IO mapping : IOBase %lx / %lx, fb %lx / %lx\n", (unsigned long) l_fb_info->pIOBase, (unsigned long) l_fb_info->vIOBase, (unsigned long) l_fb_info->p_fb, (unsigned long) l_fb_info->v_fb);}static void pm3fb_unmapIO(struct pm3fb_info *l_fb_info){ DTRACE; iounmap(l_fb_info->vIOBase); iounmap(l_fb_info->v_fb); l_fb_info->vIOBase = (unsigned char *) -1; l_fb_info->v_fb = (unsigned char *) -1;}#if defined(PM3FB_MASTER_DEBUG) && (PM3FB_MASTER_DEBUG >= 2)static void pm3fb_show_cur_mode(struct pm3fb_info *l_fb_info){ DPRINTK(2, "PM3Aperture0: 0x%08x\n", PM3_READ_REG(PM3Aperture0)); DPRINTK(2, "PM3Aperture1: 0x%08x\n", PM3_READ_REG(PM3Aperture1)); DPRINTK(2, "PM3ByAperture1Mode: 0x%08x\n", PM3_READ_REG(PM3ByAperture1Mode)); DPRINTK(2, "PM3ByAperture2Mode: 0x%08x\n", PM3_READ_REG(PM3ByAperture2Mode)); DPRINTK(2, "PM3ChipConfig: 0x%08x\n", PM3_READ_REG(PM3ChipConfig)); DPRINTK(2, "PM3FIFODis: 0x%08x\n", PM3_READ_REG(PM3FIFODis)); DPRINTK(2, "PM3HTotal: 0x%08x\n", PM3_READ_REG(PM3HTotal)); DPRINTK(2, "PM3HbEnd: 0x%08x\n", PM3_READ_REG(PM3HbEnd)); DPRINTK(2, "PM3HgEnd: 0x%08x\n", PM3_READ_REG(PM3HgEnd)); DPRINTK(2, "PM3HsEnd: 0x%08x\n", PM3_READ_REG(PM3HsEnd)); DPRINTK(2, "PM3HsStart: 0x%08x\n", PM3_READ_REG(PM3HsStart)); DPRINTK(2, "PM3MemBypassWriteMask: 0x%08x\n", PM3_READ_REG(PM3MemBypassWriteMask)); DPRINTK(2, "PM3RD_IndexControl: 0x%08x\n", PM3_READ_REG(PM3RD_IndexControl)); DPRINTK(2, "PM3ScreenBase: 0x%08x\n", PM3_READ_REG(PM3ScreenBase)); DPRINTK(2, "PM3ScreenStride: 0x%08x\n", PM3_READ_REG(PM3ScreenStride)); DPRINTK(2, "PM3VClkCtl: 0x%08x\n", PM3_READ_REG(PM3VClkCtl)); DPRINTK(2, "PM3VTotal: 0x%08x\n", PM3_READ_REG(PM3VTotal)); DPRINTK(2, "PM3VbEnd: 0x%08x\n", PM3_READ_REG(PM3VbEnd)); DPRINTK(2, "PM3VideoControl: 0x%08x\n", PM3_READ_REG(PM3VideoControl)); DPRINTK(2, "PM3VsEnd: 0x%08x\n", PM3_READ_REG(PM3VsEnd)); DPRINTK(2, "PM3VsStart: 0x%08x\n", PM3_READ_REG(PM3VsStart)); DPRINTK(2, "PM3RD_ColorFormat: %ld\n", PM3_READ_DAC_REG(PM3RD_ColorFormat)); DPRINTK(2, "PM3RD_DACControl: %ld\n", PM3_READ_DAC_REG(PM3RD_DACControl)); DPRINTK(2, "PM3RD_DClk0FeedbackScale: %ld\n", PM3_READ_DAC_REG(PM3RD_DClk0FeedbackScale)); DPRINTK(2, "PM3RD_DClk0PostScale: %ld\n", PM3_READ_DAC_REG(PM3RD_DClk0PostScale)); DPRINTK(2, "PM3RD_DClk0PreScale: %ld\n", PM3_READ_DAC_REG(PM3RD_DClk0PreScale)); DPRINTK(2, "[not set] PM3RD_IndexControl: %ld\n", PM3_READ_DAC_REG(PM3RD_IndexControl)); DPRINTK(2, "PM3RD_MiscControl: %ld\n", PM3_READ_DAC_REG(PM3RD_MiscControl)); DPRINTK(2, "PM3RD_PixelSize: %ld\n", PM3_READ_DAC_REG(PM3RD_PixelSize)); DPRINTK(2, "PM3RD_SyncControl: %ld\n", PM3_READ_DAC_REG(PM3RD_SyncControl));}#endif /* defined(PM3FB_MASTER_DEBUG) && (PM3FB_MASTER_DEBUG >= 2) */static void pm3fb_show_cur_timing(struct pm3fb_info *l_fb_info){ u16 subvendor, subdevice; if ((!pci_read_config_word (l_fb_info->dev, PCI_SUBSYSTEM_VENDOR_ID, &subvendor)) && (!pci_read_config_word (l_fb_info->dev, PCI_SUBSYSTEM_ID, &subdevice))) { /* well, nothing... */ } else { subvendor = subdevice = (u16)-1; } printk(KERN_INFO "pm3fb: memory timings for board #%ld (subvendor: 0x%hx, subdevice: 0x%hx)\n", l_fb_info->board_num, subvendor, subdevice); printk(KERN_INFO " PM3LocalMemCaps: 0x%08x\n", PM3_READ_REG(PM3LocalMemCaps)); printk(KERN_INFO " PM3LocalMemTimings: 0x%08x\n", PM3_READ_REG(PM3LocalMemTimings)); printk(KERN_INFO " PM3LocalMemControl: 0x%08x\n", PM3_READ_REG(PM3LocalMemControl)); printk(KERN_INFO " PM3LocalMemRefresh: 0x%08x\n", PM3_READ_REG(PM3LocalMemRefresh)); printk(KERN_INFO " PM3LocalMemPowerDown: 0x%08x\n", PM3_READ_REG(PM3LocalMemPowerDown));}/* write the mode to registers */static void pm3fb_write_mode(struct pm3fb_info *l_fb_info){ char tempsync = 0x00, tempmisc = 0x00; DTRACE; PM3_SLOW_WRITE_REG(PM3MemBypassWriteMask, 0xffffffff); PM3_SLOW_WRITE_REG(PM3Aperture0, 0x00000000); PM3_SLOW_WRITE_REG(PM3Aperture1, 0x00000000); PM3_SLOW_WRITE_REG(PM3FIFODis, 0x00000007); PM3_SLOW_WRITE_REG(PM3HTotal, pm3fb_Shiftbpp(l_fb_info, l_fb_info->current_par->depth, l_fb_info->current_par->htotal - 1)); PM3_SLOW_WRITE_REG(PM3HsEnd, pm3fb_Shiftbpp(l_fb_info, l_fb_info->current_par->depth, l_fb_info->current_par->hsend)); PM3_SLOW_WRITE_REG(PM3HsStart, pm3fb_Shiftbpp(l_fb_info, l_fb_info->current_par->depth, l_fb_info->current_par-> hsstart)); PM3_SLOW_WRITE_REG(PM3HbEnd, pm3fb_Shiftbpp(l_fb_info, l_fb_info->current_par->depth, l_fb_info->current_par->hbend)); PM3_SLOW_WRITE_REG(PM3HgEnd, pm3fb_Shiftbpp(l_fb_info, l_fb_info->current_par->depth, l_fb_info->current_par->hbend)); PM3_SLOW_WRITE_REG(PM3ScreenStride, pm3fb_Shiftbpp(l_fb_info, l_fb_info->current_par->depth, l_fb_info->current_par->stride)); PM3_SLOW_WRITE_REG(PM3VTotal, l_fb_info->current_par->vtotal - 1); PM3_SLOW_WRITE_REG(PM3VsEnd, l_fb_info->current_par->vsend - 1); PM3_SLOW_WRITE_REG(PM3VsStart, l_fb_info->current_par->vsstart - 1); PM3_SLOW_WRITE_REG(PM3VbEnd, l_fb_info->current_par->vbend); switch (l_fb_info->current_par->depth) { case 8: PM3_SLOW_WRITE_REG(PM3ByAperture1Mode, PM3ByApertureMode_PIXELSIZE_8BIT); PM3_SLOW_WRITE_REG(PM3ByAperture2Mode, PM3ByApertureMode_PIXELSIZE_8BIT); break; case 12: case 15: case 16:#ifndef __BIG_ENDIAN PM3_SLOW_WRITE_REG(PM3ByAperture1Mode, PM3ByApertureMode_PIXELSIZE_16BIT); PM3_SLOW_WRITE_REG(PM3ByAperture2Mode, PM3ByApertureMode_PIXELSIZE_16BIT);#else PM3_SLOW_WRITE_REG(PM3ByAperture1Mode, PM3ByApertureMode_PIXELSIZE_16BIT | PM3ByApertureMode_BYTESWAP_BADC); PM3_SLOW_WRITE_REG(PM3ByAperture2Mode, PM3ByApertureMode_PIXELSIZE_16BIT | PM3ByApertureMode_BYTESWAP_BADC);#endif /* ! __BIG_ENDIAN */ break; case 32:#ifndef __BIG_ENDIAN PM3_SLOW_WRITE_REG(PM3ByAperture1Mode, PM3ByApertureMode_PIXELSIZE_32BIT); PM3_SLOW_WRITE_REG(PM3ByAperture2Mode, PM3ByApertureMode_PIXELSIZE_32BIT);#else PM3_SLOW_WRITE_REG(PM3ByAperture1Mode, PM3ByApertureMode_PIXELSIZE_32BIT | PM3ByApertureMode_BYTESWAP_DCBA); PM3_SLOW_WRITE_REG(PM3ByAperture2Mode, PM3ByApertureMode_PIXELSIZE_32BIT | PM3ByApertureMode_BYTESWAP_DCBA);#endif /* ! __BIG_ENDIAN */ break; default: DPRINTK(1, "Unsupported depth %d\n", l_fb_info->current_par->depth); break; } /*
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -