display.c

来自「omap3 linux 2.6 用nocc去除了冗余代码」· C语言 代码 · 共 2,061 行 · 第 1/5 页

C
2,061
字号
			if(mirroring ==1) row_inc_value = row_inc_value - 				MAX_PIXELS_PER_LINE * ps;			else	row_inc_value = row_inc_value + MAX_PIXELS_PER_LINE * ps;		}		else{			if(mirroring ==1) row_inc_value = row_inc_value +				pix->width * ps / vr_ps;			else	row_inc_value = row_inc_value + pix->width * ps;		}		dispc_reg_out(DISPC_VID_ROW_INC(v), row_inc_value);		dispc_reg_out(DISPC_VID_PIXEL_INC(v), pixel_inc_value);	}	/*	 * Store BA0 BA1 for TV, BA1 points to the alternate row	 */	if(flicker_filter == 1){		layer[ltype].dma[1].row_inc = row_inc_value;	} else if (rotation_deg >= 0){		if(mirroring ==1) 			layer[ltype].dma[1].row_inc = row_inc_value - 				MAX_PIXELS_PER_LINE * ps;		else			layer[ltype].dma[1].row_inc = row_inc_value + 				MAX_PIXELS_PER_LINE * ps;	}	else{		if(mirroring ==1) 			layer[ltype].dma[1].row_inc = 				row_inc_value + pix->width * ps/vr_ps;		else	row_inc_value = row_inc_value + pix->width * ps;	}	layer[ltype].dma[1].pix_inc = pixel_inc_value;	layer[ltype].size_x = cropwidth;	layer[ltype].size_y = cropheight;	vid_position = ((vid_position_x << DISPC_VID_POSITION_VIDPOSX_SHIFT)			& DISPC_VID_POSITION_VIDPOSX)		| ((vid_position_y << DISPC_VID_POSITION_VIDPOSY_SHIFT)				& DISPC_VID_POSITION_VIDPOSY);	dispc_reg_out(DISPC_VID_POSITION(v), vid_position);	dispc_reg_out(DISPC_VID_SIZE(v), vid_size);	dispc_reg_out(DISPC_VID_PICTURE_SIZE(v), vid_picture_size);	omap2_disp_save_initstate(ltype);}/* Many display controller registers are shadowed. Setting the GO bit causes * changes to these registers to take effect in hardware. */voidomap2_disp_reg_sync(int output_dev){	if (output_dev == OMAP2_OUTPUT_LCD)		dispc_reg_merge(DISPC_CONTROL, DISPC_CONTROL_GOLCD,				DISPC_CONTROL_GOLCD);	else		dispc_reg_merge(DISPC_CONTROL, DISPC_CONTROL_GODIGITAL,				DISPC_CONTROL_GODIGITAL);}/* This function provides the status of the GO bit. After the GO bit is set * through software, register changes take affect at the next VFP (vertical * front porch) or EVSYNC. Per the specs, no further register changes * must be done until the GO bit is reset by hardware. This function allows * drivers to poll the status of the GO bit, and wait until it is reset if they * wish to. */intomap2_disp_reg_sync_done(int output_dev){	u32 control = dispc_reg_in(DISPC_CONTROL);	if (output_dev == OMAP2_OUTPUT_LCD)		return ~(control & DISPC_CONTROL_GOLCD);	else		return ~(control & DISPC_CONTROL_GODIGITAL);}/* This function turns on/off the clocks needed for TV-out. *  - 2430SDP: Controls the dss_54m_fck  *  - 3430SDP: Controls the dss_tv_fck  *  - 3430LAB: Controls both dss_tv_fck and dss_96m_fck. *             By default Labrador turns off the 96MHz DAC clock for *             power saving reasons. */static voidomap24xx_ll_config_tv_clocks(int sleep_state){	static int start = 1;	static struct clk *tv_clk;	static int disabled = 0;	static int enabled = 0;	if(start) {		tv_clk = clk_get(NULL,"dss_tv_fck");		if(IS_ERR(tv_clk)) {			printk("\n UNABLE to get dss TV fclk \n");			return;		}		start = 0;	}	if (sleep_state == 1) {		if (disabled == 0) {				clk_disable(tv_clk);			disabled = 1;		}		enabled = 0;	}	else {		if (enabled == 0) {			if(clk_enable(tv_clk) != 0) {				printk("\n UNABLE to enable dss TV fclk \n");				return;			}			enabled = 1;		}		disabled = 0;	}}/* * Disable the display controller. May be called in interrupt or process * context. However, this function should not be called with interrupts * disabled as jiffies will not increment. */voidomap2_disp_disable(unsigned long timeout_ticks){	unsigned long timeout;	if (dispc_reg_in(DISPC_CONTROL)			& (DISPC_CONTROL_DIGITALENABLE | DISPC_CONTROL_LCDENABLE))	{		/* disable the display controller */		dispc_reg_merge(DISPC_CONTROL, 0,				DISPC_CONTROL_DIGITALENABLE | DISPC_CONTROL_LCDENABLE);		/* wait for any frame in progress to complete */		dispc_reg_out(DISPC_IRQSTATUS,				DISPC_IRQSTATUS_FRAMEDONE);		timeout = jiffies + timeout_ticks;		while(!(dispc_reg_in(DISPC_IRQSTATUS)					& DISPC_IRQSTATUS_FRAMEDONE)				&& time_before(jiffies, timeout))		{			int a_ctx = (in_atomic() || irqs_disabled() 					|| in_interrupt());			if (!a_ctx) {				set_current_state(TASK_INTERRUPTIBLE);				schedule_timeout(1);			} else				udelay(100);		}		if (!(dispc_reg_in(DISPC_IRQSTATUS)					& DISPC_IRQSTATUS_FRAMEDONE)) {			printk(KERN_WARNING "timeout waiting for "					"frame-done interrupt\n");		}		omap24xx_ll_config_tv_clocks(1);	}	return;}voidomap2_disp_set_gfx_palette(u32 palette_ba){	dispc_reg_out(DISPC_GFX_TABLE_BA, palette_ba);	dispc_reg_merge(DISPC_CONFIG, DISPC_CONFIG_LOADMODE_PGTABUSETB,			DISPC_CONFIG_LOADMODE_PGTABUSETB);}/* Configure Graphics layer parameters */voidomap2_disp_config_gfxlayer(u32 size_x, u32 size_y, int color_depth){	u32 config = 0;	u32 gfx_attributes = 0, gfx_fifo_threshold = 0, gfx_format = 0;	u32 gfx_position = 0, gfx_window_skip = 0;	config = dispc_reg_in(DISPC_CONFIG);	config |= (DISPC_CONFIG_LOADMODE_PGTABUSETB |			DISPC_CONFIG_LOADMODE_FRDATLEFR);	/* This driver doesn't currently support the video windows, so	 * we force the palette/gamma table to be a palette table and	 * force both video windows to be disabled.	 */	config &= ~DISPC_CONFIG_PALETTEGAMMATABLE;	gfx_attributes = DISPC_GFX_ATTRIBUTES_GFXBURSTSIZE_BURST16X32;	/* enable the graphics window only if its size is not zero */	gfx_fifo_threshold =		(RMODE_GFX_FIFO_HIGH_THRES << DISPC_GFX_FIFO_THRESHOLD_HIGH_SHIFT) |		(RMODE_GFX_FIFO_LOW_THRES << DISPC_GFX_FIFO_THRESHOLD_LOW_SHIFT);	gfx_position = 0;	gfx_window_skip = 0;	switch(color_depth) {		case 1:			gfx_format = DISPC_GFX_ATTRIBUTES_GFXFORMAT_BITMAP1;			break;		case 2:			gfx_format = DISPC_GFX_ATTRIBUTES_GFXFORMAT_BITMAP2;			break;		case 4:			gfx_format = DISPC_GFX_ATTRIBUTES_GFXFORMAT_BITMAP4;			break;		case 8:			gfx_format = DISPC_GFX_ATTRIBUTES_GFXFORMAT_BITMAP8;			break;		case 12:			gfx_format = DISPC_GFX_ATTRIBUTES_GFXFORMAT_RGB12;			break;		case 16:			gfx_format = DISPC_GFX_ATTRIBUTES_GFXFORMAT_RGB16;			break;		case 24:			gfx_format = DISPC_GFX_ATTRIBUTES_GFXFORMAT_RGB24;			break;		case 32:			gfx_format = DISPC_GFX_ATTRIBUTES_GFXFORMAT_RGBA32;			break;		default:			gfx_format = dispc_reg_in(DISPC_GFX_ATTRIBUTES)				& DISPC_GFX_ATTRIBUTES_GFXFORMAT;			break;	}	gfx_attributes |= gfx_format;	dispc_reg_out(DISPC_GFX_FIFO_THRESHOLD, gfx_fifo_threshold);	dispc_reg_out(DISPC_GFX_POSITION, gfx_position);	dispc_reg_out(DISPC_GFX_WINDOW_SKIP, gfx_window_skip);	dispc_reg_out(DISPC_CONFIG, config);	dispc_reg_out(DISPC_GFX_ATTRIBUTES, gfx_attributes);	layer[OMAP2_GRAPHICS].size_x = size_x;	layer[OMAP2_GRAPHICS].size_y = size_y;}/* Calculate the number of pixels sent to the display per pixel clock as * (nom/den) pixels per clock. */voidomap2_disp_pixels_per_clock(unsigned int *nom, unsigned int *den){	u32 dispc_control;	dispc_control = dispc_reg_in(DISPC_CONTROL);	if (dispc_control & DISPC_CONTROL_STNTFT) {		/* active display (TFT) */		if (dispc_control & DISPC_CONTROL_TDMENABLE) {			/* TFT with TDM */			switch (dispc_control & DISPC_CONTROL_TDMCYCLEFORMAT) {				case DISPC_CONTROL_TDMCYCLEFORMAT_1CYCPERPIX:					*nom = 1;					*den = 1;					break;				case DISPC_CONTROL_TDMCYCLEFORMAT_2CYCPERPIX:					*nom = 1;					*den = 2;					break;				case DISPC_CONTROL_TDMCYCLEFORMAT_3CYCPERPIX:					*nom = 1;					*den = 3;					break;				case DISPC_CONTROL_TDMCYCLEFORMAT_3CYCPER2PIX:					*nom = 2;					*den = 3;					break;			}		}		else {			/* TFT without TDM */			*nom = 1;			*den = 1;		}	}	else {		/* passive display (STN) */		if (dispc_control & DISPC_CONTROL_MONOCOLOR) {			/* STN mono */			if (dispc_control & DISPC_CONTROL_M8B) {				/* 8 pixels per pixclock */				*nom = 8;				*den = 1;			}			else {				/* 4 pixels per pixclock */				*nom = 4;				*den = 1;			}		}		else {			/* STN color--8 pixels per 3 pixclocks */			*nom = 8;			*den = 3;		}	}}/* Configure the signal configuration for LCD panel */voidomap2_disp_lcdcfg_polfreq(u32 hsync_high, u32 vsync_high,				u32 acb,u32 ipc, u32 onoff){	u32 pol_freq = 0;	/* set the sync polarity */	if (!hsync_high)		pol_freq &=  ~DISPC_POL_FREQ_IHS;	else		pol_freq |=  DISPC_POL_FREQ_IHS;	if (!vsync_high)		pol_freq &= ~DISPC_POL_FREQ_IVS;	else		pol_freq |=  DISPC_POL_FREQ_IVS;	pol_freq |= acb | (ipc << DISPC_POL_FREQ_IPC_SHIFT) <<		(onoff << DISPC_POL_FREQ_ONOFF_SHIFT) ;	dispc_reg_out(DISPC_POL_FREQ, pol_freq);}/* Configure LCD parameters */void omap2_disp_config_lcd(u32 clkdiv, u32 hbp, u32 hfp, u32 hsw,					u32 vbp, u32 vfp, u32 vsw){	u32 control, divisor, timing_h, timing_v;	divisor = (1 << DISPC_DIVISOR_LCD_SHIFT) 		| (2 << DISPC_DIVISOR_PCD_SHIFT); //clkdiv replaced with 2	if (hbp > 255) hbp = 255;	if (hfp > 255) hfp = 255; 	if (hsw > 63)  hsw = 63;	if (vbp > 255) vbp = 255;	if (vfp > 255) vfp = 255;	if (vsw > 63)  vsw = 63;	timing_h = (hbp << DISPC_TIMING_H_HBP_SHIFT) | (hfp << DISPC_TIMING_H_HFP_SHIFT) 		| (hsw << DISPC_TIMING_H_HSW_SHIFT);	timing_v = (vbp << DISPC_TIMING_V_VBP_SHIFT) | (vfp << DISPC_TIMING_V_VFP_SHIFT)		| (vsw << DISPC_TIMING_V_VSW_SHIFT);//	dispc_reg_out(DISPC_TIMING_H, timing_h);//	dispc_reg_out(DISPC_TIMING_V, timing_v);	dispc_reg_out(DISPC_TIMING_H, 0x0FF03F31);	dispc_reg_out(DISPC_TIMING_V, 0x01400504);	dispc_reg_out(DISPC_DIVISOR, divisor);	control = dispc_reg_in(DISPC_CONTROL);	control |= DISPC_CONTROL_TFTDATALINES_OALSB18B;	control |= DISPC_CONTROL_GPOUT1	| DISPC_CONTROL_GPOUT0 		| DISPC_CONTROL_STNTFT;	dispc_reg_out(DISPC_CONTROL, control);}/* Set the pixel clock divisor for the LCD */voidomap2_disp_set_pcd(u32 pcd){	dispc_reg_out(DISPC_DIVISOR, (1 << DISPC_DIVISOR_LCD_SHIFT) |			(pcd << DISPC_DIVISOR_PCD_SHIFT));}/* * Set the DSS Functional clock * The DSS clock should be 4 times the Panel's Pixel clock * For TV the Pixel clock required is 13.5Mhz * For LCD the Pixel clock is 6Mhz */voidomap2_disp_set_dssfclk(void){	/* TODO set the LCD pixel clock rate based on the LCD configuration */	static int LCD_pixel_clk = 26000000; /* to get more bandwidth*/	static int TV_pixel_clk  = 14000000; /* rounded 13.5 to 14*/	u32 ask_clkrate=0,sup_clkrate=0,tgt_clkrate=0,i;//	ask_clkrate = LCD_pixel_clk * 4;	if(ask_clkrate < (TV_pixel_clk * 4))		ask_clkrate = TV_pixel_clk * 4;	ask_clkrate = 148500000;	tgt_clkrate = ask_clkrate;	sup_clkrate = clk_round_rate(dss1f_scale, ask_clkrate);	if(is_sil_rev_less_than(OMAP3430_REV_ES2_0)){		if(clk_get_rate(dss1f_scale) == 96000000){			/*96M already, dont do anything for ES 1.0

⌨️ 快捷键说明

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