📄 pm3fb.c
字号:
* Oxygen VX1 - it appears that setting PM3VideoControl and * then PM3RD_SyncControl to the same SYNC settings undoes * any net change - they seem to xor together. Only set the * sync options in PM3RD_SyncControl. --rmk */ { unsigned int video = l_fb_info->current_par->video; video &= ~(PM3VideoControl_HSYNC_MASK | PM3VideoControl_VSYNC_MASK); video |= PM3VideoControl_HSYNC_ACTIVE_HIGH | PM3VideoControl_VSYNC_ACTIVE_HIGH; PM3_SLOW_WRITE_REG(PM3VideoControl, video); } PM3_SLOW_WRITE_REG(PM3VClkCtl, (PM3_READ_REG(PM3VClkCtl) & 0xFFFFFFFC)); PM3_SLOW_WRITE_REG(PM3ScreenBase, l_fb_info->current_par->base); PM3_SLOW_WRITE_REG(PM3ChipConfig, (PM3_READ_REG(PM3ChipConfig) & 0xFFFFFFFD)); { unsigned char m; /* ClkPreScale */ unsigned char n; /* ClkFeedBackScale */ unsigned char p; /* ClkPostScale */ (void)pm3fb_CalculateClock(l_fb_info, l_fb_info->current_par->pixclock, PM3_REF_CLOCK, &m, &n, &p); DPRINTK(2, "Pixclock: %d, Pre: %d, Feedback: %d, Post: %d\n", l_fb_info->current_par->pixclock, (int) m, (int) n, (int) p); PM3_WRITE_DAC_REG(PM3RD_DClk0PreScale, m); PM3_WRITE_DAC_REG(PM3RD_DClk0FeedbackScale, n); PM3_WRITE_DAC_REG(PM3RD_DClk0PostScale, p); } /* PM3_WRITE_DAC_REG(PM3RD_IndexControl, 0x00); */ /* PM3_SLOW_WRITE_REG(PM3RD_IndexControl, 0x00); */ if ((l_fb_info->current_par->video & PM3VideoControl_HSYNC_MASK) == PM3VideoControl_HSYNC_ACTIVE_HIGH) tempsync |= PM3RD_SyncControl_HSYNC_ACTIVE_HIGH; if ((l_fb_info->current_par->video & PM3VideoControl_VSYNC_MASK) == PM3VideoControl_VSYNC_ACTIVE_HIGH) tempsync |= PM3RD_SyncControl_VSYNC_ACTIVE_HIGH; PM3_WRITE_DAC_REG(PM3RD_SyncControl, tempsync); DPRINTK(2, "PM3RD_SyncControl: %d\n", tempsync); if (flatpanel[l_fb_info->board_num]) { PM3_WRITE_DAC_REG(PM3RD_DACControl, PM3RD_DACControl_BLANK_PEDESTAL_ENABLE); PM3_WAIT(2); PM3_WRITE_REG(PM3VSConfiguration, 0x06); PM3_WRITE_REG(0x5a00, 1 << 14); /* black magic... */ tempmisc = PM3RD_MiscControl_VSB_OUTPUT_ENABLE; } else PM3_WRITE_DAC_REG(PM3RD_DACControl, 0x00); switch (l_fb_info->current_par->depth) { case 8: PM3_WRITE_DAC_REG(PM3RD_PixelSize, PM3RD_PixelSize_8_BIT_PIXELS); PM3_WRITE_DAC_REG(PM3RD_ColorFormat, PM3RD_ColorFormat_CI8_COLOR | PM3RD_ColorFormat_COLOR_ORDER_BLUE_LOW); tempmisc |= PM3RD_MiscControl_HIGHCOLOR_RES_ENABLE; break; case 12: PM3_WRITE_DAC_REG(PM3RD_PixelSize, PM3RD_PixelSize_16_BIT_PIXELS); PM3_WRITE_DAC_REG(PM3RD_ColorFormat, PM3RD_ColorFormat_4444_COLOR | PM3RD_ColorFormat_COLOR_ORDER_BLUE_LOW | PM3RD_ColorFormat_LINEAR_COLOR_EXT_ENABLE); tempmisc |= PM3RD_MiscControl_DIRECTCOLOR_ENABLE | PM3RD_MiscControl_HIGHCOLOR_RES_ENABLE; break; case 15: PM3_WRITE_DAC_REG(PM3RD_PixelSize, PM3RD_PixelSize_16_BIT_PIXELS); PM3_WRITE_DAC_REG(PM3RD_ColorFormat, PM3RD_ColorFormat_5551_FRONT_COLOR | PM3RD_ColorFormat_COLOR_ORDER_BLUE_LOW | PM3RD_ColorFormat_LINEAR_COLOR_EXT_ENABLE); tempmisc |= PM3RD_MiscControl_DIRECTCOLOR_ENABLE | PM3RD_MiscControl_HIGHCOLOR_RES_ENABLE; break; case 16: PM3_WRITE_DAC_REG(PM3RD_PixelSize, PM3RD_PixelSize_16_BIT_PIXELS); PM3_WRITE_DAC_REG(PM3RD_ColorFormat, PM3RD_ColorFormat_565_FRONT_COLOR | PM3RD_ColorFormat_COLOR_ORDER_BLUE_LOW | PM3RD_ColorFormat_LINEAR_COLOR_EXT_ENABLE); tempmisc |= PM3RD_MiscControl_DIRECTCOLOR_ENABLE | PM3RD_MiscControl_HIGHCOLOR_RES_ENABLE; break; case 32: PM3_WRITE_DAC_REG(PM3RD_PixelSize, PM3RD_PixelSize_32_BIT_PIXELS); PM3_WRITE_DAC_REG(PM3RD_ColorFormat, PM3RD_ColorFormat_8888_COLOR | PM3RD_ColorFormat_COLOR_ORDER_BLUE_LOW); tempmisc |= PM3RD_MiscControl_DIRECTCOLOR_ENABLE | PM3RD_MiscControl_HIGHCOLOR_RES_ENABLE; break; } PM3_WRITE_DAC_REG(PM3RD_MiscControl, tempmisc); PM3_SHOW_CUR_MODE;}static void pm3fb_read_mode(struct pm3fb_info *l_fb_info, struct pm3fb_par *curpar){ unsigned long pixsize1, pixsize2, clockused; unsigned long pre, feedback, post; DTRACE; clockused = PM3_READ_REG(PM3VClkCtl); switch (clockused) { case 3: pre = PM3_READ_DAC_REG(PM3RD_DClk3PreScale); feedback = PM3_READ_DAC_REG(PM3RD_DClk3FeedbackScale); post = PM3_READ_DAC_REG(PM3RD_DClk3PostScale); DPRINTK(2, "DClk3 parameter: Pre: %ld, Feedback: %ld, Post: %ld ; giving pixclock: %ld\n", pre, feedback, post, PM3_SCALE_TO_CLOCK(pre, feedback, post)); break; case 2: pre = PM3_READ_DAC_REG(PM3RD_DClk2PreScale); feedback = PM3_READ_DAC_REG(PM3RD_DClk2FeedbackScale); post = PM3_READ_DAC_REG(PM3RD_DClk2PostScale); DPRINTK(2, "DClk2 parameter: Pre: %ld, Feedback: %ld, Post: %ld ; giving pixclock: %ld\n", pre, feedback, post, PM3_SCALE_TO_CLOCK(pre, feedback, post)); break; case 1: pre = PM3_READ_DAC_REG(PM3RD_DClk1PreScale); feedback = PM3_READ_DAC_REG(PM3RD_DClk1FeedbackScale); post = PM3_READ_DAC_REG(PM3RD_DClk1PostScale); DPRINTK(2, "DClk1 parameter: Pre: %ld, Feedback: %ld, Post: %ld ; giving pixclock: %ld\n", pre, feedback, post, PM3_SCALE_TO_CLOCK(pre, feedback, post)); break; case 0: pre = PM3_READ_DAC_REG(PM3RD_DClk0PreScale); feedback = PM3_READ_DAC_REG(PM3RD_DClk0FeedbackScale); post = PM3_READ_DAC_REG(PM3RD_DClk0PostScale); DPRINTK(2, "DClk0 parameter: Pre: %ld, Feedback: %ld, Post: %ld ; giving pixclock: %ld\n", pre, feedback, post, PM3_SCALE_TO_CLOCK(pre, feedback, post)); break; default: pre = feedback = post = 0; DPRINTK(1, "Unknowk D clock used : %ld\n", clockused); break; } curpar->pixclock = PM3_SCALE_TO_CLOCK(pre, feedback, post); pixsize1 = PM3ByApertureMode_PIXELSIZE_MASK & (PM3_READ_REG(PM3ByAperture1Mode)); pixsize2 = PM3ByApertureMode_PIXELSIZE_MASK & (PM3_READ_REG(PM3ByAperture2Mode)); DASSERT((pixsize1 == pixsize2), "pixsize the same in both aperture\n"); if (pixsize1 & PM3ByApertureMode_PIXELSIZE_32BIT) curpar->depth = 32; else if (pixsize1 & PM3ByApertureMode_PIXELSIZE_16BIT) { curpar->depth = 16; } else curpar->depth = 8; /* not sure if I need to add one on the next ; it give better result with */ curpar->htotal = pm3fb_Unshiftbpp(l_fb_info, curpar->depth, 1 + PM3_READ_REG(PM3HTotal)); curpar->hsend = pm3fb_Unshiftbpp(l_fb_info, curpar->depth, PM3_READ_REG(PM3HsEnd)); curpar->hsstart = pm3fb_Unshiftbpp(l_fb_info, curpar->depth, PM3_READ_REG(PM3HsStart)); curpar->hbend = pm3fb_Unshiftbpp(l_fb_info, curpar->depth, PM3_READ_REG(PM3HbEnd)); curpar->stride = pm3fb_Unshiftbpp(l_fb_info, curpar->depth, PM3_READ_REG(PM3ScreenStride)); curpar->vtotal = 1 + PM3_READ_REG(PM3VTotal); curpar->vsend = 1 + PM3_READ_REG(PM3VsEnd); curpar->vsstart = 1 + PM3_READ_REG(PM3VsStart); curpar->vbend = PM3_READ_REG(PM3VbEnd); curpar->video = PM3_READ_REG(PM3VideoControl); curpar->base = PM3_READ_REG(PM3ScreenBase); curpar->width = curpar->htotal - curpar->hbend; /* make virtual == displayed resolution */ curpar->height = curpar->vtotal - curpar->vbend; DPRINTK(2, "Found : %d * %d, %d Khz, stride is %08x\n", curpar->width, curpar->height, curpar->pixclock, curpar->stride);}static unsigned long pm3fb_size_memory(struct pm3fb_info *l_fb_info){ unsigned long memsize = 0, tempBypass, i, temp1, temp2; u16 subvendor, subdevice; pm3fb_timing_result ptr; DTRACE; l_fb_info->fb_size = 64 * 1024 * 1024; /* pm3 aperture always 64 MB */ pm3fb_mapIO(l_fb_info); /* temporary map IO */ DASSERT((l_fb_info->vIOBase != NULL), "IO successfully mapped before mem detect\n"); DASSERT((l_fb_info->v_fb != NULL), "FB successfully mapped before mem detect\n"); /* card-specific stuff, *before* accessing *any* FB memory */ 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))) { i = 0; l_fb_info->board_type = 0; while ((cardbase[i].cardname[0]) && !(l_fb_info->board_type)) { if ((cardbase[i].subvendor == subvendor) && (cardbase[i].subdevice == subdevice) && (cardbase[i].func == PCI_FUNC(l_fb_info->dev->devfn))) { DPRINTK(2, "Card #%ld is an %s\n", l_fb_info->board_num, cardbase[i].cardname); if (cardbase[i].specific_setup) cardbase[i].specific_setup(l_fb_info); l_fb_info->board_type = i; } i++; } if (!l_fb_info->board_type) { DPRINTK(1, "Card #%ld is an unknown 0x%04x / 0x%04x\n", l_fb_info->board_num, subvendor, subdevice); } } else { printk(KERN_ERR "pm3fb: Error: pci_read_config_word failed, board #%ld\n", l_fb_info->board_num); } if (printtimings) pm3fb_show_cur_timing(l_fb_info); /* card-specific setup is done, we preserve the final memory timing for future reference */ if ((ptr = pm3fb_preserve_memory_timings(l_fb_info)) == pm3fb_timing_problem) { /* memory timings were wrong ! oops.... */ return(0); } tempBypass = PM3_READ_REG(PM3MemBypassWriteMask); DPRINTK(2, "PM3MemBypassWriteMask was: 0x%08lx\n", tempBypass); PM3_SLOW_WRITE_REG(PM3MemBypassWriteMask, 0xFFFFFFFF); /* pm3 split up memory, replicates, and do a lot of nasty stuff IMHO ;-) */ for (i = 0; i < 32; i++) {#ifdef KERNEL_2_2#ifdef MUST_BYTESWAP writel(__swab32(i * 0x00345678), (l_fb_info->v_fb + (i * 1048576)));#else writel(i * 0x00345678, (l_fb_info->v_fb + (i * 1048576)));#endif mb();#ifdef MUST_BYTESWAP temp1 = __swab32(readl((l_fb_info->v_fb + (i * 1048576))));#else temp1 = readl((l_fb_info->v_fb + (i * 1048576)));#endif#endif /* KERNEL_2_2 */#if (defined KERNEL_2_4) || (defined KERNEL_2_5) fb_writel(i * 0x00345678, (l_fb_info->v_fb + (i * 1048576))); mb(); temp1 = fb_readl((l_fb_info->v_fb + (i * 1048576)));#endif /* KERNEL_2_4 or KERNEL_2_5 */ /* Let's check for wrapover, write will fail at 16MB boundary */ if (temp1 == (i * 0x00345678)) memsize = i; else break; } DPRINTK(2, "First detect pass already got %ld MB\n", memsize + 1); if (memsize == i) { for (i = 0; i < 32; i++) { /* Clear first 32MB ; 0 is 0, no need to byteswap */ writel(0x0000000, (l_fb_info->v_fb + (i * 1048576))); mb(); } for (i = 32; i < 64; i++) {#ifdef KERNEL_2_2#ifdef MUST_BYTESWAP writel(__swab32(i * 0x00345678), (l_fb_info->v_fb + (i * 1048576)));#else writel(i * 0x00345678, (l_fb_info->v_fb + (i * 1048576)));#endif mb();#ifdef MUST_BYTESWAP temp1 = __swab32(readl ((l_fb_info->v_fb + (i * 1048576)))); temp2 = __swab32(readl ((l_fb_info->v_fb + ((i - 32) * 1048576))));#else temp1 = readl((l_fb_info->v_fb + (i * 1048576))); temp2 = readl((l_fb_info->v_fb + ((i - 32) * 1048576)));#endif#endif /* KERNEL_2_2 */#if (defined KERNEL_2_4) || (defined KERNEL_2_5) fb_writel(i * 0x00345678, (l_fb_info->v_fb + (i * 1048576))); mb(); temp1 = fb_readl((l_fb_info->v_fb + (i * 1048576))); temp2 = fb_readl((l_fb_info->v_fb + ((i - 32) * 1048576)));#endif /* KERNEL_2_4 or KERNEL_2_5 */ if ((temp1 == (i * 0x00345678)) && (temp2 == 0)) /* different value, different RAM... */ memsize = i; else break; } } DPRINTK(2, "Second detect pass got %ld MB\n", memsize + 1); PM3_SLOW_WRITE_REG(PM3MemBypassWriteMask, tempBypass); pm3fb_unmapIO(l_fb_info); memsize = 1048576 * (memsize + 1); DPRINTK(2, "Returning 0x%08lx bytes\n", memsize); if (forcesize[l_fb_info->board_num] && ((forcesize[l_fb_info->board_num] * 1048576) != memsize)) { printk(KERN_WARNING "pm3fb: mismatch between probed (%ld MB) and specified (%hd MB) memory size, using SPECIFIED !\n", memsize, forcesize[l_fb_info->board_num]); memsize = 1048576 * forcesize[l_fb_info->board_num];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -