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

📄 aty128fb.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 5 页
字号:
			    const struct aty128fb_par *par){	aty_st_le32(CRTC_GEN_CNTL, crtc->gen_cntl);	aty_st_le32(CRTC_H_TOTAL_DISP, crtc->h_total);	aty_st_le32(CRTC_H_SYNC_STRT_WID, crtc->h_sync_strt_wid);	aty_st_le32(CRTC_V_TOTAL_DISP, crtc->v_total);	aty_st_le32(CRTC_V_SYNC_STRT_WID, crtc->v_sync_strt_wid);	aty_st_le32(CRTC_PITCH, crtc->pitch);	aty_st_le32(CRTC_OFFSET, crtc->offset);	aty_st_le32(CRTC_OFFSET_CNTL, crtc->offset_cntl);	/* Disable ATOMIC updating.  Is this the right place? */	aty_st_pll(PPLL_CNTL, aty_ld_pll(PPLL_CNTL) & ~(0x00030000));}static int aty128_var_to_crtc(const struct fb_var_screeninfo *var,			      struct aty128_crtc *crtc,			      const struct aty128fb_par *par){	u32 xres, yres, vxres, vyres, xoffset, yoffset, bpp, dst;	u32 left, right, upper, lower, hslen, vslen, sync, vmode;	u32 h_total, h_disp, h_sync_strt, h_sync_wid, h_sync_pol;	u32 v_total, v_disp, v_sync_strt, v_sync_wid, v_sync_pol, c_sync;	u32 depth, bytpp;	u8 mode_bytpp[7] = { 0, 0, 1, 2, 2, 3, 4 };	/* input */	xres = var->xres;	yres = var->yres;	vxres   = var->xres_virtual;	vyres   = var->yres_virtual;	xoffset = var->xoffset;	yoffset = var->yoffset;	bpp   = var->bits_per_pixel;	left  = var->left_margin;	right = var->right_margin;	upper = var->upper_margin;	lower = var->lower_margin;	hslen = var->hsync_len;	vslen = var->vsync_len;	sync  = var->sync;	vmode = var->vmode;	if (bpp != 16)		depth = bpp;	else		depth = (var->green.length == 6) ? 16 : 15;	/* check for mode eligibility	 * accept only non interlaced modes */	if ((vmode & FB_VMODE_MASK) != FB_VMODE_NONINTERLACED)		return -EINVAL;	/* convert (and round up) and validate */	xres = (xres + 7) & ~7;	xoffset = (xoffset + 7) & ~7;	if (vxres < xres + xoffset)		vxres = xres + xoffset;	if (vyres < yres + yoffset)		vyres = yres + yoffset;	/* convert depth into ATI register depth */	dst = depth_to_dst(depth);	if (dst == -EINVAL) {		printk(KERN_ERR "aty128fb: Invalid depth or RGBA\n");		return -EINVAL;	}	/* convert register depth to bytes per pixel */	bytpp = mode_bytpp[dst];	/* make sure there is enough video ram for the mode */	if ((u32)(vxres * vyres * bytpp) > par->vram_size) {		printk(KERN_ERR "aty128fb: Not enough memory for mode\n");		return -EINVAL;	}	h_disp = (xres >> 3) - 1;	h_total = (((xres + right + hslen + left) >> 3) - 1) & 0xFFFFL;	v_disp = yres - 1;	v_total = (yres + upper + vslen + lower - 1) & 0xFFFFL;	/* check to make sure h_total and v_total are in range */	if (((h_total >> 3) - 1) > 0x1ff || (v_total - 1) > 0x7FF) {		printk(KERN_ERR "aty128fb: invalid width ranges\n");		return -EINVAL;	}	h_sync_wid = (hslen + 7) >> 3;	if (h_sync_wid == 0)		h_sync_wid = 1;	else if (h_sync_wid > 0x3f)        /* 0x3f = max hwidth */		h_sync_wid = 0x3f;	h_sync_strt = (h_disp << 3) + right;	v_sync_wid = vslen;	if (v_sync_wid == 0)		v_sync_wid = 1;	else if (v_sync_wid > 0x1f)        /* 0x1f = max vwidth */		v_sync_wid = 0x1f;    	v_sync_strt = v_disp + lower;	h_sync_pol = sync & FB_SYNC_HOR_HIGH_ACT ? 0 : 1;	v_sync_pol = sync & FB_SYNC_VERT_HIGH_ACT ? 0 : 1;    	c_sync = sync & FB_SYNC_COMP_HIGH_ACT ? (1 << 4) : 0;	crtc->gen_cntl = 0x3000000L | c_sync | (dst << 8);	crtc->h_total = h_total | (h_disp << 16);	crtc->v_total = v_total | (v_disp << 16);	crtc->h_sync_strt_wid = h_sync_strt | (h_sync_wid << 16) |	        (h_sync_pol << 23);	crtc->v_sync_strt_wid = v_sync_strt | (v_sync_wid << 16) |                (v_sync_pol << 23);	crtc->pitch = vxres >> 3;	crtc->offset = 0;	if ((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW)		crtc->offset_cntl = 0x00010000;	else		crtc->offset_cntl = 0;	crtc->vxres = vxres;	crtc->vyres = vyres;	crtc->xoffset = xoffset;	crtc->yoffset = yoffset;	crtc->depth = depth;	crtc->bpp = bpp;	return 0;}static int aty128_pix_width_to_var(int pix_width, struct fb_var_screeninfo *var){	/* fill in pixel info */	var->red.msb_right = 0;	var->green.msb_right = 0;	var->blue.offset = 0;	var->blue.msb_right = 0;	var->transp.offset = 0;	var->transp.length = 0;	var->transp.msb_right = 0;	switch (pix_width) {	case CRTC_PIX_WIDTH_8BPP:		var->bits_per_pixel = 8;		var->red.offset = 0;		var->red.length = 8;		var->green.offset = 0;		var->green.length = 8;		var->blue.length = 8;		break;	case CRTC_PIX_WIDTH_15BPP:		var->bits_per_pixel = 16;		var->red.offset = 10;		var->red.length = 5;		var->green.offset = 5;		var->green.length = 5;		var->blue.length = 5;		break;	case CRTC_PIX_WIDTH_16BPP:		var->bits_per_pixel = 16;		var->red.offset = 11;		var->red.length = 5;		var->green.offset = 5;		var->green.length = 6;		var->blue.length = 5;		break;	case CRTC_PIX_WIDTH_24BPP:		var->bits_per_pixel = 24;		var->red.offset = 16;		var->red.length = 8;		var->green.offset = 8;		var->green.length = 8;		var->blue.length = 8;		break;	case CRTC_PIX_WIDTH_32BPP:		var->bits_per_pixel = 32;		var->red.offset = 16;		var->red.length = 8;		var->green.offset = 8;		var->green.length = 8;		var->blue.length = 8;		var->transp.offset = 24;		var->transp.length = 8;		break;	default:		printk(KERN_ERR "aty128fb: Invalid pixel width\n");		return -EINVAL;	}	return 0;}static int aty128_crtc_to_var(const struct aty128_crtc *crtc,			      struct fb_var_screeninfo *var){	u32 xres, yres, left, right, upper, lower, hslen, vslen, sync;	u32 h_total, h_disp, h_sync_strt, h_sync_dly, h_sync_wid, h_sync_pol;	u32 v_total, v_disp, v_sync_strt, v_sync_wid, v_sync_pol, c_sync;	u32 pix_width;	/* fun with masking */	h_total     = crtc->h_total & 0x1ff;	h_disp      = (crtc->h_total >> 16) & 0xff;	h_sync_strt = (crtc->h_sync_strt_wid >> 3) & 0x1ff;	h_sync_dly  = crtc->h_sync_strt_wid & 0x7;	h_sync_wid  = (crtc->h_sync_strt_wid >> 16) & 0x3f;	h_sync_pol  = (crtc->h_sync_strt_wid >> 23) & 0x1;	v_total     = crtc->v_total & 0x7ff;	v_disp      = (crtc->v_total >> 16) & 0x7ff;	v_sync_strt = crtc->v_sync_strt_wid & 0x7ff;	v_sync_wid  = (crtc->v_sync_strt_wid >> 16) & 0x1f;	v_sync_pol  = (crtc->v_sync_strt_wid >> 23) & 0x1;	c_sync      = crtc->gen_cntl & CRTC_CSYNC_EN ? 1 : 0;	pix_width   = crtc->gen_cntl & CRTC_PIX_WIDTH_MASK;	/* do conversions */	xres  = (h_disp + 1) << 3;	yres  = v_disp + 1;	left  = ((h_total - h_sync_strt - h_sync_wid) << 3) - h_sync_dly;	right = ((h_sync_strt - h_disp) << 3) + h_sync_dly;	hslen = h_sync_wid << 3;	upper = v_total - v_sync_strt - v_sync_wid;	lower = v_sync_strt - v_disp;	vslen = v_sync_wid;	sync  = (h_sync_pol ? 0 : FB_SYNC_HOR_HIGH_ACT) |		(v_sync_pol ? 0 : FB_SYNC_VERT_HIGH_ACT) |		(c_sync ? FB_SYNC_COMP_HIGH_ACT : 0);	aty128_pix_width_to_var(pix_width, var);	var->xres = xres;	var->yres = yres;	var->xres_virtual = crtc->vxres;	var->yres_virtual = crtc->vyres;	var->xoffset = crtc->xoffset;	var->yoffset = crtc->yoffset;	var->left_margin  = left;	var->right_margin = right;	var->upper_margin = upper;	var->lower_margin = lower;	var->hsync_len = hslen;	var->vsync_len = vslen;	var->sync  = sync;	var->vmode = FB_VMODE_NONINTERLACED;	return 0;}static void aty128_set_crt_enable(struct aty128fb_par *par, int on){	if (on) {		aty_st_le32(CRTC_EXT_CNTL, aty_ld_le32(CRTC_EXT_CNTL) | CRT_CRTC_ON);		aty_st_le32(DAC_CNTL, (aty_ld_le32(DAC_CNTL) | DAC_PALETTE2_SNOOP_EN));	} else		aty_st_le32(CRTC_EXT_CNTL, aty_ld_le32(CRTC_EXT_CNTL) & ~CRT_CRTC_ON);}static void aty128_set_lcd_enable(struct aty128fb_par *par, int on){	u32 reg;	if (on) {		reg = aty_ld_le32(LVDS_GEN_CNTL);		reg |= LVDS_ON | LVDS_EN | LVDS_BLON | LVDS_DIGION;		reg &= ~LVDS_DISPLAY_DIS;		aty_st_le32(LVDS_GEN_CNTL, reg);#ifdef CONFIG_PMAC_BACKLIGHT		aty128_set_backlight_enable(get_backlight_enable(),					    get_backlight_level(), par);#endif		} else {#ifdef CONFIG_PMAC_BACKLIGHT		aty128_set_backlight_enable(0, 0, par);#endif			reg = aty_ld_le32(LVDS_GEN_CNTL);		reg |= LVDS_DISPLAY_DIS;		aty_st_le32(LVDS_GEN_CNTL, reg);		mdelay(100);		reg &= ~(LVDS_ON /*| LVDS_EN*/);		aty_st_le32(LVDS_GEN_CNTL, reg);	}}static void aty128_set_pll(struct aty128_pll *pll, const struct aty128fb_par *par){	u32 div3;	unsigned char post_conv[] =	/* register values for post dividers */        { 2, 0, 1, 4, 2, 2, 6, 2, 3, 2, 2, 2, 7 };	/* select PPLL_DIV_3 */	aty_st_le32(CLOCK_CNTL_INDEX, aty_ld_le32(CLOCK_CNTL_INDEX) | (3 << 8));	/* reset PLL */	aty_st_pll(PPLL_CNTL,		   aty_ld_pll(PPLL_CNTL) | PPLL_RESET | PPLL_ATOMIC_UPDATE_EN);	/* write the reference divider */	aty_pll_wait_readupdate(par);	aty_st_pll(PPLL_REF_DIV, par->constants.ref_divider & 0x3ff);	aty_pll_writeupdate(par);	div3 = aty_ld_pll(PPLL_DIV_3);	div3 &= ~PPLL_FB3_DIV_MASK;	div3 |= pll->feedback_divider;	div3 &= ~PPLL_POST3_DIV_MASK;	div3 |= post_conv[pll->post_divider] << 16;	/* write feedback and post dividers */	aty_pll_wait_readupdate(par);	aty_st_pll(PPLL_DIV_3, div3);	aty_pll_writeupdate(par);	aty_pll_wait_readupdate(par);	aty_st_pll(HTOTAL_CNTL, 0);	/* no horiz crtc adjustment */	aty_pll_writeupdate(par);	/* clear the reset, just in case */	aty_st_pll(PPLL_CNTL, aty_ld_pll(PPLL_CNTL) & ~PPLL_RESET);}static int aty128_var_to_pll(u32 period_in_ps, struct aty128_pll *pll,			     const struct aty128fb_par *par){	const struct aty128_constants c = par->constants;	unsigned char post_dividers[] = {1,2,4,8,3,6,12};	u32 output_freq;	u32 vclk;        /* in .01 MHz */	int i;	u32 n, d;	vclk = 100000000 / period_in_ps;	/* convert units to 10 kHz */	/* adjust pixel clock if necessary */	if (vclk > c.ppll_max)		vclk = c.ppll_max;	if (vclk * 12 < c.ppll_min)		vclk = c.ppll_min/12;	/* now, find an acceptable divider */	for (i = 0; i < sizeof(post_dividers); i++) {		output_freq = post_dividers[i] * vclk;		if (output_freq >= c.ppll_min && output_freq <= c.ppll_max)			break;	}	/* calculate feedback divider */	n = c.ref_divider * output_freq;	d = c.ref_clk;	pll->post_divider = post_dividers[i];	pll->feedback_divider = round_div(n, d);	pll->vclk = vclk;	DBG("post %d feedback %d vlck %d output %d ref_divider %d "	    "vclk_per: %d\n", pll->post_divider,	    pll->feedback_divider, vclk, output_freq,	    c.ref_divider, period_in_ps);	return 0;}static int aty128_pll_to_var(const struct aty128_pll *pll, struct fb_var_screeninfo *var){	var->pixclock = 100000000 / pll->vclk;	return 0;}static void aty128_set_fifo(const struct aty128_ddafifo *dsp,			    const struct aty128fb_par *par){	aty_st_le32(DDA_CONFIG, dsp->dda_config);	aty_st_le32(DDA_ON_OFF, dsp->dda_on_off);}static int aty128_ddafifo(struct aty128_ddafifo *dsp,			  const struct aty128_pll *pll,			  u32 depth,			  const struct aty128fb_par *par){	const struct aty128_meminfo *m = par->mem;	u32 xclk = par->constants.xclk;	u32 fifo_width = par->constants.fifo_width;	u32 fifo_depth = par->constants.fifo_depth;	s32 x, b, p, ron, roff;	u32 n, d, bpp;	/* round up to multiple of 8 */	bpp = (depth+7) & ~7;	n = xclk * fifo_width;	d = pll->vclk * bpp;	x = round_div(n, d);	ron = 4 * m->MB +		3 * ((m->Trcd - 2 > 0) ? m->Trcd - 2 : 0) +		2 * m->Trp +		m->Twr +		m->CL +		m->Tr2w +		x;	DBG("x %x\n", x);	b = 0;	while (x) {		x >>= 1;		b++;	}	p = b + 1;	ron <<= (11 - p);	n <<= (11 - p);	x = round_div(n, d);	roff = x * (fifo_depth - 4);	if ((ron + m->Rloop) >= roff) {		printk(KERN_ERR "aty128fb: Mode out of range!\n");		return -EINVAL;	}	DBG("p: %x rloop: %x x: %x ron: %x roff: %x\n",	    p, m->Rloop, x, ron, roff);	dsp->dda_config = p << 16 | m->Rloop << 20 | x;	dsp->dda_on_off = ron << 16 | roff;	return 0;}/* * This actually sets the video mode. */static int aty128fb_set_par(struct fb_info *info){ 	struct aty128fb_par *par = info->par;	u32 config;	int err;	if ((err = aty128_decode_var(&info->var, par)) != 0)		return err;	if (par->blitter_may_be_busy)		wait_for_idle(par);	/* clear all registers that may interfere with mode setting */	aty_st_le32(OVR_CLR, 0);	aty_st_le32(OVR_WID_LEFT_RIGHT, 0);	aty_st_le32(OVR_WID_TOP_BOTTOM, 0);	aty_st_le32(OV0_SCALE_CNTL, 0);	aty_st_le32(MPP_TB_CONFIG, 0);	aty_st_le32(MPP_GP_CONFIG, 0);	aty_st_le32(SUBPIC_CNTL, 0);	aty_st_le32(VIPH_CONTROL, 0);	aty_st_le32(I2C_CNTL_1, 0);         /* turn off i2c */	aty_st_le32(GEN_INT_CNTL, 0);	/* turn off interrupts */	aty_st_le32(CAP0_TRIG_CNTL, 0);	aty_st_le32(CAP1_TRIG_CNTL, 0);	aty_st_8(CRTC_EXT_CNTL + 1, 4);	/* turn video off */	aty128_set_crtc(&par->crtc, par);	aty128_set_pll(&par->pll, par);	aty128_set_fifo(&par->fifo_reg, par);	config = aty_ld_le32(CONFIG_CNTL) & ~3;#if defined(__BIG_ENDIAN)	if (par->crtc.bpp == 32)		config |= 2;	/* make aperture do 32 bit swapping */	else if (par->crtc.bpp == 16)		config |= 1;	/* make aperture do 16 bit swapping */

⌨️ 快捷键说明

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