📄 sis_main.c
字号:
sisfb_heap.max_freesize = poh->size; sisfb_heap.oh_used.poh_next = &sisfb_heap.oh_used; sisfb_heap.oh_used.poh_prev = &sisfb_heap.oh_used; sisfb_heap.oh_used.size = SENTINEL; return 0;}static SIS_OH *sisfb_poh_new_node(void){ int i; unsigned long cOhs; SIS_OHALLOC *poha; SIS_OH *poh; if (sisfb_heap.poh_freelist == NULL) { poha = kmalloc(OH_ALLOC_SIZE, GFP_KERNEL); poha->poha_next = sisfb_heap.poha_chain; sisfb_heap.poha_chain = poha; cOhs = (OH_ALLOC_SIZE - sizeof(SIS_OHALLOC)) / sizeof(SIS_OH) + 1; poh = &poha->aoh[0]; for (i = cOhs - 1; i != 0; i--) { poh->poh_next = poh + 1; poh = poh + 1; } poh->poh_next = NULL; sisfb_heap.poh_freelist = &poha->aoh[0]; } poh = sisfb_heap.poh_freelist; sisfb_heap.poh_freelist = poh->poh_next; return (poh);}static SIS_OH *sisfb_poh_allocate(unsigned long size){ SIS_OH *pohThis; SIS_OH *pohRoot; int bAllocated = 0; if (size > sisfb_heap.max_freesize) { DPRINTK("sisfb: Can't allocate %dk size on offscreen\n", (unsigned int) size / 1024); return (NULL); } pohThis = sisfb_heap.oh_free.poh_next; while (pohThis != &sisfb_heap.oh_free) { if (size <= pohThis->size) { bAllocated = 1; break; } pohThis = pohThis->poh_next; } if (!bAllocated) { DPRINTK("sisfb: Can't allocate %dk size on offscreen\n", (unsigned int) size / 1024); return (NULL); } if (size == pohThis->size) { pohRoot = pohThis; sisfb_delete_node(pohThis); } else { pohRoot = sisfb_poh_new_node(); if (pohRoot == NULL) { return (NULL); } pohRoot->offset = pohThis->offset; pohRoot->size = size; pohThis->offset += size; pohThis->size -= size; } sisfb_heap.max_freesize -= size; pohThis = &sisfb_heap.oh_used; sisfb_insert_node(pohThis, pohRoot); return (pohRoot);}static void sisfb_delete_node(SIS_OH *poh){ SIS_OH *poh_prev; SIS_OH *poh_next; poh_prev = poh->poh_prev; poh_next = poh->poh_next; poh_prev->poh_next = poh_next; poh_next->poh_prev = poh_prev; return;}static void sisfb_insert_node(SIS_OH *pohList, SIS_OH *poh){ SIS_OH *pohTemp; pohTemp = pohList->poh_next; pohList->poh_next = poh; pohTemp->poh_prev = poh; poh->poh_prev = pohList; poh->poh_next = pohTemp;}static SIS_OH *sisfb_poh_free(unsigned long base){ SIS_OH *pohThis; SIS_OH *poh_freed; SIS_OH *poh_prev; SIS_OH *poh_next; unsigned long ulUpper; unsigned long ulLower; int foundNode = 0; poh_freed = sisfb_heap.oh_used.poh_next; while (poh_freed != &sisfb_heap.oh_used) { if (poh_freed->offset == base) { foundNode = 1; break; } poh_freed = poh_freed->poh_next; } if (!foundNode) return (NULL); sisfb_heap.max_freesize += poh_freed->size; poh_prev = poh_next = NULL; ulUpper = poh_freed->offset + poh_freed->size; ulLower = poh_freed->offset; pohThis = sisfb_heap.oh_free.poh_next; while (pohThis != &sisfb_heap.oh_free) { if (pohThis->offset == ulUpper) { poh_next = pohThis; } else if ((pohThis->offset + pohThis->size) == ulLower) { poh_prev = pohThis; } pohThis = pohThis->poh_next; } sisfb_delete_node(poh_freed); if (poh_prev && poh_next) { poh_prev->size += (poh_freed->size + poh_next->size); sisfb_delete_node(poh_next); sisfb_free_node(poh_freed); sisfb_free_node(poh_next); return (poh_prev); } if (poh_prev) { poh_prev->size += poh_freed->size; sisfb_free_node(poh_freed); return (poh_prev); } if (poh_next) { poh_next->size += poh_freed->size; poh_next->offset = poh_freed->offset; sisfb_free_node(poh_freed); return (poh_next); } sisfb_insert_node(&sisfb_heap.oh_free, poh_freed); return (poh_freed);}static void sisfb_free_node(SIS_OH *poh){ if (poh == NULL) { return; } poh->poh_next = sisfb_heap.poh_freelist; sisfb_heap.poh_freelist = poh; return;}void sis_malloc(struct sis_memreq *req){ SIS_OH *poh; poh = sisfb_poh_allocate(req->size); if (poh == NULL) { req->offset = 0; req->size = 0; DPRINTK("sisfb: Video RAM allocation failed\n"); } else { DPRINTK("sisfb: Video RAM allocation succeeded: 0x%p\n", (char *) (poh->offset + (unsigned long) ivideo.video_vbase)); req->offset = poh->offset; req->size = poh->size; }}void sis_free(unsigned long base){ SIS_OH *poh; poh = sisfb_poh_free(base); if (poh == NULL) { DPRINTK("sisfb: sisfb_poh_free() failed at base 0x%x\n", (unsigned int) base); }}/* ------------------ SetMode Routines ------------------------------- */static void sisfb_pre_setmode(void){ u8 cr30 = 0, cr31 = 0; vgawb(CRTC_ADR, 0x31); cr31 = vgarb(CRTC_DATA) & ~0x60; switch (ivideo.disp_state & DISPTYPE_DISP2) { case DISPTYPE_CRT2: printk(KERN_INFO "sisfb: CRT2 type is VGA\n"); cr30 = (SIS_VB_OUTPUT_CRT2 | SIS_SIMULTANEOUS_VIEW_ENABLE); cr31 |= SIS_DRIVER_MODE; break; case DISPTYPE_LCD: printk(KERN_INFO "sisfb: CRT2 type is LCD\n"); cr30 = (SIS_VB_OUTPUT_LCD | SIS_SIMULTANEOUS_VIEW_ENABLE); cr31 |= SIS_DRIVER_MODE; break; case DISPTYPE_TV: printk(KERN_INFO "sisfb: CRT2 type is TV\n"); if (ivideo.TV_type == TVMODE_HIVISION) cr30 = (SIS_VB_OUTPUT_HIVISION | SIS_SIMULTANEOUS_VIEW_ENABLE); else if (ivideo.TV_plug == TVPLUG_SVIDEO) cr30 = (SIS_VB_OUTPUT_SVIDEO | SIS_SIMULTANEOUS_VIEW_ENABLE); else if (ivideo.TV_plug == TVPLUG_COMPOSITE) cr30 = (SIS_VB_OUTPUT_COMPOSITE | SIS_SIMULTANEOUS_VIEW_ENABLE); else if (ivideo.TV_plug == TVPLUG_SCART) cr30 = (SIS_VB_OUTPUT_SCART | SIS_SIMULTANEOUS_VIEW_ENABLE); cr31 |= SIS_DRIVER_MODE; cr31 &= ~0x04; /* TW: No Slavemode by default */ /*karl*/ if (sisfb_tvmode == 1 || ivideo.TV_type == TVMODE_PAL) cr31 |= 0x1; if (sisfb_tvmode == 2 || ivideo.TV_type == TVMODE_NTSC) cr31 &= ~0x1; break; default: /* CRT2 disable */ printk(KERN_INFO "sisfb: CRT2 is disabled\n"); cr30 = 0x00; cr31 |= (SIS_DRIVER_MODE | SIS_VB_OUTPUT_DISABLE); } vgawb(CRTC_ADR, IND_SIS_SCRATCH_REG_CR30); vgawb(CRTC_DATA, cr30); vgawb(CRTC_ADR, IND_SIS_SCRATCH_REG_CR31); vgawb(CRTC_DATA, cr31); /* printk(KERN_INFO "sisfb: 0x30=%x 0x31=%x\n", cr30, cr31); */ vgawb(CRTC_ADR, IND_SIS_SCRATCH_REG_CR33);/* if (ivideo.disp_state & DISPTYPE_CRT2) { sisfb_rate_idx &= 0x0F; sisfb_rate_idx |= (sisfb_rate_idx << 4); vgawb(CRTC_DATA, sisfb_rate_idx); } else { vgawb(CRTC_DATA, sisfb_rate_idx & 0x0F); }*/ vgawb(CRTC_DATA, sisfb_rate_idx & 0x0F);}static void sisfb_post_setmode(void){ u8 reg; vgawb(CRTC_ADR, 0x17); reg = vgarb(CRTC_DATA); if ((ivideo.hasVB == HASVB_LVDS) || (ivideo.hasVB == HASVB_LVDS_CHRONTEL)) if (ivideo.video_bpp == 8) sisfb_crt1off = 0; if (sisfb_crt1off) reg &= ~0x80; else reg |= 0x80; vgawb(CRTC_DATA, reg); vgawb(SEQ_ADR, IND_SIS_RAMDAC_CONTROL); reg = vgarb(SEQ_DATA); reg &= ~0x04; vgawb(SEQ_DATA, reg); if ((ivideo.disp_state & DISPTYPE_TV) && (ivideo.hasVB == HASVB_301)) { /*karl*/ vgawb(VB_PART4_ADR,0x01); reg = vgarb(VB_PART4_DATA); if ((reg != 0xB1) && (reg != 0xB0)) /*301B Revision ID*/ { // Eden Chen switch (ivideo.video_width) { case 320: filter_tb = (ivideo.TV_type == TVMODE_NTSC) ? 4 : 12; break; case 640: filter_tb = (ivideo.TV_type == TVMODE_NTSC) ? 5 : 13; break; case 720: filter_tb = (ivideo.TV_type == TVMODE_NTSC) ? 6 : 14; break; case 800: filter_tb = (ivideo.TV_type == TVMODE_NTSC) ? 7 : 15; break; default: filter = -1; break; } // ~Eden Chen // Eden Chen //vgawb(VB_PART1_ADR, 0x24); vgawb(VB_PART1_ADR, sisfb_CRT2_write_enable); // ~Eden Chen vgawb(VB_PART1_DATA, 0x1); // Eden Chen for Debug/* if (ivideo.chip == SIS_550 || ivideo.chip == SIS_650) { vgawb(VB_PART1_ADR, 0x2D); vgawb(VB_PART1_DATA, 0x11); if (sisfb_mode_no == 0x63) { vgawb(VB_PART2_ADR, 0x15); vgawb(VB_PART2_DATA, 0x0A); vgawb(VB_PART2_ADR, 0x28); vgawb(VB_PART2_DATA, 0x62); vgawb(VB_PART2_ADR, 0x2D); vgawb(VB_PART2_DATA, 0xF8); vgawb(VB_PART2_ADR, 0x2E); vgawb(VB_PART2_DATA, 0x14); vgawb(VB_PART2_ADR, 0x33); vgawb(VB_PART2_DATA, 0x8A); vgawb(VB_PART2_ADR, 0x35); vgawb(VB_PART2_DATA, 0xF4); vgawb(VB_PART2_ADR, 0x36); vgawb(VB_PART2_DATA, 0x10); vgawb(VB_PART2_ADR, 0x37); vgawb(VB_PART2_DATA, 0x1C); vgawb(VB_PART2_ADR, 0x38); vgawb(VB_PART2_DATA, 0x00); vgawb(VB_PART2_ADR, 0x44); vgawb(VB_PART2_DATA, 0x29); vgawb(VB_PART2_ADR, 0x45); vgawb(VB_PART2_DATA, 0x54); vgawb(VB_PART4_ADR, 0x0D); vgawb(VB_PART4_DATA, 0x0F); vgawb(VB_PART4_ADR, 0x0F); vgawb(VB_PART4_DATA, 0x0F); vgawb(VB_PART4_ADR, 0x10); vgawb(VB_PART4_DATA, 0x83); vgawb(VB_PART4_ADR, 0x11); vgawb(VB_PART4_DATA, 0xFF); vgawb(VB_PART4_ADR, 0x18); vgawb(VB_PART4_DATA, 0x20); vgawb(VB_PART4_ADR, 0x19); vgawb(VB_PART4_DATA, 0x52); } }*/ // ~Eden Chen if (ivideo.TV_type == TVMODE_NTSC) { vgawb(VB_PART2_ADR, 0x3A); reg = vgarb(VB_PART2_DATA); reg &= 0x1F; vgawb(VB_PART2_DATA, reg); if (ivideo.TV_plug == TVPLUG_SVIDEO) { vgawb(VB_PART2_ADR, 0x30); reg = vgarb(VB_PART2_DATA); reg &= 0xDF; vgawb(VB_PART2_DATA, reg); } else if (ivideo.TV_plug == TVPLUG_COMPOSITE) { vgawb(VB_PART2_ADR, 0x30); reg = vgarb(VB_PART2_DATA); reg |= 0x20; vgawb(VB_PART2_DATA, reg); switch (ivideo.video_width) { case 640: vgawb(VB_PART2_ADR, 0x35); vgawb(VB_PART2_DATA, 0xEB); vgawb(VB_PART2_ADR, 0x36); vgawb(VB_PART2_DATA, 0x04); vgawb(VB_PART2_ADR, 0x37); vgawb(VB_PART2_DATA, 0x25); vgawb(VB_PART2_ADR, 0x38); vgawb(VB_PART2_DATA, 0x18); break; case 720: vgawb(VB_PART2_ADR, 0x35); vgawb(VB_PART2_DATA, 0xEE); vgawb(VB_PART2_ADR, 0x36); vgawb(VB_PART2_DATA, 0x0C); vgawb(VB_PART2_ADR, 0x37); vgawb(VB_PART2_DATA, 0x22); vgawb(VB_PART2_ADR, 0x38); vgawb(VB_PART2_DATA, 0x08); break; case 800: vgawb(VB_PART2_ADR, 0x35); vgawb(VB_PART2_DATA, 0xEB); vgawb(VB_PART2_ADR, 0x36); vgawb(VB_PART2_DATA, 0x15); vgawb(VB_PART2_ADR, 0x37); vgawb(VB_PART2_DATA, 0x25); vgawb(VB_PART2_ADR, 0x38); vgawb(VB_PART2_DATA, 0xF6); break; } } } else if (ivideo.TV_type == TVMODE_PAL) { vgawb(VB_PART2_ADR, 0x3A); reg = vgarb(VB_PART2_DATA); reg &= 0x1F; vgawb(VB_PART2_DATA, reg); if (ivideo.TV_plug == TVPLUG_SVIDEO) { vgawb(VB_PART2_ADR, 0x30); reg = vgarb(VB_PART2_DATA); reg &= 0xDF; vgawb(VB_PART2_DATA, reg); } else if (ivideo.TV_plug == TVPLUG_COMPOSITE) { vgawb(VB_PART2_ADR, 0x30); reg = vgarb(VB_PART2_DATA); reg |= 0x20; vgawb(VB_PART2_DATA, reg); switch (ivideo.video_width) { case 640: vgawb(VB_PART2_ADR, 0x35); vgawb(VB_PART2_DATA, 0xF1); vgawb(VB_PART2_ADR, 0x36); vgawb(VB_PART2_DATA, 0xF7); vgawb(VB_PART2_ADR, 0x37); vgawb(VB_PART2_DATA, 0x1F); vgawb(VB_PART2_ADR, 0x38); vgawb(VB_PART2_DATA, 0x32); break; case 720: vgawb(VB_PART2_ADR, 0x35); vgawb(VB_PART2_DATA, 0xF3); vgawb(VB_PART2_ADR, 0x36); vgawb(VB_PART2_DATA, 0x00); vgawb(VB_PART2_ADR, 0x37); vgawb(VB_PART2_DATA, 0x1D); vgawb(VB_PART2_ADR, 0x38); vgawb(VB_PART2_DATA, 0x20); break; case 800: vgawb(VB_PART2_ADR, 0x35); vgawb(VB_PART2_DATA, 0xFC); vgawb(VB_PART2_ADR, 0x36); vgawb(VB_PART2_DATA, 0xFB); vgawb(VB_PART2_ADR, 0x37); vgawb(VB_PART2_DATA, 0x14); vgawb(VB_PART2_ADR, 0x38); vgawb(VB_PART2_DATA, 0x2A); break; } } } // Eden if ((filter >= 0) && (filter <=7)) { DPRINTK("FilterTable[%d]-%d: %02x %02x %02x %02x\n", filter_tb, filter, sis_TV_filter[filter_tb].filter[filter][0], sis_TV_filter[filter_tb].filter[filter][1], sis_TV_filter[filter_tb].filter[filter][2], sis_TV_filter[filter_tb].filter[filter][3] ); vgawb(VB_PART2_ADR, 0x35); vgawb(VB_PART2_DATA, sis_TV_filter[filter_tb].filter[filter][0]); vgawb(VB_PART2_ADR, 0x36); vgawb(VB_PART2_DATA, sis_TV_filter[filter_tb].filter[filter][1]); vgawb(VB_PART2_ADR, 0x37); vgawb(VB_PART2_DATA, sis_TV_filter[filter_tb].filter[filter][2]); vgawb(VB_PART2_ADR, 0x38); vgawb(VB_PART2_DATA, sis_TV_filter[filter_tb].filter[filter][3]); } // ~Eden
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -