⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sis_main.c

📁 移植到2410开发板上的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
	sisfb_heap_size = sisfb_heap_end - sisfb_heap_start;#ifdef CONFIG_FB_SIS_315	cmdq_baseport =	    (unsigned long *) (ivideo.mmio_vbase + MMIO_QUEUE_PHYBASE);	write_port =	    (unsigned long *) (ivideo.mmio_vbase + MMIO_QUEUE_WRITEPORT);	read_port = (unsigned long *) (ivideo.mmio_vbase + MMIO_QUEUE_READPORT);	DPRINTK ("AGP base: 0x%p, read: 0x%p, write: 0x%p\n", cmdq_baseport,		 read_port, write_port);	agp_size = COMMAND_QUEUE_AREA_SIZE;#ifndef AGPOFF	agp_info = vmalloc (sizeof (agp_kern_info));	memset ((void *) agp_info, 0x00, sizeof (agp_kern_info));	agp_copy_info (agp_info);	agp_backend_acquire ();	agp =	    agp_allocate_memory (COMMAND_QUEUE_AREA_SIZE / PAGE_SIZE,				 AGP_NORMAL_MEMORY);	if (agp == NULL) {		DPRINTK ("Allocate AGP buffer failed.\n");		agp_enabled = 0;	} else {		if (agp_bind_memory (agp, agp->pg_start) != 0) {			DPRINTK ("AGP : can not bind memory\n");			agp_enabled = 0;		} else {			agp_enable (0);		}	}#else	agp_enabled = 0;#endif	if (agp_enabled)		cmd_type = AGP_CMD_QUEUE;	else if (sisfb_heap_size >= COMMAND_QUEUE_AREA_SIZE)		cmd_type = VM_CMD_QUEUE;	else		cmd_type = MMIO_CMD;	switch (agp_size) {	case 0x80000:		temp = SIS_CMD_QUEUE_SIZE_512k;		break;	case 0x100000:		temp = SIS_CMD_QUEUE_SIZE_1M;		break;	case 0x200000:		temp = SIS_CMD_QUEUE_SIZE_2M;		break;	case 0x400000:		temp = SIS_CMD_QUEUE_SIZE_4M;		break;	}	switch (cmd_type) {	case AGP_CMD_QUEUE:#ifndef AGPOFF		DPRINTK ("AGP buffer base:0x%lx, offset:0x%x, size is %dK\n",			 agp_info->aper_base, agp->physical, agp_size / 1024);		agp_phys = agp_info->aper_base + agp->physical;		vgawb (CRTC_ADR, IND_SIS_AGP_IO_PAD);		vgawb (CRTC_DATA, 0);		vgawb (CRTC_DATA, SIS_AGP_2X);		vgawb (SEQ_ADR, IND_SIS_CMDQUEUE_THRESHOLD);		vgawb (SEQ_DATA, COMMAND_QUEUE_THRESHOLD);		vgawb (SEQ_ADR, IND_SIS_CMDQUEUE_SET);		vgawb (SEQ_DATA, SIS_CMD_QUEUE_RESET);		*write_port = *read_port;		temp |= SIS_AGP_CMDQUEUE_ENABLE;		vgawb (SEQ_ADR, IND_SIS_CMDQUEUE_SET);		vgawb (SEQ_DATA, temp);		*cmdq_baseport = agp_phys;		sisfb_caps |= AGP_CMD_QUEUE_CAP;#endif		break;	case VM_CMD_QUEUE:		sisfb_heap_end -= COMMAND_QUEUE_AREA_SIZE;		sisfb_heap_size -= COMMAND_QUEUE_AREA_SIZE;		vgawb (SEQ_ADR, IND_SIS_CMDQUEUE_THRESHOLD);		vgawb (SEQ_DATA, COMMAND_QUEUE_THRESHOLD);		vgawb (SEQ_ADR, IND_SIS_CMDQUEUE_SET);		vgawb (SEQ_DATA, SIS_CMD_QUEUE_RESET);		*write_port = *read_port;		temp |= SIS_VRAM_CMDQUEUE_ENABLE;		vgawb (SEQ_ADR, IND_SIS_CMDQUEUE_SET);		vgawb (SEQ_DATA, temp);		*cmdq_baseport = ivideo.video_size - COMMAND_QUEUE_AREA_SIZE;		sisfb_caps |= VM_CMD_QUEUE_CAP;		DPRINTK ("VM Cmd Queue offset = 0x%lx, size is %dK\n",			 *cmdq_baseport, COMMAND_QUEUE_AREA_SIZE / 1024);		break;	default:		vgawb (SEQ_ADR, IND_SIS_CMDQUEUE_SET);		vgawb (SEQ_DATA, SIS_MMIO_CMD_ENABLE);		break;	}#endif#ifdef CONFIG_FB_SIS_300	if (sisfb_heap_size >= TURBO_QUEUE_AREA_SIZE) {		unsigned int tqueue_pos;		u8 tq_state;		tqueue_pos =		    (ivideo.video_size - TURBO_QUEUE_AREA_SIZE) / (64 * 1024);		temp = (u8) (tqueue_pos & 0xff);		vgawb (SEQ_ADR, IND_SIS_TURBOQUEUE_SET);		tq_state = vgarb (SEQ_DATA);		tq_state |= 0xf0;		tq_state &= 0xfc;		tq_state |= (u8) (tqueue_pos >> 8);		vgawb (SEQ_DATA, tq_state);		vgawb (SEQ_ADR, IND_SIS_TURBOQUEUE_ADR);		vgawb (SEQ_DATA, temp);		sisfb_caps |= TURBO_QUEUE_CAP;		sisfb_heap_end -= TURBO_QUEUE_AREA_SIZE;		sisfb_heap_size -= TURBO_QUEUE_AREA_SIZE;		DPRINTK ("Turbo Queue: start at 0x%lx, size is %dK\n",			 sisfb_heap_end, TURBO_QUEUE_AREA_SIZE / 1024);	}#endif	if (sisfb_heap_size >= HW_CURSOR_AREA_SIZE) {		sisfb_heap_end -= HW_CURSOR_AREA_SIZE;		sisfb_heap_size -= HW_CURSOR_AREA_SIZE;		sisfb_hwcursor_vbase = sisfb_heap_end;		sisfb_caps |= HW_CURSOR_CAP;		DPRINTK ("Hardware Cursor: start at 0x%lx, size is %dK\n",			 sisfb_heap_end, HW_CURSOR_AREA_SIZE / 1024);	}	sisfb_heap.poha_chain = NULL;	sisfb_heap.poh_freelist = NULL;	poh = sisfb_poh_new_node ();	if (poh == NULL)		return 1;	poh->poh_next = &sisfb_heap.oh_free;	poh->poh_prev = &sisfb_heap.oh_free;	poh->size = sisfb_heap_end - sisfb_heap_start + 1;	poh->offset = sisfb_heap_start - (unsigned long) ivideo.video_vbase;	DPRINTK ("sisfb:Heap start:0x%p, end:0x%p, len=%dk\n",		 (char *) sisfb_heap_start, (char *) sisfb_heap_end,		 (unsigned int) poh->size / 1024);	DPRINTK ("sisfb:First Node offset:0x%x, size:%dk\n",		 (unsigned int) poh->offset, (unsigned int) poh->size / 1024);	sisfb_heap.oh_free.poh_next = poh;	sisfb_heap.oh_free.poh_prev = poh;	sisfb_heap.oh_free.size = 0;	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: VMEM Allocation Failed\n");	} else {		DPRINTK ("sisfb: VMEM Allocation Successed : 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:		cr30 = (SIS_VB_OUTPUT_CRT2 | SIS_SIMULTANEOUS_VIEW_ENABLE);		cr31 |= SIS_DRIVER_MODE;		break;	case DISPTYPE_LCD:		cr30 = (SIS_VB_OUTPUT_LCD | SIS_SIMULTANEOUS_VIEW_ENABLE);		cr31 |= SIS_DRIVER_MODE;		break;	case DISPTYPE_TV:		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;		/*karl */		if (sisfb_tvmode == 1)			cr31 |= 0x1;		if (sisfb_tvmode == 2)			cr31 &= ~0x1;		break;	default:		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);	vgawb (CRTC_ADR, IND_SIS_SCRATCH_REG_CR33);	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, IND_SIS_CRT2_WRITE_ENABLE);			// ~Eden Chen			vgawb (VB_PART1_DATA, 0x1);			// Eden Chen for Debug			// ~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) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -