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

📄 cyberpro.c

📁 移植到2410开发板上的源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
	cyberpro_grphw8(REG_BANK, REG_BANK_X, dp);	cyberpro_grphw24(X_V2_VID_MEM_START, wi->src.offset, dp);	cyberpro_grphw16(X_V2_VID_SRC_WIDTH, pitch | ((phase << 4) & 0xf000), dp);	cyberpro_grphw8 (X_V2_VID_SRC_WIN_WIDTH, phase, dp);	cyberpro_grphw8(REG_BANK, REG_BANK_Y, dp);	cyberpro_grphw8(Y_V2_VID_FMT, wi->vid_fmt, dp);}/* * Set v2 window */static voidcyberpro_v2_set_win(struct cyberpro_vidinfo *dp, struct win_info *wi){	unsigned int xscale, yscale;	unsigned int xoff, yoff;	/*	 * Note: the offset does not appear to be influenced by	 * hardware scrolling.	 */	xoff = yoff = 0;	xoff += wi->dst.x;	yoff += wi->dst.y;	xscale = (wi->src.width  * 4096) / wi->dst.width;	yscale = (wi->src.height * 4096) / wi->dst.height;	cyberpro_grphw8(REG_BANK, REG_BANK_X, dp);	cyberpro_grphw16(X_V2_X_START,	xoff, dp);	cyberpro_grphw16(X_V2_X_END,	xoff + wi->dst.width, dp);	cyberpro_grphw16(X_V2_Y_START,	yoff, dp);	cyberpro_grphw16(X_V2_Y_END,	yoff + wi->dst.height, dp);	cyberpro_grphw8(REG_BANK, REG_BANK_Y, dp);	cyberpro_grphw16(Y_V2_DDA_X_INC, xscale, dp);	cyberpro_grphw16(Y_V2_DDA_Y_INC, yscale, dp);}/* * Enable or disable the 2nd overlay window.  Note that for anything * useful to be displayed, we must have capture enabled. */static voidcyberpro_v2_ctl(struct cyberpro_vidinfo *dp, struct win_info *wi, int on){	if (on)		wi->vid_disp_ctl1 |= EXT_VID_DISP_CTL1_ENABLE_WINDOW;	else		wi->vid_disp_ctl1 &= ~EXT_VID_DISP_CTL1_ENABLE_WINDOW;	cyberpro_grphw8(REG_BANK, REG_BANK_Y, dp);	cyberpro_grphw8(Y_V2_VID_DISP_CTL1, wi->vid_disp_ctl1, dp);}/*--------------------------- X2 Overlay Window ----------------------------- * Initialise 3rd overlay window (guesswork) */static voidcyberpro_x2_init(struct cyberpro_vidinfo *dp, struct win_info *wi){	wi->vid_fmt       = EXT_VID_FMT_YUV422;	wi->vid_disp_ctl1 = 0x40;	wi->vid_misc_ctl1 = 0;	cyberpro_grphw8(REG_BANK, REG_BANK_K, dp);	cyberpro_grphw8 (K_X2_VID_DISP_CTL1, wi->vid_disp_ctl1, dp);	cyberpro_grphw16(K_X2_DDA_X_INIT, 0x0800, dp);	cyberpro_grphw16(K_X2_DDA_Y_INIT, 0x0800, dp);}/* * Set the source parameters for the x2 window */static voidcyberpro_x2_set_src(struct cyberpro_vidinfo *dp, struct win_info *wi){	unsigned int phase, pitch;	pitch = (wi->src.width >> 2) & 0x0fff;	phase = (wi->src.width + 3) >> 2;	wi->vid_fmt &= ~7;	switch (wi->src.format) {	case VIDEO_PALETTE_RGB565: wi->vid_fmt |= EXT_VID_FMT_RGB565;    break;	case VIDEO_PALETTE_RGB24:  wi->vid_fmt |= EXT_VID_FMT_RGB888_24; break;	case VIDEO_PALETTE_RGB32:  wi->vid_fmt |= EXT_VID_FMT_RGB888_32; break;	case VIDEO_PALETTE_RGB555: wi->vid_fmt |= EXT_VID_FMT_RGB555;    break;	case VIDEO_PALETTE_YUV422: wi->vid_fmt |= EXT_VID_FMT_YUV422;    break;	}	cyberpro_grphw8(REG_BANK, REG_BANK_J, dp);	cyberpro_grphw24(J_X2_VID_MEM_START, wi->src.offset, dp);	cyberpro_grphw16(J_X2_VID_SRC_WIDTH, pitch | ((phase << 4) & 0xf000), dp);	cyberpro_grphw8 (J_X2_VID_SRC_WIN_WIDTH, phase, dp);	cyberpro_grphw8(REG_BANK, REG_BANK_K, dp);	cyberpro_grphw8(K_X2_VID_FMT, wi->vid_fmt, dp);}/* * Set x2 window */static voidcyberpro_x2_set_win(struct cyberpro_vidinfo *dp, struct win_info *wi){	unsigned int xscale, yscale;	unsigned int xoff, yoff;	/*	 * Note: the offset does not appear to be influenced by	 * hardware scrolling.	 */	xoff = yoff = 0;	xoff += wi->dst.x;	yoff += wi->dst.y;	xscale = (wi->src.width  * 4096) / wi->dst.width;	yscale = (wi->src.height * 4096) / wi->dst.height;	cyberpro_grphw8(REG_BANK, REG_BANK_J, dp);	cyberpro_grphw16(J_X2_X_START,	xoff, dp);	cyberpro_grphw16(J_X2_X_END,	xoff + wi->dst.width, dp);	cyberpro_grphw16(J_X2_Y_START,	yoff, dp);	cyberpro_grphw16(J_X2_Y_END,	yoff + wi->dst.height, dp);	cyberpro_grphw8(REG_BANK, REG_BANK_K, dp);	cyberpro_grphw16(K_X2_DDA_X_INC, xscale, dp);	cyberpro_grphw16(K_X2_DDA_Y_INC, yscale, dp);}/* * Enable or disable the 3rd overlay window.  Note that for anything * useful to be displayed, we must have capture enabled. */static voidcyberpro_x2_ctl(struct cyberpro_vidinfo *dp, struct win_info *wi, int on){	if (on)		wi->vid_disp_ctl1 |= EXT_VID_DISP_CTL1_ENABLE_WINDOW;	else		wi->vid_disp_ctl1 &= ~EXT_VID_DISP_CTL1_ENABLE_WINDOW;	cyberpro_grphw8(REG_BANK, REG_BANK_K, dp);	cyberpro_grphw8(K_X2_VID_DISP_CTL1, wi->vid_disp_ctl1, dp);}/* ------------------------------------------------------------------------- */#if 0static void reset_seq(struct cyberpro_vidinfo *dp){	unsigned char ext_mem_ctl = cyberpro_grphr8(0x70, dp);	cyberpro_grphw8(ext_mem_ctl | 0x80, 0x70, dp);	cyberpro_grphw8(ext_mem_ctl, 0x70, dp);}#endif#ifdef USE_MMAP/* * Buffer support */static intcyberpro_alloc_frame_buffer(struct cyberpro_vidinfo *dp,			    struct framebuf *frame){	unsigned long addr;	void *buffer;	int pgidx;	if (frame->buffer)		return 0;	/*	 * Allocate frame buffer	 */	buffer = vmalloc(NR_PAGES * PAGE_SIZE);	if (frame->buffer) {		vfree(buffer);		return 0;	}	if (!buffer)		return -ENOMEM;	printk("Buffer allocated @ %p [", buffer);	frame->buffer = buffer;	frame->dbg = 1;	/*	 * Don't leak information from the kernel.	 */	memset(buffer, 0x5a, NR_PAGES * PAGE_SIZE);	/*	 * Now, reserve all the pages, and calculate	 * each pages' bus address.	 */	addr = (unsigned long)buffer;	for (pgidx = 0; pgidx < NR_PAGES; pgidx++, addr += PAGE_SIZE) {		struct page *page;		pgd_t *pgd;		pmd_t *pmd;		pte_t *pte;		/*		 * The page should be present.  If not,		 * vmalloc has gone nuts.		 */		pgd = pgd_offset_k(addr);		if (pgd_none(*pgd))			BUG();		pmd = pmd_offset(pgd, addr);		if (pmd_none(*pmd))			BUG();		pte = pte_offset(pmd, addr);		if (!pte_present(*pte))			BUG();		page = pte_page(*pte);		frame->bus_addr[pgidx] = virt_to_bus((void *)page_address(page));		frame->pages[pgidx] = page;		SetPageReserved(page);		printk("%08lx (%08lx) ", page_address(page), frame->bus_addr[pgidx]);	}	printk("\n");	return 0;}static voidcyberpro_frames_free_one(struct cyberpro_vidinfo *dp, struct framebuf *frame){	void *buffer;	int pgidx;	frame->status = FRAME_FREE;	buffer = frame->buffer;	frame->buffer = NULL;	if (buffer) {		for (pgidx = 0; pgidx < NR_PAGES; pgidx++) {			frame->bus_addr[pgidx] = 0;			ClearPageReserved(frame->pages[pgidx]);			frame->pages[pgidx] = NULL;		}		vfree(buffer);	}}static voidcyberpro_busmaster_frame(struct cyberpro_vidinfo *dp, struct framebuf *frame){	unsigned long bus_addr;	bus_addr = frame->bus_addr[dp->bm_index];	if (frame->dbg) {		printk("Frame%d: %06x -> %08lx\n",			dp->frame_idx,			dp->bm_offset,			bus_addr);	}	cyber2000_outw(dp->bm_offset, BM_VID_ADDR_LOW);	cyber2000_outw(dp->bm_offset >> 16, BM_VID_ADDR_HIGH);	cyber2000_outw(bus_addr, BM_ADDRESS_LOW);	cyber2000_outw(bus_addr >> 16, BM_ADDRESS_HIGH);	/*	 * One page-full only	 */	cyber2000_outw(1023, BM_LENGTH);	/*	 * Load length	 */	cyber2000_outw(BM_CONTROL_INIT, BM_CONTROL);	/*	 * Enable transfer	 */	cyber2000_outw(BM_CONTROL_ENABLE|BM_CONTROL_IRQEN, BM_CONTROL);	dp->bm_offset += 1024;	dp->bm_index += 1;}static void cyberpro_busmaster_interrupt(struct cyberpro_vidinfo *dp){	struct framebuf *frame = dp->frame + dp->frame_idx;	/*	 * Disable Busmaster operations	 */	cyber2000_outw(0, BM_CONTROL);	if (frame->status == FRAME_GRABBING) {		/*		 * We are still grabbing this frame to system		 * memory.  Transfer next page if there are		 * more, or else flag this frame as complete.		 */		if (dp->bm_index < NR_PAGES)			cyberpro_busmaster_frame(dp);		else {			unsigned int idx;			frame->status = FRAME_DONE;			frame->dbg = 0;			idx = dp->frame_idx + 1;			if (idx >= NR_FRAMES)				idx = 0;			dp->frame_idx = idx;			wake_up(&dp->frame_wait);		}	}}static void cyberpro_frames_vbl(struct cyberpro_vidinfo *dp, unsigned int stat){	struct framebuf *frame = dp->frame + dp->frame_idx;	/*	 * No point capturing frames if the grabber isn't active.	 */	if (stat & EXT_ROM_UCB4GH_FREEZE)		return;	/*	 * If the next buffer is ready for grabbing,	 * set up the bus master registers for the	 * transfer.	 */	if (frame->status == FRAME_WAITING) {		frame->status = FRAME_GRABBING;		dp->bm_offset = dp->cap_mem_offset;		dp->bm_index  = 0;		cyberpro_busmaster_frame(dp, frame);	}}static void __init cyberpro_frames_init(struct cyberpro_vidinfo *dp){	unsigned int offset, maxsize;	int i;	init_waitqueue_head(&dp->frame_wait);	maxsize = 2 * dp->cap.maxwidth * dp->cap.maxheight;	dp->frame_size = PAGE_ALIGN(maxsize);	dp->frame_idx = 0;	for (i = offset = 0; i < NR_FRAMES; i++) {		dp->frame[i].offset = offset;		dp->frame[i].status = FRAME_FREE;		offset += dp->frame_size;	}}static void cyberpro_frames_free(struct cyberpro_vidinfo *dp){	int i;	dp->mmaped = 0;	/*	 * Free all frame buffers	 */	for (i = 0; i < NR_FRAMES; i++)		cyberpro_frames_free_one(dp, dp->frame + i);}#else#define cyberpro_frames_vbl(dp,stat) do { } while (0)#define cyberpro_frames_init(dp)     do { } while (0)#define cyberpro_frames_free(dp)     do { } while (0)#endif/* * CyberPro Interrupts * ------------------- * *  We don't really know how to signal an IRQ clear to the chip.  However, *  disabling and re-enabling the capture interrupt enable seems to do what *  we want. */static void cyberpro_interrupt(int nr, void *dev_id, struct pt_regs *regs){	struct cyberpro_vidinfo *dp = dev_id;	unsigned char old_grphidx;	unsigned int status;	/*	 * Save old graphics index register	 */	old_grphidx = cyberpro_readb(0x3ce, dp);	status = cyberpro_grphr8(EXT_ROM_UCB4GH, dp);	/*	 * Was it due to the Capture VSYNC?	 */	if (status & EXT_ROM_UCB4GH_INTSTAT) {		/*		 * Frob the IRQ enable bit to drop the request.		 */		cyberpro_grphw8(VFAC_CTL3, dp->vfac3 & ~VFAC_CTL3_CAP_IRQ, dp);		cyberpro_grphw8(VFAC_CTL3, dp->vfac3, dp);		cyberpro_frames_vbl(dp, status);		wake_up(&dp->vbl_wait);	}	/*	 * Restore graphics controller index	 */	cyberpro_writeb(old_grphidx, 0x3ce, dp);#ifdef USE_MMAP	/*	 * Do Bus-Master IRQ stuff	 */	if (cyber2000_inb(BM_CONTROL) & (1 << 7))		cyberpro_busmaster_interrupt(dp);#endif}static void cyberpro_capture(struct cyberpro_vidinfo *dp, int on){	DECLARE_WAITQUEUE(wait, current);	unsigned int status;	status = cyberpro_grphr8(EXT_ROM_UCB4GH, dp);	add_wait_queue(&dp->vbl_wait, &wait);	set_current_state(TASK_UNINTERRUPTIBLE);	if (!!on ^ !(status & EXT_ROM_UCB4GH_FREEZE)) {		if (on) {			schedule_timeout(40 * HZ / 1000);			dp->vfac1 &= ~(VFAC_CTL1_FREEZE_CAPTURE|VFAC_CTL1_FREEZE_CAPTURE_SYNC);			cyberpro_grphw8(VFAC_CTL1, dp->vfac1, dp);			status = cyberpro_grphr8(EXT_ROM_UCB4GH, dp);		} else {			dp->vfac1 |= VFAC_CTL1_FREEZE_CAPTURE_SYNC;			cyberpro_grphw8(VFAC_CTL1, dp->vfac1, dp);			status = cyberpro_grphr8(EXT_ROM_UCB4GH, dp);			if (!(status & EXT_ROM_UCB4GH_FREEZE))				schedule_timeout(40 * HZ / 1000);		}	}	current->state = TASK_RUNNING;	remove_wait_queue(&dp->vbl_wait, &wait);}static void cyberpro_capture_one(struct cyberpro_vidinfo *dp){	struct task_struct *tsk = current;	DECLARE_WAITQUEUE(wait, tsk);	unsigned int status;	unsigned long policy, rt_priority;	policy = tsk->policy;	rt_priority = tsk->rt_priority;	tsk->policy = SCHED_FIFO;	tsk->rt_priority = 1;	status = cyberpro_grphr8(EXT_ROM_UCB4GH, dp);	add_wait_queue(&dp->vbl_wait, &wait);	set_current_state(TASK_UNINTERRUPTIBLE);	schedule_timeout(40 * HZ / 1000);	dp->vfac1 &= ~(VFAC_CTL1_FREEZE_CAPTURE|VFAC_CTL1_FREEZE_CAPTURE_SYNC);	cyberpro_grphw8(VFAC_CTL1, dp->vfac1, dp);	status = cyberpro_grphr8(EXT_ROM_UCB4GH, dp);	set_current_state(TASK_UNINTERRUPTIBLE);	schedule_timeout(40 * HZ / 1000);	set_current_state(TASK_UNINTERRUPTIBLE);	schedule_timeout(40 * HZ / 1000);	dp->vfac1 |= VFAC_CTL1_FREEZE_CAPTURE_SYNC;	cyberpro_grphw8(VFAC_CTL1, dp->vfac1, dp);	set_current_state(TASK_UNINTERRUPTIBLE);	status = cyberpro_grphr8(EXT_ROM_UCB4GH, dp);	current->state = TASK_RUNNING;	remove_wait_queue(&dp->vbl_wait, &wait);	tsk->policy = policy;	tsk->rt_priority = rt_priority;}static void cyberpro_capture_set_win(struct cyberpro_vidinfo *dp){	unsigned int xstart, xend, ystart, yend;	xstart = 4 + dp->capt.x;	xend   = xstart + dp->capt.width;	if (dp->cap_mode1 & EXT_CAP_MODE1_8BIT) {

⌨️ 快捷键说明

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