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

📄 planb.c

📁 microwindows移植到S3C44B0的源码
💻 C
📖 第 1 页 / 共 5 页
字号:
	pb->mask = (unsigned char *)(pb->gbuf[MAX_GBUFFERS-1].status + 1);	pb->rawbuf = NULL;	pb->rawbuf_nchunks = 0;	pb->grabbing = 0;	for (i = 0; i < MAX_GBUFFERS; i++) {		gbuf_ptr	gbuf = &pb->gbuf[i];		*gbuf->status = GBUFFER_UNUSED;		gbuf->width = 0;		gbuf->height = 0;		gbuf->fmt = 0;		gbuf->norm_switch = 0;#ifndef PLANB_GSCANLINE		gbuf->lsize = 0;		gbuf->lnum = 0;#endif	}	pb->gcount = 0;	pb->suspend = 0;	pb->last_fr = -999;	pb->prev_last_fr = -999;	/* Reset DMA controllers */	planb_dbdma_stop(&pb->planb_base->ch2);	planb_dbdma_stop(&pb->planb_base->ch1);	DBG("PlanB: planb_prepare_video, dbdma cmd_buf at 0x%08x, "		"length %d.\n", (unsigned int)pb->vid_cbo.start, 2*size);	return 0;}static void planb_prepare_close(struct planb *pb){	/* make sure the dma's are idle */	planb_dbdma_stop(&pb->planb_base->ch2);	planb_dbdma_stop(&pb->planb_base->ch1);	if(pb->jump_raw != 0) {		kfree(pb->jump_raw);		pb->jump_raw = 0;	}	return;}static void planb_close_vbi(struct planb *pb){	/* FIXME: stop running DMA */	/* Make sure the DMA controller doesn't jump here anymore */	tab_cmd_dbdma(pb->vbi_cbo.jumpaddr, DBDMA_NOP, 0);	tab_cmd_dbdma(pb->vbi_cbe.jumpaddr, DBDMA_NOP, 0);	if(pb->vbi_raw != 0) {		kfree (pb->vbi_raw);		pb->vbi_raw = 0;	}	/* FIXME: deallocate VBI data buffer */	/* FIXME: restart running DMA if app. */	return;}static void planb_close_video(struct planb *pb){	int i;	/* FIXME: stop running DMA */	/* Make sure the DMA controller doesn't jump here anymore */	tab_cmd_dbdma(pb->vid_cbo.jumpaddr, DBDMA_NOP, 0);	tab_cmd_dbdma(pb->vid_cbe.jumpaddr, DBDMA_NOP, 0);/* No clipmask jumpbuffer yet  */#if 0	tab_cmd_dbdma(pb->clip_cbo.jumpaddr, DBDMA_NOP, 0);	tab_cmd_dbdma(pb->clip_cbe.jumpaddr, DBDMA_NOP, 0);#endif	if(pb->vid_raw != 0) {		kfree (pb->vid_raw);		pb->vid_raw = 0;		pb->cmd_buff_inited = 0;	}	if(pb->rawbuf) {		for (i = 0; i < pb->rawbuf_nchunks; i++) {			mem_map_unreserve(virt_to_page(pb->rawbuf[i]));			free_pages((unsigned long)pb->rawbuf[i], 0);		}		kfree(pb->rawbuf);	}	pb->rawbuf = NULL;	/* FIXME: restart running DMA if app. */	return;}/*****************************//* overlay support functions *//*****************************/static void overlay_start(struct planb *pb){	DBG("PlanB: overlay_start()\n");	if(ACTIVE & readl(&pb->planb_base->ch1.status)) {		DBG("PlanB: presumably, grabbing is in progress...\n");		planb_dbdma_stop(&pb->planb_base->ch2);		writel(pb->clip_cbo.bus, &pb->planb_base->ch2.cmdptr);		planb_dbdma_restart(&pb->planb_base->ch2);		st_le16 (&pb->vid_cbo.start->command, DBDMA_NOP);		tab_cmd_dbdma(pb->gbuf[pb->last_fr].last_cmd,			DBDMA_NOP | BR_ALWAYS, pb->vid_cbo.bus);		eieio();		pb->prev_last_fr = pb->last_fr;		pb->last_fr = -2;		if(!(ACTIVE & readl(&pb->planb_base->ch1.status))) {			IDBG("PlanB: became inactive "				"in the mean time... reactivating\n");			planb_dbdma_stop(&pb->planb_base->ch1);			writel(pb->vid_cbo.bus, &pb->planb_base->ch1.cmdptr);			planb_dbdma_restart(&pb->planb_base->ch1);		}	} else {		DBG("PlanB: currently idle, so can do whatever\n");		planb_dbdma_stop(&pb->planb_base->ch2);		planb_dbdma_stop(&pb->planb_base->ch1);		st_le32(&pb->planb_base->ch2.cmdptr, pb->clip_cbo.bus);		st_le32(&pb->planb_base->ch1.cmdptr, pb->vid_cbo.bus);		writew(DBDMA_NOP, &pb->vid_cbo.start->command);		planb_dbdma_restart(&pb->planb_base->ch2);		planb_dbdma_restart(&pb->planb_base->ch1);		pb->last_fr = -1;	}	return;}static void overlay_stop(struct planb *pb){	DBG("PlanB: overlay_stop()\n");	if(pb->last_fr == -1) {		DBG("PlanB: no grabbing, it seems...\n");		planb_dbdma_stop(&pb->planb_base->ch2);		planb_dbdma_stop(&pb->planb_base->ch1);		pb->last_fr = -999;	} else if(pb->last_fr == -2) {		unsigned int cmd_dep;		tab_cmd_dbdma(pb->gbuf[pb->prev_last_fr].cap_cmd, DBDMA_STOP, 0);		eieio();		cmd_dep = (unsigned int)readl(&pb->overlay_last1->cmd_dep);		if(overlay_is_active(pb)) {			DBG("PlanB: overlay is currently active\n");			planb_dbdma_stop(&pb->planb_base->ch2);			planb_dbdma_stop(&pb->planb_base->ch1);			if(cmd_dep != pb->vid_cbo.bus) {				writel(virt_to_bus(pb->overlay_last1),					&pb->planb_base->ch1.cmdptr);				planb_dbdma_restart(&pb->planb_base->ch1);			}		}		pb->last_fr = pb->prev_last_fr;		pb->prev_last_fr = -999;	}	return;}static void suspend_overlay(struct planb *pb){	int fr = -1;	struct dbdma_cmd last;	DBG("PlanB: suspend_overlay: %d\n", pb->suspend);	if(pb->suspend++)		return;	if(ACTIVE & readl(&pb->planb_base->ch1.status)) {		if(pb->last_fr == -2) {			fr = pb->prev_last_fr;			memcpy(&last, (void*)pb->gbuf[fr].last_cmd, sizeof(last));			tab_cmd_dbdma(pb->gbuf[fr].last_cmd, DBDMA_STOP, 0);		}		if(overlay_is_active(pb)) {			planb_dbdma_stop(&pb->planb_base->ch2);			planb_dbdma_stop(&pb->planb_base->ch1);			pb->suspended.overlay = 1;			pb->suspended.frame = fr;			memcpy(&pb->suspended.cmd, &last, sizeof(last));			return;		}	}	pb->suspended.overlay = 0;	pb->suspended.frame = fr;	memcpy(&pb->suspended.cmd, &last, sizeof(last));	return;}static void resume_overlay(struct planb *pb){	DBG("PlanB: resume_overlay: %d\n", pb->suspend);	if(pb->suspend > 1)		return;	if(pb->suspended.frame != -1) {		memcpy((void*)pb->gbuf[pb->suspended.frame].last_cmd,			&pb->suspended.cmd, sizeof(pb->suspended.cmd));	}	if(ACTIVE & readl(&pb->planb_base->ch1.status)) {		goto finish;	}	if(pb->suspended.overlay) {		DBG("PlanB: overlay being resumed\n");		st_le16 (&pb->vid_cbo.start->command, DBDMA_NOP);		st_le16 (&pb->clip_cbo.start->command, DBDMA_NOP);		/* Set command buffer addresses */		writel(virt_to_bus(pb->overlay_last1),			&pb->planb_base->ch1.cmdptr);		writel(virt_to_bus(pb->overlay_last2),			&pb->planb_base->ch2.cmdptr);		/* Start the DMA controller */		writel(PLANB_CLR(PAUSE) | PLANB_SET(RUN|WAKE),			&pb->planb_base->ch2.control);		writel(PLANB_CLR(PAUSE) | PLANB_SET(RUN|WAKE),			&pb->planb_base->ch1.control);	} else if(pb->suspended.frame != -1) {		writel(virt_to_bus(pb->gbuf[pb->suspended.frame].last_cmd),			&pb->planb_base->ch1.cmdptr);		writel(PLANB_CLR(PAUSE) | PLANB_SET(RUN|WAKE),			&pb->planb_base->ch1.control);	}finish:	pb->suspend--;	wake_up_interruptible(&pb->suspendq);}static void add_clip(struct planb *pb, struct video_clip *clip) {	volatile unsigned char	*base;	int	xc = clip->x, yc = clip->y;	int	wc = clip->width, hc = clip->height;	int	ww = pb->win.width, hw = pb->win.height;	int	x, y, xtmp1, xtmp2;	DBG("PlanB: clip %dx%d+%d+%d\n", wc, hc, xc, yc);	if(xc < 0) {		wc += xc;		xc = 0;	}	if(yc < 0) {		hc += yc;		yc = 0;	}	if(xc + wc > ww)		wc = ww - xc;	if(wc <= 0) /* Nothing to do */		return;	if(yc + hc > hw)		hc = hw - yc;	for (y = yc; y < yc+hc; y++) {		xtmp1=xc>>3;		xtmp2=(xc+wc)>>3;		base = pb->mask + y*96;		if(xc != 0 || wc >= 8)			*(base + xtmp1) &= (unsigned char)(0x00ff &				(0xff00 >> (xc&7)));		for (x = xtmp1 + 1; x < xtmp2; x++) {			*(base + x) = 0;		}		if(xc < (ww & ~0x7))			*(base + xtmp2) &= (unsigned char)(0x00ff >>				((xc+wc) & 7));	}	return;}static void fill_cmd_buff(struct planb *pb){	int		restore = 0;	dbdma_cmd_t	last;	DBG("PlanB: fill_cmd_buff()\n");	if(pb->overlay_last1 != pb->vid_cbo.start) {		restore = 1;		last = *(pb->overlay_last1);	}	memset ((void *) pb->vid_cbo.start, 0, 2 * pb->tab_size					* sizeof(struct dbdma_cmd));	cmd_buff (pb);	if(restore)		*(pb->overlay_last1) = last;	if(pb->suspended.overlay) {		unsigned long jump_addr = readl(&pb->overlay_last1->cmd_dep);		if(jump_addr != pb->vid_cbo.bus) {			int i;			DBG("PlanB: adjusting ch1's jump address\n");			for(i = 0; i < MAX_GBUFFERS; i++) {				if(pb->gbuf[i].need_pre_capture) {				    if(jump_addr == virt_to_bus(pb->gbuf[i].pre_cmd))					goto found;				} else {				    if(jump_addr ==					    virt_to_bus(pb->gbuf[i].cap_cmd))					goto found;				}			}			DBG("       not found!\n");			goto out;found:			if(pb->gbuf[i].need_pre_capture)				writel(virt_to_bus(pb->overlay_last1),					&pb->gbuf[i].pre_cmd->phy_addr);			else				writel(virt_to_bus(pb->overlay_last1),					&pb->gbuf[i].cap_cmd->phy_addr);		}	}out:	pb->cmd_buff_inited = 1;	return;}static void cmd_buff(struct planb *pb){	int		i, bpp, count, nlines, stepsize, interlace;	unsigned long	base, jump, addr_com, addr_dep;	dbdma_cmd_ptr	c1 = pb->vid_cbo.start;	dbdma_cmd_ptr	c2 = pb->clip_cbo.start;	interlace = pb->win.interlace;	bpp = pb->win.bpp;	count = (bpp * ((pb->win.x + pb->win.width > pb->win.swidth) ?		(pb->win.swidth - pb->win.x) : pb->win.width));	nlines = ((pb->win.y + pb->win.height > pb->win.sheight) ?		(pb->win.sheight - pb->win.y) : pb->win.height);	/* Do video in: */	/* Preamble commands: */	addr_com = virt_to_bus(c1);	addr_dep = virt_to_bus(&c1->cmd_dep);	tab_cmd_dbdma(c1++, DBDMA_NOP, 0);	jump = virt_to_bus(c1+16); /* 14 by cmd_geo_setup() and 2 for padding */	c1 = cmd_geo_setup(c1, pb->win.width, pb->win.height, interlace,						pb->win.color_fmt, 1, pb);	tab_cmd_store(c1++, addr_com, (unsigned)(DBDMA_NOP | BR_ALWAYS) << 16);	tab_cmd_store(c1++, addr_dep, jump);	tab_cmd_store(c1++, (unsigned)(&pb->planb_base_bus->ch1.wait_sel),							PLANB_SET(FIELD_SYNC));		/* (1) wait for field sync to be set */	tab_cmd_dbdma(c1++, DBDMA_NOP | WAIT_IFCLR, 0);	tab_cmd_store(c1++, (unsigned)(&pb->planb_base_bus->ch1.br_sel),							PLANB_SET(ODD_FIELD));		/* wait for field sync to be cleared */	tab_cmd_dbdma(c1++, DBDMA_NOP | WAIT_IFSET, 0);		/* if not odd field, wait until field sync is set again */	tab_cmd_dbdma(c1, DBDMA_NOP | BR_IFSET, virt_to_bus(c1-3)); c1++;		/* assert ch_sync to ch2 */	tab_cmd_store(c1++, (unsigned)(&pb->planb_base_bus->ch2.control),							PLANB_SET(CH_SYNC));	tab_cmd_store(c1++, (unsigned)(&pb->planb_base_bus->ch1.br_sel),							PLANB_SET(DMA_ABORT));	base = (pb->fb.phys + pb->fb.offset + pb->win.y * (pb->win.bpl +					pb->win.pad) + pb->win.x * bpp);	if (interlace) {		stepsize = 2;		jump = virt_to_bus(c1 + (nlines + 1) / 2);	} else {		stepsize = 1;		jump = virt_to_bus(c1 + nlines);	}	/* even field data: */	for (i=0; i < nlines; i += stepsize, c1++)		tab_cmd_gen(c1, INPUT_MORE | KEY_STREAM0 | BR_IFSET,			count, base + i * (pb->win.bpl + pb->win.pad), jump);	/* For non-interlaced, we use even fields only */	if (!interlace)		goto cmd_tab_data_end;	/* Resync to odd field */		/* (2) wait for field sync to be set */	tab_cmd_dbdma(c1++, DBDMA_NOP | WAIT_IFCLR, 0);	tab_cmd_store(c1++, (unsigned)(&pb->planb_base_bus->ch1.br_sel),							PLANB_SET(ODD_FIELD));		/* wait for field sync to be cleared */	tab_cmd_dbdma(c1++, DBDMA_NOP | WAIT_IFSET, 0);		/* if not odd field, wait until field sync is set again */	tab_cmd_dbdma(c1, DBDMA_NOP | BR_IFCLR, virt_to_bus(c1-3)); c1++;		/* assert ch_sync to ch2 */	tab_cmd_store(c1++, (unsigned)(&pb->planb_base_bus->ch2.control),							PLANB_SET(CH_SYNC));	tab_cmd_store(c1++, (unsigned)(&pb->planb_base_bus->ch1.br_sel),							PLANB_SET(DMA_ABORT));		/* odd field data: */	jump = virt_to_bus(c1 + nlines / 2);	for (i=1; i < nlines; i += stepsize, c1++)		tab_cmd_gen(c1, INPUT_MORE | KEY_STREAM0 | BR_IFSET, count,			base + i * (pb->win.bpl + pb->win.pad), jump);	/* And jump back to the start */cmd_tab_data_end:	pb->overlay_last1 = c1;	/* keep a pointer to the last command */	tab_cmd_dbdma(c1, DBDMA_NOP | BR_ALWAYS, pb->vid_cbo.bus);	/* Clipmask command buffer */	/* Preamble commands: */	tab_cmd_dbdma(c2++, DBDMA_NOP, 0);	tab_cmd_store(c2++, (unsigned)(&pb->planb_base_bus->ch2.wait_sel),							PLANB_SET(CH_SYNC));		/* wait until ch1 asserts ch_sync */	tab_cmd_dbdma(c2++, DBDMA_NOP | WAIT_IFCLR, 0);		/* clear ch_sync asserted by ch1 */	tab_cmd_store(c2++, (unsigned)(&pb->planb_base_bus->ch2.control),							PLANB_CLR(CH_SYNC));	tab_cmd_store(c2++, (unsigned)(&pb->planb_base_bus->ch2.wait_sel),							PLANB_SET(FIELD_SYNC));	tab_cmd_store(c2++, (unsigned)(&pb->planb_base_bus->ch2.br_sel),							PLANB_SET(ODD_FIELD));	/* jump to end of even field if appropriate */	/* this points to (interlace)? pos. C: pos. B */	jump = (interlace) ? virt_to_bus(c2 + (nlines + 1) / 2 + 2):						virt_to_bus(c2 + nlines + 2);		/* if odd field, skip over to odd field clipmasking */	tab_cmd_dbdma(c2++, DBDMA_NOP | BR_IFSET, jump);	/* even field mask: */	tab_cmd_store(c2++, (unsigned)(&pb->planb_base_bus->ch2.br_sel),							PLANB_SET(DMA_ABORT));	/* this points to pos. B */	jump = (interlace) ? virt_to_bus(c2 + nlines + 1):						virt_to_bus(c2 + nlines);	base = virt_to_bus(pb->mask);	for (i=0; i < nlines; i += stepsize, c2++)		tab_cmd_gen(c2, OUTPUT_MORE | KEY_STREAM0 | BR_IFSET, 96,			base + i * 96, jump);	/* For non-interlaced, we use only even fields */	if(!interlace)		goto cmd_tab_mask_end;	/* odd field mask: */

⌨️ 快捷键说明

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