📄 sis_main.c
字号:
return 1;}static void sisfb_blank (int blank, struct fb_info *info){ u8 reg; vgawb (CRTC_ADR, 0x17); reg = vgarb (CRTC_DATA); if (blank > 0) reg &= 0x7f; else reg |= 0x80; vgawb (CRTC_ADR, 0x17); vgawb (CRTC_DATA, reg);}int sisfb_setup (char *options){ char *this_opt; fb_info.fontname[0] = '\0'; ivideo.refresh_rate = 0; if (!options || !*options) return 0; for (this_opt = strtok (options, ","); this_opt; this_opt = strtok (NULL, ",")) { if (!*this_opt) continue; if (!strcmp (this_opt, "inverse")) { sisfb_inverse = 1; fb_invert_cmaps (); } else if (!strncmp (this_opt, "font:", 5)) { strcpy (fb_info.fontname, this_opt + 5); } else if (!strncmp (this_opt, "mode:", 5)) { sisfb_search_mode (this_opt + 5); } else if (!strncmp (this_opt, "vrate:", 6)) { ivideo.refresh_rate = simple_strtoul (this_opt + 6, NULL, 0); } else if (!strncmp (this_opt, "off", 3)) { sisfb_off = 1; } else if (!strncmp (this_opt, "crt1off", 7)) { sisfb_crt1off = 1; } else if (!strncmp (this_opt, "filter:", 7)) { filter = (int) simple_strtoul (this_opt + 7, NULL, 0); } /*karl */ else if (!strncmp (this_opt, "tvmode:", 7)) { if (!strncmp (this_opt + 7, "pal", 3)) sisfb_tvmode = 1; if (!strncmp (this_opt + 7, "ntsc", 4)) sisfb_tvmode = 2; } /*karl:10/01/2001 */ else if (!strncmp (this_opt, "mem:", 4)) { sisfb_mem = simple_strtoul (this_opt + 4, NULL, 0); } else DPRINTK ("invalid parameter %s\n", this_opt); } return 0;}int __init sisfb_init (void){ struct pci_dev *pdev = NULL; struct board *b; int pdev_valid = 0; //unsigned long rom_vbase; u32 reg32; u16 reg16; u8 reg; int nRes; outb (0x77, 0x80); if (sisfb_off) return -ENXIO; pci_for_each_dev (pdev) { for (b = sisdev_list; b->vendor; b++) { if ((b->vendor == pdev->vendor) && (b->device == pdev->device)) { pdev_valid = 1; strcpy (fb_info.modename, b->name); ivideo.chip_id = pdev->device; pci_read_config_byte (pdev, PCI_REVISION_ID, &ivideo.revision_id); pci_read_config_word (pdev, PCI_COMMAND, ®16); // Eden Chen //sishw_ext.uRevisionID = ivideo.revision_id; sishw_ext.jChipRevision = ivideo.revision_id; // ~Eden Chen sisvga_enabled = reg16 & 0x1; break; } } if (pdev_valid) break; } if (!pdev_valid) return -1; // Eden Chen switch (ivideo.chip_id) { case PCI_DEVICE_ID_SI_300: ivideo.chip = SIS_300; sisvga_engine = SIS_300_VGA; break; case PCI_DEVICE_ID_SI_630_VGA: { sisfb_set_reg4 (0xCF8, 0x80000000); reg32 = sisfb_get_reg3 (0xCFC); if (reg32 == 0x07301039) { ivideo.chip = SIS_730; strcpy (fb_info.modename, "SIS 730"); } else ivideo.chip = SIS_630; sisvga_engine = SIS_300_VGA; break; } case PCI_DEVICE_ID_SI_540_VGA: ivideo.chip = SIS_540; sisvga_engine = SIS_300_VGA; break; case PCI_DEVICE_ID_SI_315H: ivideo.chip = SIS_315H; sisvga_engine = SIS_315_VGA; break; case PCI_DEVICE_ID_SI_315: ivideo.chip = SIS_315; sisvga_engine = SIS_315_VGA; break; case PCI_DEVICE_ID_SI_315PRO: ivideo.chip = SIS_315PRO; sisvga_engine = SIS_315_VGA; break; case PCI_DEVICE_ID_SI_550_VGA: ivideo.chip = SIS_550; sisvga_engine = SIS_315_VGA; break; } // Eden Chen //sishw_ext.jChipID = ivideo.chip; sishw_ext.jChipType = ivideo.chip; // for Debug if ((sishw_ext.jChipType == SIS_315PRO) || (sishw_ext.jChipType == SIS_315)) sishw_ext.jChipType = SIS_315H; // ~Eden Chen DPRINTK ("%s is used as %s device(VGA Engine %d).\n", fb_info.modename, sisvga_enabled ? "primary" : "secondary", sisvga_engine); ivideo.video_base = pci_resource_start (pdev, 0); ivideo.mmio_base = pci_resource_start (pdev, 1); // Eden Chen //sishw_ext.IOAddress = (unsigned short) ivideo.vga_base // = pci_resource_start(pdev, 2) + 0x30; sishw_ext.ulIOAddress = (unsigned short) ivideo.vga_base = pci_resource_start (pdev, 2) + 0x30; // ~Eden Chen sisfb_mmio_size = pci_resource_len (pdev, 1); if (!sisvga_enabled) if (pci_enable_device (pdev)) return -EIO; vgawb (SEQ_ADR, IND_SIS_PASSWORD); vgawb (SEQ_DATA, SIS_PASSWORD);#ifdef LINUXBIOS#ifdef CONFIG_FB_SIS_300 if (sisvga_engine == SIS_300_VGA) { vgawb (SEQ_ADR, 0x28); vgawb (SEQ_DATA, 0x37); vgawb (SEQ_ADR, 0x29); vgawb (SEQ_DATA, 0x61); vgawb (SEQ_ADR, IND_SIS_SCRATCH_REG_1A); reg = vgarb (SEQ_DATA); reg |= SIS_SCRATCH_REG_1A_MASK; vgawb (SEQ_DATA, reg); }#endif#ifdef CONFIG_FB_SIS_315 if (ivideo.chip == SIS_550) { vgawb (SEQ_ADR, 0x28); vgawb (SEQ_DATA, 0x5A); vgawb (SEQ_ADR, 0x29); vgawb (SEQ_DATA, 0x64); vgawb (CRTC_ADR, 0x3A); vgawb (CRTC_DATA, 0x00); }#endif#endif if (sisvga_engine == SIS_315_VGA) { switch (ivideo.chip) { case SIS_315H: case SIS_315: sishw_ext.bIntegratedMMEnabled = TRUE; break; case SIS_550: // Eden Chen //vgawb(SEQ_ADR, IND_SIS_SCRATCH_REG_1A); //reg = vgarb(SEQ_DATA); //if (reg & SIS_SCRATCH_REG_1A_MASK) // sishw_ext.bIntegratedMMEnabled = TRUE; //else // sishw_ext.bIntegratedMMEnabled = FALSE; //for Debug sishw_ext.bIntegratedMMEnabled = TRUE; // ~Eden Chen break; default: break; } } else if (sisvga_engine == SIS_300_VGA) { if (ivideo.chip == SIS_300) { sishw_ext.bIntegratedMMEnabled = TRUE; } else { vgawb (SEQ_ADR, IND_SIS_SCRATCH_REG_1A); reg = vgarb (SEQ_DATA); if (reg & SIS_SCRATCH_REG_1A_MASK) sishw_ext.bIntegratedMMEnabled = TRUE; else sishw_ext.bIntegratedMMEnabled = FALSE; } } // Eden Chen sishw_ext.pDevice = NULL; sishw_ext.pjVirtualRomBase = NULL; sishw_ext.pjCustomizedROMImage = NULL; sishw_ext.bSkipDramSizing = 0; sishw_ext.pQueryVGAConfigSpace = &sisfb_query_VGA_config_space; sishw_ext.pQueryNorthBridgeSpace = &sisfb_query_north_bridge_space; strcpy (sishw_ext.szVBIOSVer, "0.84"); sishw_ext.pSR = vmalloc (sizeof (SIS_DSReg) * SR_BUFFER_SIZE); if (sishw_ext.pSR == NULL) printk (KERN_DEBUG "Allocated SRReg space fail.\n"); sishw_ext.pSR[0].jIdx = sishw_ext.pSR[0].jVal = 0xFF; sishw_ext.pCR = vmalloc (sizeof (SIS_DSReg) * CR_BUFFER_SIZE); if (sishw_ext.pCR == NULL) printk (KERN_DEBUG "Allocated CRReg space fail.\n"); sishw_ext.pCR[0].jIdx = sishw_ext.pCR[0].jVal = 0xFF; // ~Eden Chen #ifdef CONFIG_FB_SIS_300 if (sisvga_engine == SIS_300_VGA) { if (!sisvga_enabled) { // Eden Chen sishw_ext.pjVideoMemoryAddress = ioremap (ivideo.video_base, 0x2000000); //SiSInit300(&sishw_ext); SiSInit (&sishw_ext); vgawb (SEQ_ADR, IND_SIS_PASSWORD); vgawb (SEQ_DATA, SIS_PASSWORD); // ~Eden Chen }#ifdef LINUXBIOS else { // Eden Chen sishw_ext.pjVideoMemoryAddress = ioremap (ivideo.video_base, 0x2000000); //SiSInit300(&sishw_ext); SiSInit (&sishw_ext); vgawb (SEQ_ADR, IND_SIS_PASSWORD); vgawb (SEQ_DATA, SIS_PASSWORD); // ~Eden Chen } vgawb (SEQ_ADR, 0x7); reg = vgarb (SEQ_DATA); reg |= 0x10; vgawb (SEQ_DATA, reg);#endif sisfb_get_dram_size_300 (); }#endif #ifdef CONFIG_FB_SIS_315 if (sisvga_engine == SIS_315_VGA) { if (!sisvga_enabled) { /* Mapping Max FB Size for 315 Init */ // Eden Chen //sishw_ext.VirtualVideoMemoryAddress sishw_ext.pjVideoMemoryAddress = ioremap (ivideo.video_base, 0x8000000); //SiSInit310(&sishw_ext); SiSInit (&sishw_ext); vgawb (SEQ_ADR, IND_SIS_PASSWORD); vgawb (SEQ_DATA, SIS_PASSWORD); sishw_ext.bSkipDramSizing = TRUE; vgawb (SEQ_ADR, 0x13); sishw_ext.pSR[0].jIdx = 0x13; sishw_ext.pSR[0].jVal = vgarb (SEQ_DATA); vgawb (SEQ_ADR, 0x14); sishw_ext.pSR[1].jIdx = 0x14; sishw_ext.pSR[1].jVal = vgarb (SEQ_DATA); sishw_ext.pSR[2].jIdx = 0xFF; sishw_ext.pSR[2].jVal = 0xFF; // Eden Chen }#ifdef LINUXBIOS else { sishw_ext.pjVideoMemoryAddress = ioremap (ivideo.video_base, 0x8000000); SiSInit (&sishw_ext); vgawb (SEQ_ADR, IND_SIS_PASSWORD); vgawb (SEQ_DATA, SIS_PASSWORD); sishw_ext.bSkipDramSizing = TRUE; vgawb (SEQ_ADR, 0x13); sishw_ext.pSR[0].jIdx = 0x13; sishw_ext.pSR[0].jVal = vgarb (SEQ_DATA); vgawb (SEQ_ADR, 0x14); sishw_ext.pSR[1].jIdx = 0x14; sishw_ext.pSR[1].jVal = vgarb (SEQ_DATA); sishw_ext.pSR[2].jIdx = 0xFF; sishw_ext.pSR[2].jVal = 0xFF; }#endif sisfb_get_dram_size_315 (); }#endif //Eden Chen vgawb (SEQ_ADR, IND_SIS_PCI_ADDRESS_SET); reg = vgarb (SEQ_DATA); reg |= SIS_PCI_ADDR_ENABLE; reg |= SIS_MEM_MAP_IO_ENABLE; vgawb (SEQ_DATA, reg); vgawb (SEQ_ADR, IND_SIS_MODULE_ENABLE); reg = vgarb (SEQ_DATA); reg |= SIS_ENABLE_2D; vgawb (SEQ_DATA, reg); //~Eden Chen // Eden Chen sishw_ext.ulVideoMemorySize = ivideo.video_size; // ~Eden Chen if (!request_mem_region (ivideo.video_base, ivideo.video_size, "sisfb FB")) { printk (KERN_ERR "sisfb: cannot reserve frame buffer memory\n"); return -ENODEV; } if (!request_mem_region (ivideo.mmio_base, sisfb_mmio_size, "sisfb MMIO")) { printk (KERN_ERR "sisfb: cannot reserve MMIO region\n"); release_mem_region (ivideo.video_base, ivideo.video_size); return -ENODEV; } // Eden Chen //sishw_ext.VirtualVideoMemoryAddress = ivideo.video_vbase sishw_ext.pjVideoMemoryAddress = ivideo.video_vbase = ioremap (ivideo.video_base, ivideo.video_size); // Eden Chen ivideo.mmio_vbase = ioremap (ivideo.mmio_base, sisfb_mmio_size); printk (KERN_INFO "sisfb: framebuffer at 0x%lx, mapped to 0x%p, size %dk\n", ivideo.video_base, ivideo.video_vbase, ivideo.video_size / 1024); printk (KERN_INFO "sisfb: MMIO at 0x%lx, mapped to 0x%p, size %ldk\n", ivideo.mmio_base, ivideo.mmio_vbase, sisfb_mmio_size / 1024); #ifdef CONFIG_FB_SIS_300 if (sisvga_engine == SIS_300_VGA) { sisfb_get_VB_type_300 (); if (ivideo.hasVB != HASVB_NONE) { sisfb_detect_VB_connect_300 (); } }#endif#ifdef CONFIG_FB_SIS_315 if (sisvga_engine == SIS_315_VGA) { sisfb_get_VB_type_315 (); if (ivideo.hasVB != HASVB_NONE) { sisfb_detect_VB_connect_315 (); } }#endif // Eden Chensishw_ext.ujVBChipID = VB_CHIP_UNKNOWN;sishw_ext.usExternalChip = 0; switch (ivideo.hasVB) { case HASVB_301: /*karl */ vgawb (VB_PART4_ADR, 0x01); reg = vgarb (VB_PART4_DATA); if ((reg != 0xB1) && (reg != 0xB0)) sishw_ext.ujVBChipID = VB_CHIP_301; else sishw_ext.ujVBChipID = VB_CHIP_301B; break; case HASVB_302: sishw_ext.ujVBChipID = VB_CHIP_302; break; case HASVB_303: sishw_ext.ujVBChipID = VB_CHIP_303; break; case HASVB_LVDS: sishw_ext.usExternalChip = 0x1; break; case HASVB_TRUMPION: sishw_ext.usExternalChip = 0x2; break; case HASVB_CHRONTEL: sishw_ext.usExternalChip = 0x4; break; case HASVB_LVDS_CHRONTEL: sishw_ext.usExternalChip = 0x5; break; default: break; } // ~Eden Chen if (ivideo.disp_state & DISPTYPE_DISP2) { if (sisfb_crt1off) ivideo.disp_state |= DISPMODE_SINGLE; else ivideo.disp_state |= (DISPMODE_MIRROR | DISPTYPE_CRT1); } else ivideo.disp_state = DISPMODE_SINGLE | DISPTYPE_CRT1; if (ivideo.disp_state & DISPTYPE_LCD) { vgawb (CRTC_ADR, IND_SIS_LCD_PANEL); reg = vgarb (CRTC_DATA); // Eden Chen switch (reg) { case SIS_LCD_PANEL_800X600: sishw_ext.ulCRT2LCDType = LCD_800x600; break; case SIS_LCD_PANEL_1024X768: sishw_ext.ulCRT2LCDType = LCD_1024x768; break; case SIS_LCD_PANEL_1280X1024: sishw_ext.ulCRT2LCDType = LCD_1280x1024; break; case SIS_LCD_PANEL_640X480: sishw_ext.ulCRT2LCDType = LCD_640x480; break; case SIS_LCD_PANEL_1280X960: sishw_ext.ulCRT2LCDType = LCD_1280x960; break; default: sishw_ext.ulCRT2LCDType = LCD_1024x768; break; } // ~Eden Chen } if (sisfb_mode_idx >= 0) sisfb_validate_mode (); if (sisfb_mode_idx < 0) { switch (ivideo.disp_state & DISPTYPE_DISP2) { case DISPTYPE_LCD: sisfb_mode_idx = DEFAULT_LCDMODE; break; case DISPTYPE_TV: sisfb_mode_idx = DEFAULT_TVMODE; break; default: sisfb_mode_idx = DEFAULT_MODE; break; } } sisfb_mode_no = sisbios_mode[sisfb_mode_idx].mode_no; if (ivideo.refresh_rate != 0) sisfb_search_refresh_rate (ivideo.refresh_rate); if (sisfb_rate_idx == 0) { sisfb_rate_idx = sisbios_mode[sisfb_mode_idx].rate_idx; ivideo.refresh_rate = 60; } ivideo.video_bpp = sisbios_mode[sisfb_mode_idx].bpp; ivideo.video_vwidth = ivideo.video_width = sisbios_mode[sisfb_mode_idx].xres; ivideo.video_vheight = ivideo.video_height = sisbios_mode[sisfb_mode_idx].yres; ivideo.org_x = ivideo.org_y = 0; video_linelength = ivideo.video_width * (ivideo.video_bpp >> 3); printk (KERN_INFO "sisfb: mode is %dx%dx%d, linelength=%d\n", ivideo.video_width, ivideo.video_height, ivideo.video_bpp, video_linelength); // Eden Chen // Check interface correction For Debug DPRINTK ("VM Adr=0x%p\n", sishw_ext.pjVideoMemoryAddress); DPRINTK ("VM Size=%ldK\n", sishw_ext.ulVideoMemorySize / 1024); DPRINTK ("IO Adr=0x%lx\n", sishw_ext.ulIOAddress); DPRINTK ("Chip=%d\n", sishw_ext.jChipType); DPRINTK ("ChipRevision=%d\n", sishw_ext.jChipRevision); DPRINTK ("VBChip=%d\n", sishw_ext.ujVBChipID); DPRINTK ("ExtVB=%d\n", sishw_ext.usExternalChip); DPRINTK ("LCD=%ld\n", sishw_ext.ulCRT2LCDType); DPRINTK ("bIntegratedMMEnabled=%d\n", sishw_ext.bIntegratedMMEnabled); // ~Eden Chen sisfb_pre_setmode (); if (SiSSetMode (&sishw_ext, sisfb_mode_no) == 0) { DPRINTK ("set mode[0x%x]: failed\n", sisfb_mode_no); return -1; } vgawb (SEQ_ADR, IND_SIS_PASSWORD); vgawb (SEQ_DATA, SIS_PASSWORD); // Eden Chen sisfb_post_setmode (); sisfb_crtc_to_var (&default_var); fb_info.changevar = NULL; fb_info.node = -1; fb_info.fbops = &sisfb_ops; fb_info.disp = &disp; fb_info.switch_con = &sisfb_switch; fb_info.updatevar = &sisfb_update_var; fb_info.blank = &sisfb_blank; fb_info.flags = FBINFO_FLAG_DEFAULT; sisfb_set_disp (-1, &default_var); if (sisfb_heap_init ()) { DPRINTK ("sisfb: Failed to enable offscreen heap\n"); } /*H.C. */ nRes = mtrr_add ((unsigned int) ivideo.video_base, (unsigned int) ivideo.video_size, MTRR_TYPE_WRCOMB, 1); v
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -