📄 sis_main.c
字号:
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); } return 0;}static void sisfb_set_disp (int con, struct fb_var_screeninfo *var){ struct fb_fix_screeninfo fix; struct display *display; struct display_switch *sw; u32 flags; if (con >= 0) display = &fb_display[con]; else display = &disp; sisfb_get_fix (&fix, con, 0); display->screen_base = ivideo.video_vbase; display->visual = fix.visual; display->type = fix.type; display->type_aux = fix.type_aux; display->ypanstep = fix.ypanstep; display->ywrapstep = fix.ywrapstep; display->line_length = fix.line_length; display->next_line = fix.line_length; display->can_soft_blank = 0; display->inverse = sisfb_inverse; display->var = *var; save_flags (flags); switch (ivideo.video_bpp) {#ifdef FBCON_HAS_CFB8 case 8: sw = &fbcon_cfb8; break;#endif#ifdef FBCON_HAS_CFB16 case 15: case 16: sw = &fbcon_cfb16; display->dispsw_data = fbcon_cmap.cfb16; break;#endif#ifdef FBCON_HAS_CFB24 case 24: sw = &fbcon_cfb24; display->dispsw_data = fbcon_cmap.cfb24; break;#endif#ifdef FBCON_HAS_CFB32 case 32: sw = &fbcon_cfb32; display->dispsw_data = fbcon_cmap.cfb32; break;#endif default: sw = &fbcon_dummy; return; } memcpy (&sisfb_sw, sw, sizeof (*sw)); display->dispsw = &sisfb_sw; restore_flags (flags); display->scrollmode = SCROLL_YREDRAW; sisfb_sw.bmove = fbcon_redraw_bmove;}static void sisfb_do_install_cmap (int con, struct fb_info *info){ if (con != currcon) return; if (fb_display[con].cmap.len) fb_set_cmap (&fb_display[con].cmap, 1, sis_setcolreg, info); else fb_set_cmap (fb_default_cmap (video_cmap_len), 1, sis_setcolreg, info);}/* --------------- Chip-dependent Routines --------------------------- */#ifdef CONFIG_FB_SIS_300 /* for SiS 300/630/540/730 */static int sisfb_get_dram_size_300 (void){ struct pci_dev *pdev = NULL; int pdev_valid = 0; u8 pci_data, reg; u16 nbridge_id; switch (ivideo.chip) { case SIS_540: nbridge_id = PCI_DEVICE_ID_SI_540; break; case SIS_630: nbridge_id = PCI_DEVICE_ID_SI_630; break; case SIS_730: nbridge_id = PCI_DEVICE_ID_SI_730; break; default: nbridge_id = 0; break; } if (nbridge_id == 0) { vgawb (SEQ_ADR, IND_SIS_DRAM_SIZE); ivideo.video_size = ((unsigned int) ((vgarb (SEQ_DATA) & SIS_DRAM_SIZE_MASK) + 1) << 20); } else { pci_for_each_dev (pdev) { if ((pdev->vendor == PCI_VENDOR_ID_SI) && (pdev->device == nbridge_id)) { //&& (pdev->device == PCI_DEVICE_ID_SI_630)) { pci_read_config_byte (pdev, IND_BRI_DRAM_STATUS, &pci_data); pci_data = (pci_data & BRI_DRAM_SIZE_MASK) >> 4; ivideo.video_size = (unsigned int) (1 << (pci_data + 21)); pdev_valid = 1; reg = SIS_DATA_BUS_64 << 6; vgawb (SEQ_ADR, IND_SIS_DRAM_SIZE); switch (pci_data) { case BRI_DRAM_SIZE_2MB: reg |= SIS_DRAM_SIZE_2MB; break; case BRI_DRAM_SIZE_4MB: reg |= SIS_DRAM_SIZE_4MB; break; case BRI_DRAM_SIZE_8MB: reg |= SIS_DRAM_SIZE_8MB; break; case BRI_DRAM_SIZE_16MB: reg |= SIS_DRAM_SIZE_16MB; break; case BRI_DRAM_SIZE_32MB: reg |= SIS_DRAM_SIZE_32MB; break; case BRI_DRAM_SIZE_64MB: reg |= SIS_DRAM_SIZE_64MB; break; } vgawb (SEQ_DATA, reg); break; } } if (!pdev_valid) return -1; } return 0;}static void sisfb_detect_VB_connect_300(void){ u8 sr16, sr17, cr32, temp; vgawb (SEQ_ADR, IND_SIS_SCRATCH_REG_17); sr17 = vgarb (SEQ_DATA); vgawb (CRTC_ADR, IND_SIS_SCRATCH_REG_CR32); cr32 = vgarb (CRTC_DATA); ivideo.TV_plug = ivideo.TV_type = 0; if ((sr17 & 0x0F) && (ivideo.chip != SIS_300)) { if ((sr17 & 0x01) && !sisfb_crt1off) sisfb_crt1off = 0; else { if (sr17 & 0x0E) sisfb_crt1off = 1; else sisfb_crt1off = 0; } if (sr17 & 0x08) ivideo.disp_state = DISPTYPE_CRT2; else if (sr17 & 0x02) ivideo.disp_state = DISPTYPE_LCD; else if (sr17 & 0x04) { ivideo.disp_state = DISPTYPE_TV; if (sr17 & 0x20) ivideo.TV_plug = TVPLUG_SVIDEO; else if (sr17 & 0x10) ivideo.TV_plug = TVPLUG_COMPOSITE; vgawb (SEQ_ADR, IND_SIS_SCRATCH_REG_16); sr16 = vgarb (SEQ_DATA); if (sr16 & 0x20) ivideo.TV_type = TVMODE_PAL; else ivideo.TV_type = TVMODE_NTSC; } else ivideo.disp_state = 0; } else { if ((cr32 & SIS_CRT1) && !sisfb_crt1off) sisfb_crt1off = 0; else { if (cr32 & 0x5F) sisfb_crt1off = 1; else sisfb_crt1off = 0; } if (cr32 & SIS_VB_CRT2) ivideo.disp_state = DISPTYPE_CRT2; else if (cr32 & SIS_VB_LCD) ivideo.disp_state = DISPTYPE_LCD; else if (cr32 & SIS_VB_TV) { ivideo.disp_state = DISPTYPE_TV; if (cr32 & SIS_VB_HIVISION) { ivideo.TV_type = TVMODE_HIVISION; ivideo.TV_plug = TVPLUG_SVIDEO; } else if (cr32 & SIS_VB_SVIDEO) ivideo.TV_plug = TVPLUG_SVIDEO; else if (cr32 & SIS_VB_COMPOSITE) ivideo.TV_plug = TVPLUG_COMPOSITE; else if (cr32 & SIS_VB_SCART) ivideo.TV_plug = TVPLUG_SCART; if (ivideo.TV_type == 0) { // Eden Chen //temp = *((u8 *)(sishw_ext.VirtualRomBase+0x52)); //if (temp&0x40) { // temp=*((u8 *)(sishw_ext.VirtualRomBase+0x53)); //} else { vgawb (SEQ_ADR, IND_SIS_POWER_ON_TRAP); temp = vgarb (SEQ_DATA); //} // ~Eden Chen if (temp & 0x01) ivideo.TV_type = TVMODE_PAL; else ivideo.TV_type = TVMODE_NTSC; } } else ivideo.disp_state = 0; }}static void sisfb_get_VB_type_300 (void){ u8 reg; if (ivideo.chip != SIS_300) { if (!sisfb_has_VB_300 ()) { vgawb (CRTC_ADR, IND_SIS_SCRATCH_REG_CR37); reg = vgarb (CRTC_DATA); switch ((reg & SIS_EXTERNAL_CHIP_MASK) >> 1) { case SIS_EXTERNAL_CHIP_SIS301: ivideo.hasVB = HASVB_301; break; case SIS_EXTERNAL_CHIP_LVDS: ivideo.hasVB = HASVB_LVDS; break; case SIS_EXTERNAL_CHIP_TRUMPION: ivideo.hasVB = HASVB_TRUMPION; break; case SIS_EXTERNAL_CHIP_LVDS_CHRONTEL: ivideo.hasVB = HASVB_LVDS_CHRONTEL; break; case SIS_EXTERNAL_CHIP_CHRONTEL: ivideo.hasVB = HASVB_CHRONTEL; break; default: break; } } } else { sisfb_has_VB_300 (); } //sishw_ext.hasVB = ivideo.hasVB;}static int sisfb_has_VB_300 (void){ // Eden Chen //u8 sr38, sr39, vb_chipid; u8 vb_chipid; //vgawb(SEQ_ADR, IND_SIS_POWER_ON_TRAP); //sr38 = vgarb(SEQ_DATA); //vgawb(SEQ_ADR, IND_SIS_POWER_ON_TRAP2); //sr39 = vgarb(SEQ_DATA); vgawb (VB_PART4_ADR, 0x0); vb_chipid = vgarb (VB_PART4_DATA); switch (vb_chipid) { case 0x01: ivideo.hasVB = HASVB_301; break; case 0x02: ivideo.hasVB = HASVB_302; break; case 0x03: ivideo.hasVB = HASVB_303; break; default: ivideo.hasVB = HASVB_NONE; return FALSE; } return TRUE;}#endif /* CONFIG_FB_SIS_300 */#ifdef CONFIG_FB_SIS_315 /* for SiS 315H/315 */static int sisfb_get_dram_size_315 (void){#ifdef LINUXBIOS struct pci_dev *pdev = NULL; int pdev_valid = 0; u8 pci_data;#endif u8 reg = 0; if (ivideo.chip == SIS_550) {#ifdef LINUXBIOS pci_for_each_dev (pdev) { if ((pdev->vendor == PCI_VENDOR_ID_SI) && (pdev->device == PCI_DEVICE_ID_SI_550)) { pci_read_config_byte (pdev, IND_BRI_DRAM_STATUS, &pci_data); pci_data = (pci_data & BRI_DRAM_SIZE_MASK) >> 4; ivideo.video_size = (unsigned int) (1 << (pci_data + 21)); pdev_valid = 1; vgawb (SEQ_ADR, IND_SIS_DRAM_SIZE); reg = vgarb (SEQ_DATA) & 0xC0; switch (pci_data) { //case BRI_DRAM_SIZE_2MB: // reg |= (SIS315_DRAM_SIZE_2MB << 4); break; case BRI_DRAM_SIZE_4MB: reg |= SIS550_DRAM_SIZE_4MB; break; case BRI_DRAM_SIZE_8MB: reg |= SIS550_DRAM_SIZE_8MB; break; case BRI_DRAM_SIZE_16MB: reg |= SIS550_DRAM_SIZE_16MB; break; case BRI_DRAM_SIZE_32MB: reg |= SIS550_DRAM_SIZE_32MB; break; case BRI_DRAM_SIZE_64MB: reg |= SIS550_DRAM_SIZE_64MB; break; /* case BRI_DRAM_SIZE_128MB: reg |= (SIS315_DRAM_SIZE_128MB << 4); break; */ } /* TODO : set Dual channel and bus width bits here */ vgawb (SEQ_DATA, reg); break; } } if (!pdev_valid) return -1;#else vgawb (SEQ_ADR, IND_SIS_DRAM_SIZE); reg = vgarb (SEQ_DATA); switch (reg & SIS550_DRAM_SIZE_MASK) { case SIS550_DRAM_SIZE_4MB: ivideo.video_size = 0x400000; break; case SIS550_DRAM_SIZE_8MB: ivideo.video_size = 0x800000; break; case SIS550_DRAM_SIZE_16MB: ivideo.video_size = 0x1000000; break; case SIS550_DRAM_SIZE_24MB: ivideo.video_size = 0x1800000; break; case SIS550_DRAM_SIZE_32MB: ivideo.video_size = 0x2000000; break; case SIS550_DRAM_SIZE_64MB: ivideo.video_size = 0x4000000; break; case SIS550_DRAM_SIZE_96MB: ivideo.video_size = 0x6000000; break; case SIS550_DRAM_SIZE_128MB: ivideo.video_size = 0x8000000; break; case SIS550_DRAM_SIZE_256MB: ivideo.video_size = 0x10000000; break; default: return -1; }#endif return 0; } else { vgawb (SEQ_ADR, IND_SIS_DRAM_SIZE); reg = vgarb (SEQ_DATA); switch ((reg & SIS315_DRAM_SIZE_MASK) >> 4) { case SIS315_DRAM_SIZE_2MB: ivideo.video_size = 0x200000; break; case SIS315_DRAM_SIZE_4MB: ivideo.video_size = 0x400000; break; case SIS315_DRAM_SIZE_8MB: ivideo.video_size = 0x800000; break; case SIS315_DRAM_SIZE_16MB: ivideo.video_size = 0x1000000; break; case SIS315_DRAM_SIZE_32MB: ivideo.video_size = 0x2000000; break; case SIS315_DRAM_SIZE_64MB: ivideo.video_size = 0x4000000; break; case SIS315_DRAM_SIZE_128MB: ivideo.video_size = 0x8000000; break; default: return -1; } } reg &= SIS315_DUAL_CHANNEL_MASK; reg >>= 2; switch (reg) { case SIS315_SINGLE_CHANNEL_2_RANK: ivideo.video_size <<= 1; break; case SIS315_DUAL_CHANNEL_1_RANK: ivideo.video_size <<= 1; break; } return 0;}static void sisfb_detect_VB_connect_315 (void){ u8 cr32, temp; vgawb (CRTC_ADR, IND_SIS_SCRATCH_REG_CR32); cr32 = vgarb (CRTC_DATA); ivideo.TV_plug = ivideo.TV_type = 0; if ((cr32 & SIS_CRT1) && !sisfb_crt1off) sisfb_crt1off = 0; else { if (cr32 & 0x5F) sisfb_crt1off = 1; else sisfb_crt1off = 0; } if (cr32 & SIS_VB_CRT2) ivideo.disp_state = DISPTYPE_CRT2; else if (cr32 & SIS_VB_LCD) ivideo.disp_state = DISPTYPE_LCD; else if (cr32 & SIS_VB_TV) { ivideo.disp_state = DISPTYPE_TV; if (cr32 & SIS_VB_HIVISION) { ivideo.TV_type = TVMODE_HIVISION; ivideo.TV_plug = TVPLUG_SVIDEO; } else if (cr32 & SIS_VB_SVIDEO) ivideo.TV_plug = TVPLUG_SVIDEO; else if (cr32 & SIS_VB_COMPOSITE) ivideo.TV_plug = TVPLUG_COMPOSITE; else if (cr32 & SIS_VB_SCART) ivideo.TV_plug = TVPLUG_SCART; if (ivideo.TV_type == 0) { vgawb (SEQ_ADR, IND_SIS_POWER_ON_TRAP); temp = vgarb (SEQ_DATA); if (temp & 0x01) ivideo.TV_type = TVMODE_PAL; else ivideo.TV_type = TVMODE_NTSC; } } else ivideo.disp_state = 0;}static void sisfb_get_VB_type_315 (void){ u8 vb_chipid; vgawb (VB_PART4_ADR, 0x0); vb_chipid = vgarb (VB_PART4_DATA); switch (vb_chipid) { case 0x01: ivideo.hasVB = HASVB_301; break; case 0x02: ivideo.hasVB = HASVB_302; break; case 0x03: ivideo.hasVB = HASVB_303; break; default: ivideo.hasVB = HASVB_NONE; } // Eden Chen //sishw_ext.hasVB = ivideo.hasVB; // ~Eden Chen}#endif /* CONFIG_FB_SIS_315 *//* --------------------- Heap Routines ------------------------------- */static int sisfb_heap_init (void){ SIS_OH *poh; u8 temp = 0;#ifdef CONFIG_FB_SIS_315 int agp_enabled = 1; u32 agp_size; unsigned long *cmdq_baseport = 0; unsigned long *read_port = 0; unsigned long *write_port = 0; SIS_CMDTYPE cmd_type;#ifndef AGPOFF agp_kern_info *agp_info; agp_memory *agp; u32 agp_phys;#endif#endif /*karl:10/01/2001 */ if (!sisfb_mem) { if (ivideo.video_size > 0x800000) sisfb_heap_start = (unsigned long) ivideo.video_vbase + 0x800000; else sisfb_heap_start = (unsigned long) ivideo.video_vbase + 0x400000; } else sisfb_heap_start = (unsigned long) (ivideo.video_vbase + sisfb_mem * 0x100000); sisfb_heap_end = (unsigned long) ivideo.video_vbase + ivideo.video_size;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -