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

📄 blizzard.c

📁 Linux环境下视频显示卡设备的驱动程序源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
	int gx1_out, gy1_out, gx2_out, gy2_out;	int color_mode;	int flags;	int zoom_off;	/* Global coordinates, relative to pixel 0,0 of the LCD */	gx1 = x + blizzard.plane[plane].pos_x;	gy1 = y + blizzard.plane[plane].pos_y;	gx2 = gx1 + w;	gy2 = gy1 + h;	flags = req->par.update.flags;	if (flags & OMAPFB_FORMAT_FLAG_DOUBLE) {		gx1_out = gx1;		gy1_out = gy1;		gx2_out = gx1 + w * 2;		gy2_out = gy1 + h * 2;	} else {		gx1_out = x_out + blizzard.plane[plane].pos_x;		gy1_out = y_out + blizzard.plane[plane].pos_y;		gx2_out = gx1_out + w_out;		gy2_out = gy1_out + h_out;	}	zoom_off = blizzard.zoom_on && gx1 == 0 && gy1 == 0 &&		w == blizzard.screen_width && h == blizzard.screen_height;	blizzard.zoom_on = (!zoom_off && blizzard.zoom_on) ||			   (w < w_out || h < h_out);	for (i = 0; i < OMAPFB_PLANE_NUM; i++) {		struct plane_info *p = &blizzard.plane[i];		int px1, py1;		int px2, py2;		int pw, ph;		int pposx, pposy;		unsigned long offset;		if (!(blizzard.enabled_planes & (1 << i))  ||		    (wnd_color_mode && i != plane)) {			blizzard.int_ctrl->enable_plane(i, 0);			continue;		}		/* Plane coordinates */		if (i == plane) {			/* Plane in which we are doing the update.			 * Local coordinates are the one in the update			 * request.			 */			px1 = x;			py1 = y;			px2 = x + w;			py2 = y + h;			pposx = 0;			pposy = 0;		} else {			/* Check if this plane has an overlapping part */			px1 = gx1 - p->pos_x;			py1 = gy1 - p->pos_y;			px2 = gx2 - p->pos_x;			py2 = gy2 - p->pos_y;			if (px1 >= p->width || py1 >= p->height ||			    px2 <= 0 || py2 <= 0) {				blizzard.int_ctrl->enable_plane(i, 0);				continue;			}			/* Calculate the coordinates for the overlapping			 * part in the plane's local coordinates.			 */			pposx = -px1;			pposy = -py1;			if (px1 < 0)				px1 = 0;			if (py1 < 0)				py1 = 0;			if (px2 > p->width)				px2 = p->width;			if (py2 > p->height)				py2 = p->height;			if (pposx < 0)				pposx = 0;			if (pposy < 0)				pposy = 0;		}		pw = px2 - px1;		ph = py2 - py1;		offset = p->offset + (p->scr_width * py1 + px1) * p->bpp / 8;		if (wnd_color_mode)			/* Window embedded in the plane with a differing			 * color mode / bpp. Calculate the number of DMA			 * transfer elements in terms of the plane's bpp.			 */			pw = (pw + 1) * bpp / p->bpp;#ifdef VERBOSE		dev_dbg(blizzard.fbdev->dev,			"plane %d offset %#08lx pposx %d pposy %d "			"px1 %d py1 %d pw %d ph %d\n",			i, offset, pposx, pposy, px1, py1, pw, ph);#endif		blizzard.int_ctrl->setup_plane(i,				OMAPFB_CHANNEL_OUT_LCD, offset,				p->scr_width,				pposx, pposy, pw, ph,				p->color_mode);		blizzard.int_ctrl->enable_plane(i, 1);	}	switch (wnd_color_mode) {	case OMAPFB_COLOR_YUV420:		color_mode = BLIZZARD_COLOR_YUV420;		/* Currently only the 16 bits/pixel cycle format is		 * supported on the external interface. Adjust the number		 * of transfer elements per line for 12bpp format.		 */		w = (w + 1) * 3 / 4;		break;	default:		color_mode = BLIZZARD_COLOR_RGB565;		break;	}	blizzard_wait_line_buffer();	if (blizzard.last_color_mode == BLIZZARD_COLOR_YUV420)		blizzard_wait_yyc();	blizzard.last_color_mode = color_mode;	if (flags & OMAPFB_FORMAT_FLAG_TEARSYNC)		enable_tearsync(gy1, w, h,				blizzard.screen_height,				h_out,				flags & OMAPFB_FORMAT_FLAG_FORCE_VSYNC);	else		disable_tearsync();	set_window_regs(gx1, gy1, gx2, gy2, gx1_out, gy1_out, gx2_out, gy2_out,			color_mode, zoom_off, flags);	blizzard.extif->set_bits_per_cycle(16);	/* set_window_regs has left the register index at the right	 * place, so no need to set it here.	 */	blizzard.extif->transfer_area(w, h, request_complete, req);	return REQ_PENDING;}static int send_frame_handler(struct blizzard_request *req){	struct update_param *par = &req->par.update;	int plane = par->plane;#ifdef VERBOSE	dev_dbg(blizzard.fbdev->dev,		"send_frame: x %d y %d w %d h %d "		"x_out %d y_out %d w_out %d h_out %d "		"color_mode %04x flags %04x planes %01x\n",		par->x, par->y, par->width, par->height,		par->out_x, par->out_y, par->out_width, par->out_height,		par->color_mode, par->flags, blizzard.enabled_planes);#endif	if (par->flags & OMAPFB_FORMAT_FLAG_DISABLE_OVERLAY)		disable_overlay();	if ((blizzard.enabled_planes & blizzard.vid_nonstd_color) ||	     (blizzard.enabled_planes & blizzard.vid_scaled))		return do_full_screen_update(req);	return do_partial_update(req, plane, par->x, par->y,				 par->width, par->height,				 par->out_x, par->out_y,				 par->out_width, par->out_height,				 par->color_mode, par->bpp);}static void send_frame_complete(void *data){}#define ADD_PREQ(_x, _y, _w, _h, _x_out, _y_out, _w_out, _h_out) do {	\	req = alloc_req();			\	req->handler	= send_frame_handler;	\	req->complete	= send_frame_complete;	\	req->par.update.plane = plane_idx;	\	req->par.update.x = _x;			\	req->par.update.y = _y;			\	req->par.update.width  = _w;		\	req->par.update.height = _h;		\	req->par.update.out_x = _x_out;		\	req->par.update.out_y = _y_out;		\	req->par.update.out_width = _w_out;	\	req->par.update.out_height = _h_out;	\	req->par.update.bpp = bpp;		\	req->par.update.color_mode = color_mode;\	req->par.update.flags	  = flags;	\	list_add_tail(&req->entry, req_head);	\} while(0)static void create_req_list(int plane_idx,			    struct omapfb_update_window *win,			    struct list_head *req_head){	struct blizzard_request *req;	int x = win->x;	int y = win->y;	int width = win->width;	int height = win->height;	int x_out = win->out_x;	int y_out = win->out_y;	int width_out = win->out_width;	int height_out = win->out_height;	int color_mode;	int bpp;	int flags;	unsigned int ystart = y;	unsigned int yspan = height;	unsigned int ystart_out = y_out;	unsigned int yspan_out = height_out;	flags = win->format & ~OMAPFB_FORMAT_MASK;	color_mode = win->format & OMAPFB_FORMAT_MASK;	switch (color_mode) {	case OMAPFB_COLOR_YUV420:		/* Embedded window with different color mode */		bpp = 12;		/* X, Y, height must be aligned at 2, width at 4 pixels */		x &= ~1;		y &= ~1;		height = yspan = height & ~1;		width = width & ~3;		break;	default:		/* Same as the plane color mode */		bpp = blizzard.plane[plane_idx].bpp;		break;	}	if (width * height * bpp / 8 > blizzard.max_transmit_size) {		yspan = blizzard.max_transmit_size / (width * bpp / 8);		yspan_out = yspan * height_out / height;		ADD_PREQ(x, ystart, width, yspan, x_out, ystart_out,			 width_out, yspan_out);		ystart += yspan;		ystart_out += yspan_out;		yspan = height - yspan;		yspan_out = height_out - yspan_out;		flags &= ~OMAPFB_FORMAT_FLAG_TEARSYNC;	}	ADD_PREQ(x, ystart, width, yspan, x_out, ystart_out,		 width_out, yspan_out);}static void auto_update_complete(void *data){	if (!blizzard.stop_auto_update)		mod_timer(&blizzard.auto_update_timer,			  jiffies + BLIZZARD_AUTO_UPDATE_TIME);}static void blizzard_update_window_auto(unsigned long arg){	LIST_HEAD(req_list);	struct blizzard_request *last;	struct omapfb_plane_struct *plane;	plane = blizzard.fbdev->fb_info[0]->par;	create_req_list(plane->idx,			&blizzard.auto_update_window, &req_list);	last = list_entry(req_list.prev, struct blizzard_request, entry);	last->complete = auto_update_complete;	last->complete_data = NULL;	submit_req_list(&req_list);}int blizzard_update_window_async(struct fb_info *fbi,				 struct omapfb_update_window *win,				 void (*complete_callback)(void *arg),				 void *complete_callback_data){	LIST_HEAD(req_list);	struct blizzard_request *last;	struct omapfb_plane_struct *plane = fbi->par;	if (unlikely(blizzard.update_mode != OMAPFB_MANUAL_UPDATE))		return -EINVAL;	if (unlikely(!blizzard.te_connected &&		     (win->format & OMAPFB_FORMAT_FLAG_TEARSYNC)))		return -EINVAL;	create_req_list(plane->idx, win, &req_list);	last = list_entry(req_list.prev, struct blizzard_request, entry);	last->complete = complete_callback;	last->complete_data = (void *)complete_callback_data;	submit_req_list(&req_list);	return 0;}EXPORT_SYMBOL(blizzard_update_window_async);static int update_full_screen(void){	return blizzard_update_window_async(blizzard.fbdev->fb_info[0],				     &blizzard.auto_update_window, NULL, NULL);}static int blizzard_setup_plane(int plane, int channel_out,				  unsigned long offset, int screen_width,				  int pos_x, int pos_y, int width, int height,				  int color_mode){	struct plane_info *p;#ifdef VERBOSE	dev_dbg(blizzard.fbdev->dev,		    "plane %d ch_out %d offset %#08lx scr_width %d "		    "pos_x %d pos_y %d width %d height %d color_mode %d\n",		    plane, channel_out, offset, screen_width,		    pos_x, pos_y, width, height, color_mode);#endif	if ((unsigned)plane > OMAPFB_PLANE_NUM)		return -EINVAL;	p = &blizzard.plane[plane];	switch (color_mode) {	case OMAPFB_COLOR_YUV422:	case OMAPFB_COLOR_YUY422:		p->bpp = 16;		blizzard.vid_nonstd_color &= ~(1 << plane);		break;	case OMAPFB_COLOR_YUV420:		p->bpp = 12;		blizzard.vid_nonstd_color |= 1 << plane;		break;	case OMAPFB_COLOR_RGB565:		p->bpp = 16;		blizzard.vid_nonstd_color &= ~(1 << plane);		break;	default:		return -EINVAL;	}	p->offset = offset;	p->pos_x = pos_x;	p->pos_y = pos_y;	p->width = width;	p->height = height;	p->scr_width = screen_width;	if (!p->out_width)		p->out_width = width;	if (!p->out_height)		p->out_height = height;	p->color_mode = color_mode;	return 0;}static int blizzard_set_scale(int plane, int orig_w, int orig_h,			      int out_w, int out_h){	struct plane_info *p = &blizzard.plane[plane];	int r;	dev_dbg(blizzard.fbdev->dev,		"plane %d orig_w %d orig_h %d out_w %d out_h %d\n",		plane, orig_w, orig_h, out_w, out_h);	if ((unsigned)plane > OMAPFB_PLANE_NUM)		return -ENODEV;	r = blizzard.int_ctrl->set_scale(plane, orig_w, orig_h, out_w, out_h);	if (r < 0)		return r;	p->width = orig_w;	p->height = orig_h;	p->out_width = out_w;	p->out_height = out_h;	if (orig_w == out_w && orig_h == out_h)		blizzard.vid_scaled &= ~(1 << plane);	else		blizzard.vid_scaled |= 1 << plane;	return 0;}static int blizzard_enable_plane(int plane, int enable){	if (enable)		blizzard.enabled_planes |= 1 << plane;	else		blizzard.enabled_planes &= ~(1 << plane);	return 0;}static int sync_handler(struct blizzard_request *req){	complete(req->par.sync);	return REQ_COMPLETE;}static void blizzard_sync(void){	LIST_HEAD(req_list);	struct blizzard_request *req;	struct completion comp;	req = alloc_req();	req->handler = sync_handler;	req->complete = NULL;	init_completion(&comp);	req->par.sync = &comp;	list_add(&req->entry, &req_list);	submit_req_list(&req_list);	wait_for_completion(&comp);}static void blizzard_bind_client(struct omapfb_notifier_block *nb){	if (blizzard.update_mode == OMAPFB_MANUAL_UPDATE) {		omapfb_notify_clients(blizzard.fbdev, OMAPFB_EVENT_READY);	}}static int blizzard_set_update_mode(enum omapfb_update_mode mode){	if (unlikely(mode != OMAPFB_MANUAL_UPDATE &&		     mode != OMAPFB_AUTO_UPDATE &&		     mode != OMAPFB_UPDATE_DISABLED))		return -EINVAL;	if (mode == blizzard.update_mode)		return 0;	dev_info(blizzard.fbdev->dev, "s1d1374x: setting update mode to %s\n",			mode == OMAPFB_UPDATE_DISABLED ? "disabled" :			(mode == OMAPFB_AUTO_UPDATE ? "auto" : "manual"));	switch (blizzard.update_mode) {	case OMAPFB_MANUAL_UPDATE:		omapfb_notify_clients(blizzard.fbdev, OMAPFB_EVENT_DISABLED);		break;	case OMAPFB_AUTO_UPDATE:		blizzard.stop_auto_update = 1;		del_timer_sync(&blizzard.auto_update_timer);		break;	case OMAPFB_UPDATE_DISABLED:		break;	}	blizzard.update_mode = mode;	blizzard_sync();	blizzard.stop_auto_update = 0;	switch (mode) {	case OMAPFB_MANUAL_UPDATE:		omapfb_notify_clients(blizzard.fbdev, OMAPFB_EVENT_READY);		break;	case OMAPFB_AUTO_UPDATE:		blizzard_update_window_auto(0);		break;	case OMAPFB_UPDATE_DISABLED:		break;	}	return 0;}static enum omapfb_update_mode blizzard_get_update_mode(void){	return blizzard.update_mode;}static inline void set_extif_timings(const struct extif_timings *t){	blizzard.extif->set_timings(t);}static inline unsigned long round_to_extif_ticks(unsigned long ps, int div){	int bus_tick = blizzard.extif_clk_period * div;	return (ps + bus_tick - 1) / bus_tick * bus_tick;}static int calc_reg_timing(unsigned long sysclk, int div){	struct extif_timings *t;	unsigned long systim;	/* CSOnTime 0, WEOnTime 2 ns, REOnTime 2 ns,	 * AccessTime 2 ns + 12.2 ns (regs),	 * WEOffTime = WEOnTime + 1 ns,	 * REOffTime = REOnTime + 12 ns (regs),	 * CSOffTime = REOffTime + 1 ns	 * ReadCycle = 2ns + 2*SYSCLK  (regs),	 * WriteCycle = 2*SYSCLK + 2 ns,	 * CSPulseWidth = 10 ns */	systim = 1000000000 / (sysclk / 1000);	dev_dbg(blizzard.fbdev->dev,		  "Blizzard systim %lu ps extif_clk_period %u div %d\n",		  systim, blizzard.extif_clk_period, div);	t = &blizzard.reg_timings;	memset(t, 0, sizeof(*t));	t->clk_div = div;	t->cs_on_time = 0;	t->we_on_time = round_to_extif_ticks(t->cs_on_time + 2000, div);	t->re_on_time = round_to_extif_ticks(t->cs_on_time + 2000, div);	t->access_time = round_to_extif_ticks(t->re_on_time + 12200, div);	t->we_off_time = round_to_extif_ticks(t->we_on_time + 1000, div);	t->re_off_time = round_to_extif_ticks(t->re_on_time + 13000, div);	t->cs_off_time = round_to_extif_ticks(t->re_off_time + 1000, div);	t->we_cycle_time = round_to_extif_ticks(2 * systim + 2000, div);	if (t->we_cycle_time < t->we_off_time)

⌨️ 快捷键说明

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