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

📄 intelfbhw.c

📁 linux-2.4.29操作系统的源码
💻 C
📖 第 1 页 / 共 3 页
字号:
	/* Enable sync */	tmp = INREG(ADPA);	tmp &= ~ADPA_DPMS_CONTROL_MASK;	tmp |= ADPA_DPMS_D0;	OUTREG(ADPA, tmp);	/* setup display plane */	OUTREG(DSPACNTR, hw->disp_a_ctrl & ~DISPPLANE_PLANE_ENABLE);	OUTREG(DSPASTRIDE, hw->disp_a_stride);	OUTREG(DSPABASE, hw->disp_a_base);	/* Enable plane */	if (!blank) {		tmp = INREG(DSPACNTR);		tmp |= DISPPLANE_PLANE_ENABLE;		OUTREG(DSPACNTR, tmp);		OUTREG(DSPABASE, hw->disp_a_base);	}	return 0;}static intwait_ring(struct intelfb_info *dinfo, int n){	int i = 0;	unsigned long end;	u32 last_head = INREG(PRI_RING_HEAD) & RING_HEAD_MASK;#if 0	DBG_MSG("wait_ring: %d\n", n);#endif	end = jiffies + (HZ * 3);	while (dinfo->ring_space < n) {		dinfo->ring_head = INREG(PRI_RING_HEAD) & RING_HEAD_MASK;		dinfo->ring_space = dinfo->ring_head -				    (dinfo->ring_tail + RING_MIN_FREE);		if (dinfo->ring_space < 0)			dinfo->ring_space += dinfo->ring_size;		if (dinfo->ring_head != last_head) {			end = jiffies + (HZ * 3);			last_head = dinfo->ring_head;		}		i++;		if (time_before(end, jiffies)) {			WRN_MSG("space: %d wanted %d\n", dinfo->ring_space, n);			WRN_MSG("lockup\n");			break;		}		udelay(1);	}	return i;}voidintelfbhw_do_sync(struct intelfb_info *dinfo){#if USE_SYNC_PAGE	u32 newval;#endif	u32 tmp;	int i = 0;#if VERBOSE > 0	DBG_MSG("intelfbhw_do_sync\n");#endif#if USE_SYNC_PAGE	/*	 * Although doing MI_STORE_DWORD_IMM after the MI_FLUSH is supposed	 * to make sure everything is synchronised, there is still some	 * mis-ordering of operations when mixing 2D with direct CPU	 * writes to the framebuffer.	 */	newval = readl(dinfo->syncpage_virt);	newval++;#if VERBOSE > 0	DBG_MSG("intelfbhw_do_sync: %d\n", newval);#endif	START_RING(6);	OUT_RING(MI_FLUSH | MI_WRITE_DIRTY_STATE);	OUT_RING(MI_NOOP);	OUT_RING(MI_STORE_DWORD_IMM);	OUT_RING(dinfo->syncpage_phys);	OUT_RING(newval);	OUT_RING(MI_NOOP);	ADVANCE_RING();	while ((tmp = readl(dinfo->syncpage_virt)) != newval && i < 10000) {		i++;		udelay(10);	}	if (tmp != newval) {		DBG_MSG("intelfbhw_do_sync: STORE_DWORD_IMM returns %d "			"instead of %d\n", tmp, newval);	} else {#if VERBOSE > 1		DBG_MSG("intelfbhw_do_sync: done in %d iterations\n", i);#endif	}#else	/*	 * Send a flush, then wait until the ring is empty.  This is what	 * the XFree86 driver does, and actually it doesn't seem a lot worse	 * than the recommended method (both have problems).	 */	START_RING(2);	OUT_RING(MI_FLUSH | MI_WRITE_DIRTY_STATE);	OUT_RING(MI_NOOP);	ADVANCE_RING();	wait_ring(dinfo, dinfo->ring_size - RING_MIN_FREE);	dinfo->ring_space = dinfo->ring_size - RING_MIN_FREE;#endif}static voidrefresh_ring(struct intelfb_info *dinfo){	DBG_MSG("refresh_ring\n");	dinfo->ring_head = INREG(PRI_RING_HEAD) & RING_HEAD_MASK;	dinfo->ring_tail = INREG(PRI_RING_TAIL) & RING_TAIL_MASK;	dinfo->ring_space = dinfo->ring_head -			    (dinfo->ring_tail + RING_MIN_FREE);	if (dinfo->ring_space < 0)		dinfo->ring_space += dinfo->ring_size;}static voidreset_state(struct intelfb_info *dinfo){	int i;	u32 tmp;	DBG_MSG("reset_state\n");	for (i = 0; i < FENCE_NUM; i++)		OUTREG(FENCE + (i << 2), 0);	/* Flush the ring buffer if it's enabled. */	tmp = INREG(PRI_RING_LENGTH);	if (tmp & RING_ENABLE) {		DBG_MSG("reset_state: ring was enabled\n");		refresh_ring(dinfo);		intelfbhw_do_sync(dinfo);		DO_RING_IDLE();	}	OUTREG(PRI_RING_LENGTH, 0);	OUTREG(PRI_RING_HEAD, 0);	OUTREG(PRI_RING_TAIL, 0);	OUTREG(PRI_RING_START, 0);}/* Stop the 2D engine, and turn off the ring buffer. */voidintelfbhw_2d_stop(struct intelfb_info *dinfo){	DBG_MSG("intelfbhw_2d_stop: accel: %d, ring_active: %d\n", dinfo->accel,		dinfo->ring_active);	if (!dinfo->accel)		return;	dinfo->ring_active = 0;	reset_state(dinfo);}/* * Enable the ring buffer, and initialise the 2D engine. * It is assumed that the graphics engine has been stopped by previously * calling intelfb_2d_stop(). */voidintelfbhw_2d_start(struct intelfb_info *dinfo){	DBG_MSG("intelfbhw_2d_start: accel: %d, ring_active: %d\n",		dinfo->accel, dinfo->ring_active);	if (!dinfo->accel)		return;	/* Initialise the primary ring buffer. */	OUTREG(PRI_RING_LENGTH, 0);	OUTREG(PRI_RING_TAIL, 0);	OUTREG(PRI_RING_HEAD, 0);	OUTREG(PRI_RING_START, dinfo->ring_base_phys & RING_START_MASK);	OUTREG(PRI_RING_LENGTH,		((dinfo->ring_size - GTT_PAGE_SIZE) & RING_LENGTH_MASK) |		RING_NO_REPORT | RING_ENABLE);	refresh_ring(dinfo);	dinfo->ring_active = 1;	DBG_MSG("INSTPM was 0x%08x, setting to 0x%08x\n", INREG(INSTPM),		0x1f << 16);	OUTREG(INSTPM, 0x1f << 16);	OUTREG(INSTPM, 0x1f << 16);}/* 2D fillrect (solid fill or invert) */voidintelfbhw_do_fillrect(struct intelfb_info *dinfo, u32 x, u32 y, u32 w, u32 h,		      u32 color, u32 pitch, u32 bpp, u32 rop){	u32 br00, br09, br13, br14, br16;#if VERBOSE > 1	DBG_MSG("intelfbhw_do_fillrect: (%d,%d) %dx%d, c 0x%06x, p %d bpp %d, "		"rop 0x%02x\n", x, y, w, h, color, pitch, bpp, rop);#endif	br00 = COLOR_BLT_CMD;	br09 = dinfo->fb_offset + (y * pitch + x * (bpp / 8));	br13 = (rop << ROP_SHIFT) | pitch;	br14 = (h << HEIGHT_SHIFT) | ((w * bpp / 8) << WIDTH_SHIFT);	br16 = color;	switch (bpp) {	case 8:		br13 |= COLOR_DEPTH_8;		break;	case 16:		br13 |= COLOR_DEPTH_16;		break;	case 32:		br13 |= COLOR_DEPTH_32;		br00 |= WRITE_ALPHA | WRITE_RGB;		break;	}	START_RING(6);	OUT_RING(br00);	OUT_RING(br13);	OUT_RING(br14);	OUT_RING(br09);	OUT_RING(br16);	OUT_RING(MI_NOOP);	ADVANCE_RING();}voidintelfbhw_do_bitblt(struct intelfb_info *dinfo, u32 curx, u32 cury,		    u32 dstx, u32 dsty, u32 w, u32 h, u32 pitch, u32 bpp){	u32 br00, br09, br11, br12, br13, br22, br23, br26;#if VERBOSE > 0	DBG_MSG("intelfbhw_do_bitblt: (%d,%d)->(%d,%d) %dx%d, p %d bpp %d\n",		curx, cury, dstx, dsty, w, h, pitch, bpp);#endif	br00 = XY_SRC_COPY_BLT_CMD;	br09 = dinfo->fb_offset;	br11 = (pitch << PITCH_SHIFT);	br12 = dinfo->fb_offset;	br13 = (SRC_ROP_GXCOPY << ROP_SHIFT) | (pitch << PITCH_SHIFT);	br22 = (dstx << WIDTH_SHIFT) | (dsty << HEIGHT_SHIFT);	br23 = ((dstx + w) << WIDTH_SHIFT) |	       ((dsty + h) << HEIGHT_SHIFT);	br26 = (curx << WIDTH_SHIFT) | (cury << HEIGHT_SHIFT);	switch (bpp) {	case 8:		br13 |= COLOR_DEPTH_8;		break;	case 16:		br13 |= COLOR_DEPTH_16;		break;	case 32:		br13 |= COLOR_DEPTH_32;		br00 |= WRITE_ALPHA | WRITE_RGB;		break;	}	START_RING(8);	OUT_RING(br00);	OUT_RING(br13);	OUT_RING(br22);	OUT_RING(br23);	OUT_RING(br09);	OUT_RING(br26);	OUT_RING(br11);	OUT_RING(br12);	ADVANCE_RING();}intintelfbhw_do_drawglyph(struct intelfb_info *dinfo, u32 fg, u32 bg, u32 w, u32 h,		       u8* cdat, u32 x, u32 y, u32 pitch, u32 bpp){	int i, n = 0, fw_bytes, bytes_per_src_line;	int nbytes, ndwords, pad, tmp;	u16 *wcdat;	u32 *dwcdat;	u32 br00, br09, br13, br18, br19, br22, br23;#if 0	DBG_MSG("intelfbhw_do_drawglyph: (%d,%d) %dx%d\n", x, y, w, h);#endif	/* Support fonts up to 32 pixels wide. */	if (w > 32)		return 0;	/* Number of bytes required for each cdat scanline. */	fw_bytes = ROUND_UP_TO(w, 8) / 8;	/* Src scanlines are word (16-bit) padded. */	bytes_per_src_line = ROUND_UP_TO(fw_bytes, 2);	/* Total bytes of padded scanline data to write out. */	nbytes = h * bytes_per_src_line;	/*	 * Check if the glyph data exceeds the immediate mode limit.	 * It would take a large font (1K pixels) to hit this limit.	 */	if (nbytes > MAX_MONO_IMM_SIZE)		return 0;	/* Src data is packaged a dword (32-bit) at a time. */	ndwords = ROUND_UP_TO(nbytes, 4) / 4;	/* Ring has to be padded to a quad word. */	pad = ndwords % 2;	/* For easy reference of the glyph data in different sized chunks. */	wcdat = (u16 *)cdat;	dwcdat = (u32 *)cdat;	tmp = (XY_MONO_SRC_IMM_BLT_CMD & DW_LENGTH_MASK) + ndwords;	br00 = (XY_MONO_SRC_IMM_BLT_CMD & ~DW_LENGTH_MASK) | tmp;	br09 = dinfo->fb_offset;	br13 = (SRC_ROP_GXCOPY << ROP_SHIFT) | (pitch << PITCH_SHIFT);	br18 = bg;	br19 = fg;	br22 = (x << WIDTH_SHIFT) | (y << HEIGHT_SHIFT);	br23 = ((x + w) << WIDTH_SHIFT) | ((y + h) << HEIGHT_SHIFT);	switch (bpp) {	case 8:		br13 |= COLOR_DEPTH_8;		break;	case 16:		br13 |= COLOR_DEPTH_16;		break;	case 32:		br13 |= COLOR_DEPTH_32;		br00 |= WRITE_ALPHA | WRITE_RGB;		break;	}#if 0	DBG_MSG("ndwords + pad is %d, pad is %d\n", ndwords + pad, pad);#endif	START_RING(ndwords + pad);	OUT_RING(br00);	OUT_RING(br13);	OUT_RING(br22);	OUT_RING(br23);	OUT_RING(br09);	OUT_RING(br18);	OUT_RING(br19);	i = h;	switch (fw_bytes) {	case 1:		while (i >= 2) {			OUT_RING(cdat[0] | cdat[1] << 16);			cdat +=2;			i -= 2;			n++;		}		if (i) {			OUT_RING(cdat[0]);			n++;		}		break;	case 2:		while (i >= 2) {			OUT_RING(wcdat[0] | wcdat[1] << 16);			wcdat += 2;			i -= 2;			n++;		}		if (i) {			OUT_RING(wcdat[0]);			n++;		}		break;	case 3:		while (i) {			OUT_RING(wcdat[0] | cdat[3] << 16);			wcdat += 2;			cdat += 4;			i--;			n++;		}		break;	case 4:		while(i) {			OUT_RING(dwcdat[0]);			i--;			n++;		}	}	if (pad) {		OUT_RING(MI_NOOP);		n++;	}#if 0	DBG_MSG("%d immediate bytes + pad\n", n);#endif	ADVANCE_RING();	return 1;}/* HW cursor functions. */voidintelfbhw_cursor_init(struct intelfb_info *dinfo){	u32 tmp;	DBG_MSG("intelfbhw_cursor_init\n");	if (!dinfo->cursor_base)		return;	if (dinfo->mobile) {		if (!dinfo->cursor_base_real)			return;		tmp = INREG(CURSOR_A_CONTROL);		tmp &= ~(CURSOR_MODE_MASK | CURSOR_MOBILE_GAMMA_ENABLE |			 CURSOR_MEM_TYPE_LOCAL |			 (1 << CURSOR_PIPE_SELECT_SHIFT));		tmp |= CURSOR_MODE_DISABLE;		OUTREG(CURSOR_A_CONTROL, tmp);		OUTREG(CURSOR_A_BASEADDR, dinfo->cursor_base_real);	} else {#if 0		tmp = INREG(CURSOR_CONTROL);		tmp &= ~(CURSOR_FORMAT_MASK | CURSOR_GAMMA_ENABLE |			 CURSOR_ENABLE | CURSOR_STRIDE_MASK);#endif		tmp = CURSOR_FORMAT_3C;		OUTREG(CURSOR_CONTROL, tmp);		OUTREG(CURSOR_A_BASEADDR, dinfo->cursor_offset);		tmp = (64 << CURSOR_SIZE_H_SHIFT) |		      (64 << CURSOR_SIZE_V_SHIFT);		OUTREG(CURSOR_SIZE, tmp);	}}voidintelfbhw_cursor_hide(struct intelfb_info *dinfo){	u32 tmp;#if VERBOSE > 1	DBG_MSG("intelfbhw_cursor_hide\n");#endif	if (!dinfo->cursor_base)		return;	dinfo->cursor.enabled = 0;	dinfo->cursor.on = 0;	if (dinfo->mobile) {		if (!dinfo->cursor_base_real)			return;		tmp = INREG(CURSOR_A_CONTROL);		tmp &= ~CURSOR_MODE_MASK;		tmp |= CURSOR_MODE_DISABLE;		OUTREG(CURSOR_A_CONTROL, tmp);		/* Flush changes */		OUTREG(CURSOR_A_BASEADDR, dinfo->cursor_base_real);	} else {		tmp = INREG(CURSOR_CONTROL);		tmp &= ~CURSOR_ENABLE;		OUTREG(CURSOR_CONTROL, tmp);	}}voidintelfbhw_cursor_show(struct intelfb_info *dinfo){	u32 tmp;#if VERBOSE > 1	DBG_MSG("intelfbhw_cursor_show\n");#endif	if (!dinfo->cursor_base)		return;	dinfo->cursor.on = 1;	dinfo->cursor.enabled = 1;	if (dinfo->cursor.blanked)		return;	if (dinfo->mobile) {		if (!dinfo->cursor_base_real)			return;		tmp = INREG(CURSOR_A_CONTROL);		tmp &= ~CURSOR_MODE_MASK;		tmp |= CURSOR_MODE_64_4C_AX;		OUTREG(CURSOR_A_CONTROL, tmp);		/* Flush changes */		OUTREG(CURSOR_A_BASEADDR, dinfo->cursor_base_real);	} else {		tmp = INREG(CURSOR_CONTROL);		tmp |= CURSOR_ENABLE;		OUTREG(CURSOR_CONTROL, tmp);	}}voidintelfbhw_cursor_setpos(struct intelfb_info *dinfo, int x, int y){	u32 tmp;#if VERBOSE > 1	DBG_MSG("intelfbhw_cursor_setpos: (%d, %d)\n", x, y);#endif	/*	 * Sets the position.  The coordinates are assumed to already	 * have any offset adjusted.  Assume that the cursor is never	 * completely off-screen, and that x, y are always >= 0.	 */	if (!dinfo->cursor_base)		return;	tmp = ((x & CURSOR_POS_MASK) << CURSOR_X_SHIFT) |	      ((y & CURSOR_POS_MASK) << CURSOR_Y_SHIFT);	OUTREG(CURSOR_A_POSITION, tmp);}voidintelfbhw_cursor_setcolor(struct intelfb_info *dinfo, u32 bg, u32 fg){#if VERBOSE > 1	DBG_MSG("intelfbhw_cursor_setcolor\n");#endif	if (!dinfo->cursor_base)		return;	OUTREG(CURSOR_A_PALETTE0, bg & CURSOR_PALETTE_MASK);	OUTREG(CURSOR_A_PALETTE1, fg & CURSOR_PALETTE_MASK);	OUTREG(CURSOR_A_PALETTE2, fg & CURSOR_PALETTE_MASK);	OUTREG(CURSOR_A_PALETTE3, bg & CURSOR_PALETTE_MASK);}voidintelfbhw_cursor_load(struct intelfb_info *dinfo, struct display *disp){	u32 xline, mline;	int i;	DBG_MSG("intelfbhw_cursor_load\n");	if (!dinfo->cursor_base)		return;	intelfb_create_cursor_shape(dinfo, disp);	xline = (1 << dinfo->cursor.w) - 1;	mline = ~xline;	for (i = 0; i < dinfo->cursor.u; i++) {		writel(~0, dinfo->cursor_base + i * 16);		writel(~0, dinfo->cursor_base + i * 16 + 4);		writel(0, dinfo->cursor_base + i * 16 + 8);		writel(0, dinfo->cursor_base + i * 16 + 12);	}	for (; i < dinfo->cursor.d; i++) {		writel(mline, dinfo->cursor_base + i * 16);		writel(~0, dinfo->cursor_base + i * 16 + 4);		writel(xline, dinfo->cursor_base + i * 16 + 8);		writel(0, dinfo->cursor_base + i * 16 + 12);	}	for (; i < 64; i++) {		writel(~0, dinfo->cursor_base + i * 16);		writel(~0, dinfo->cursor_base + i * 16 + 4);		writel(0, dinfo->cursor_base + i * 16 + 8);		writel(0, dinfo->cursor_base + i * 16 + 12);	}}

⌨️ 快捷键说明

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