display.c

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

C
2,061
字号
/* * arch/arm/mach-omap2/display.c * * Copyright (C) 2005-2006 Texas Instruments, Inc. * * This file is licensed under the terms of the GNU General Public License * version 2. This program is licensed "as is" without any warranty of any * kind, whether express or implied. * * Leveraged code from the OMAP24xx camera driver * Video-for-Linux (Version 2) camera capture driver for * the OMAP24xx camera controller. * * Author: Andy Lowe (source@mvista.com) * Copyright (C) 2004 MontaVista Software, Inc. * * History: * 20-APR-2006  Khasim		Modified VRFB based Rotation equations, *				The image data is always read from 0 degree  *				view and written to the virtual space of desired  *				rotation angle */#include <linux/module.h>#include <linux/delay.h>#include <linux/interrupt.h>#include <linux/err.h>#include <asm/system.h>#include <asm/io.h>#include <asm/irq.h>#include <asm/arch/hardware.h>#include <asm/arch/display.h>#include <asm/arch/venc.h>#include <asm/arch/clock.h>extern int lpr_enabled;/* usage count for DSS power management */static int disp_usage;static int omap2_current_tvstandard = NTSC_M;static spinlock_t dss_lock;short int current_colorconv_values[2][3][3];static struct omap_dss_regs dss_ctx;static struct clk *dss1f_scale;static struct tvlcd_status_t tvlcd_status;static struct clk *dss1f, *dss1i;struct omap2_disp_dma_params {	u32 ba0;	u32 ba1;	int row_inc;	int pix_inc;};static struct layer_t {	int output_dev;	int in_use;	int ctx_valid;	/* one set of dma parameters each for LCD and TV */	struct omap2_disp_dma_params dma[2];	int size_x;	int size_y;} layer[DSS_CTX_NUMBER] = {	{.ctx_valid = 0,},	{.ctx_valid = 0,},	{.ctx_valid = 0,},	{.ctx_valid = 0,},	{.ctx_valid = 0,},};#define MAX_ISR_NR   8static int omap2_disp_irq;static struct {	omap2_disp_isr_t isr;	void *arg;	unsigned int mask;} registered_isr[MAX_ISR_NR];/* VRFB offset computation parameters */#define SIDE_H		1 #define SIDE_W		0 /* GFX FIFO thresholds */#define RMODE_GFX_FIFO_HIGH_THRES	0x3FC#define RMODE_GFX_FIFO_LOW_THRES	0x3BC/* * DSS register I/O routines */static __inline__ u32dss_reg_in(u32 offset){	return  omap_readl(DSS_REG_BASE + DSS_REG_OFFSET + offset);}static __inline__ u32dss_reg_out(u32 offset, u32 val){	omap_writel(val,DSS_REG_BASE + DSS_REG_OFFSET + offset);	return val;}static __inline__ u32dss_reg_merge(u32 offset, u32 val, u32 mask){	u32 addr = DSS_REG_BASE + DSS_REG_OFFSET + offset;	u32 new_val = (omap_readl(addr) & ~mask) | (val & mask);	omap_writel(new_val, addr);	return new_val;}/* * Display controller register I/O routines */static __inline__ u32dispc_reg_in(u32 offset){	return omap_readl(DSS_REG_BASE + DISPC_REG_OFFSET + offset);}static __inline__ u32dispc_reg_out(u32 offset, u32 val){	omap_writel(val, DSS_REG_BASE + DISPC_REG_OFFSET + offset);	return val;}static __inline__ u32dispc_reg_merge(u32 offset, u32 val, u32 mask){	u32 addr = DSS_REG_BASE + DISPC_REG_OFFSET + offset;	u32 new_val = (omap_readl(addr) & ~mask) | (val & mask);	omap_writel(new_val, addr);	return new_val;}/* * RFBI controller register I/O routines */static __inline__ u32rfbi_reg_in(u32 offset){	return omap_readl(DSS_REG_BASE + RFBI_REG_OFFSET + offset);}static __inline__ u32rfbi_reg_out(u32 offset, u32 val){	omap_writel(val, DSS_REG_BASE + RFBI_REG_OFFSET + offset);	return val;}/* * VENC register I/O Routines */static __inline__ u32venc_reg_in(u32 offset){	return omap_readl(DSS_REG_BASE + VENC_REG_OFFSET + offset);}static __inline__ u32venc_reg_out(u32 offset, u32 val){	omap_writel(val, DSS_REG_BASE + VENC_REG_OFFSET + offset);	return val;}static __inline__ u32venc_reg_merge(u32 offset, u32 val, u32 mask){	u32 addr = DSS_REG_BASE + VENC_REG_OFFSET + offset;	u32 new_val = (omap_readl(addr) & ~mask) | (val & mask);	omap_writel(new_val, addr);	return new_val;}/* Write the color space conversion coefficients to the display controller * registers.  Each coefficient is a signed 11-bit integer in the range * [-1024, 1023].  The matrix coefficients are: *	[ RY  RCr  RCb ] *	[ GY  GCr  GCb ] *	[ BY  BCr  BCb ] */static voidset_colorconv(int v,int colorspace){	unsigned long ccreg;	short int mtx[3][3];	int i,j;	for(i=0;i<3;i++)		for(j=0;j<3;j++){			mtx[i][j] = current_colorconv_values[v][i][j];		}	ccreg = (mtx[0][0] & 0x7ff) | ((mtx[0][1] & 0x7ff) << 16);	dispc_reg_out(DISPC_VID_CONV_COEF0(v), ccreg);	ccreg = (mtx[0][2] & 0x7ff) | ((mtx[1][0] & 0x7ff) << 16);	dispc_reg_out(DISPC_VID_CONV_COEF1(v), ccreg);	ccreg = (mtx[1][1] & 0x7ff) | ((mtx[1][2] & 0x7ff) << 16);	dispc_reg_out(DISPC_VID_CONV_COEF2(v), ccreg);	ccreg = (mtx[2][0] & 0x7ff) | ((mtx[2][1] & 0x7ff) << 16);	dispc_reg_out(DISPC_VID_CONV_COEF3(v), ccreg);	ccreg = mtx[2][2] & 0x7ff;	dispc_reg_out(DISPC_VID_CONV_COEF4(v), ccreg);	if(colorspace == V4L2_COLORSPACE_JPEG || 			colorspace == V4L2_COLORSPACE_SRGB){		dispc_reg_merge(DISPC_VID_ATTRIBUTES(v), 			DISPC_VID_ATTRIBUTES_VIDFULLRANGE, 			DISPC_VID_ATTRIBUTES_VIDFULLRANGE);	}}static voidupdate_colorconv_mtx(int v,const short int mtx[3][3]){	int i,j;	for(i=0;i<3;i++)		for(j=0;j<3;j++)			current_colorconv_values[v][i][j] = mtx[i][j];}voidomap2_disp_set_default_colorconv(int ltype, struct v4l2_pix_format *pix){	int v;	if (ltype == OMAP2_VIDEO1) v = 0;	else if (ltype == OMAP2_VIDEO2) v = 1;	else return;	switch (pix->colorspace) {	case V4L2_COLORSPACE_SMPTE170M:	case V4L2_COLORSPACE_SMPTE240M:	case V4L2_COLORSPACE_BT878:	case V4L2_COLORSPACE_470_SYSTEM_M:	case V4L2_COLORSPACE_470_SYSTEM_BG:		/* luma (Y) range lower limit is 16, BT.601 standard */		update_colorconv_mtx(v,cc_bt601);		set_colorconv(v,pix->colorspace);		break;	case V4L2_COLORSPACE_REC709:		/* luma (Y) range lower limit is 16, BT.709 standard */		update_colorconv_mtx(v,cc_bt709);		set_colorconv(v,pix->colorspace);		break;	case V4L2_COLORSPACE_JPEG:	case V4L2_COLORSPACE_SRGB:		/* full luma (Y) range, assume BT.601 standard */		update_colorconv_mtx(v,cc_bt601_full);		set_colorconv(v,pix->colorspace);		break;	}}voidomap2_disp_set_colorconv(int ltype, struct v4l2_pix_format *pix){	int v;	if (ltype == OMAP2_VIDEO1) v = 0;	else if (ltype == OMAP2_VIDEO2) v = 1;	else return;	set_colorconv(v,pix->colorspace);}/* Write the horizontal and vertical resizing coefficients to the display * controller registers.  Each coefficient is a signed 8-bit integer in the * range [-128, 127] except for the middle coefficient (vc[1][i] and hc[3][i]) * which is an unsigned 8-bit integer in the range [0, 255].  The first index of * the matrix is the coefficient number (0 to 2 vertical or 0 to 4 horizontal) * and the second index is the phase (0 to 7). */static voidomap2_disp_set_resize(int v, short int *vc, short int *hc){	int i;	unsigned long reg;	for (i = 0; i < 8; i++) {		reg = (*(hc+(8*0)+i) & 0xff) | ((*(hc+(8*1)+i) & 0xff) << 8)			| ((*(hc+(8*2)+i) & 0xff) << 16) | ((*(hc+(8*3)+i) & 0xff) << 24);		dispc_reg_out(DISPC_VID_FIR_COEF_H(v, i), reg);		reg = (*(hc+(8*4)+i) & 0xff) | ((*(vc+(0*8)+i) & 0xff) << 8)			| ((*(vc+(8*1)+i) & 0xff) << 16) | ((*(vc+(2*8)+i) & 0xff) << 24);		dispc_reg_out(DISPC_VID_FIR_COEF_HV(v, i), reg);	}}/*---------------------------------------------------------------------------*/voidomap2_disp_get_panel_size(int output_dev, int *width, int *height){	unsigned long size;	if (output_dev == OMAP2_OUTPUT_TV) {		size = dispc_reg_in(DISPC_SIZE_DIG);		*width = 1 + ((size & DISPC_SIZE_DIG_PPL)				>> DISPC_SIZE_DIG_PPL_SHIFT);		*height = 1 + ((size & DISPC_SIZE_DIG_LPP)				>> DISPC_SIZE_DIG_LPP_SHIFT);		*height = *height << 1;	}	else if (output_dev == OMAP2_OUTPUT_LCD) {		size = dispc_reg_in(DISPC_SIZE_LCD);		*width = 1 + ((size & DISPC_SIZE_LCD_PPL)				>> DISPC_SIZE_LCD_PPL_SHIFT);		*height = 1 + ((size & DISPC_SIZE_LCD_LPP)				>> DISPC_SIZE_LCD_LPP_SHIFT);	}}voidomap2_disp_set_panel_size(int output_dev, int width, int height){	unsigned long size;	if (output_dev == OMAP2_OUTPUT_TV) {		height = height >> 1;		size = ((width - 1) << DISPC_SIZE_DIG_PPL_SHIFT) &  DISPC_SIZE_DIG_PPL;		size |= ((height - 1) << DISPC_SIZE_DIG_LPP_SHIFT) 									& DISPC_SIZE_DIG_LPP;		dispc_reg_out(DISPC_SIZE_DIG, size);	}	else if (output_dev == OMAP2_OUTPUT_LCD) {		size = ((width - 1) << DISPC_SIZE_LCD_PPL_SHIFT) & DISPC_SIZE_LCD_PPL;		size |= ((height - 1) << DISPC_SIZE_LCD_LPP_SHIFT) 									& DISPC_SIZE_LCD_LPP;		//dispc_reg_out(DISPC_SIZE_LCD, size);		dispc_reg_out(DISPC_SIZE_LCD,0x02FF03FF);	}}static int graphics_in_use;/* Turn off the GFX, or video1, or video2 layer. */voidomap2_disp_disable_layer(int ltype){	unsigned long attributes;	int digital, v;	if (ltype == OMAP2_GRAPHICS) {		attributes = dispc_reg_merge(DISPC_GFX_ATTRIBUTES, 0,				DISPC_GFX_ATTRIBUTES_ENABLE);		digital = attributes & DISPC_GFX_ATTRIBUTES_GFXCHANNELOUT;		graphics_in_use = 0;	}	else {		if (ltype == OMAP2_VIDEO1) v = 0;		else if (ltype == OMAP2_VIDEO2) v = 1;		else return;		attributes = dispc_reg_merge(DISPC_VID_ATTRIBUTES(v), 0,			DISPC_VID_ATTRIBUTES_ENABLE);		digital = attributes & DISPC_VID_ATTRIBUTES_VIDCHANNELOUT;	}	if (digital) {		/* digital output */		dispc_reg_merge(DISPC_CONTROL, DISPC_CONTROL_GODIGITAL,			DISPC_CONTROL_GODIGITAL);	}	else {		/* LCD */		dispc_reg_merge(DISPC_CONTROL, DISPC_CONTROL_GOLCD,			DISPC_CONTROL_GOLCD);	}		dispc_reg_merge(DISPC_CONTROL, 0,			 DISPC_CONTROL_OVERLAYOPTIMIZATION);}/* Turn on the GFX, or video1, or video2 layer. */voidomap2_disp_enable_layer(int ltype){	unsigned long attributes;	int digital, v;	if (ltype == OMAP2_GRAPHICS) {		attributes = dispc_reg_merge(DISPC_GFX_ATTRIBUTES,			DISPC_GFX_ATTRIBUTES_ENABLE, DISPC_GFX_ATTRIBUTES_ENABLE);		digital = attributes & DISPC_GFX_ATTRIBUTES_GFXCHANNELOUT;		graphics_in_use = 1;	}	else {		if (ltype == OMAP2_VIDEO1) v = 0;		else if (ltype == OMAP2_VIDEO2) v = 1;		else return;		attributes = dispc_reg_merge(DISPC_VID_ATTRIBUTES(v),			DISPC_VID_ATTRIBUTES_ENABLE, DISPC_VID_ATTRIBUTES_ENABLE);		digital = attributes & DISPC_VID_ATTRIBUTES_VIDCHANNELOUT;	}	if (digital) {		/* digital output */		dispc_reg_merge(DISPC_CONTROL, DISPC_CONTROL_GODIGITAL,			DISPC_CONTROL_GODIGITAL);	}	else {		/* LCD */		dispc_reg_merge(DISPC_CONTROL, DISPC_CONTROL_GOLCD,

⌨️ 快捷键说明

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