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

📄 s3c_pp_6400.c

📁 s3c6400 post processor decoder
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * linux/drivers/video/s3c_pp_6400.c * * Revision 1.0   * * * This file is subject to the terms and conditions of the GNU General Public * License.  See the file COPYING in the main directory of this archive for * more details. * *	    S3C PostProcessor driver  * */#include <linux/init.h>#include <linux/module.h>#include <linux/moduleparam.h>#include <linux/types.h>#include <linux/timer.h>#include <linux/kernel.h>#include <linux/fs.h>#include <linux/platform_device.h>#include <linux/interrupt.h>#include <linux/clk.h>#include <linux/delay.h>#include <asm/uaccess.h>#include <linux/errno.h> /* error codes */#include <asm/div64.h>#include <linux/mm.h>#include <linux/tty.h>#include <asm/io.h>#include <asm/irq.h>#include <asm/hardware.h>#include <asm/uaccess.h>#include <asm/arch/map.h>#include <linux/miscdevice.h>#include <linux/poll.h>#include <linux/mutex.h>#include <linux/init.h>#include <linux/version.h>#if LINUX_VERSION_CODE == KERNEL_VERSION(2,6,16)#include <linux/config.h>#include <asm/arch/registers.h>#include <asm/arch-s3c64xx/reserved_mem.h>#else#include <asm/arch/regs-pp.h>#include <asm/arch/regs-lcd.h>#include <asm/arch-s3c2410/regs-s3c6400-clock.h>#include <asm/arch-s3c2410/reserved_mem.h>#include <linux/pm.h>#include <asm/plat-s3c24xx/pm.h>#endif#include "s3c_pp_common.h"#define PFX "s3c_pp"#define NO_PIP_MODE	1	// Currently, Do not support PIP mode// if you want to modify src/dst buffer size, modify below defined size #define SYSTEM_RAM			0x07000000	// 128mb#define RESERVE_POST_MEM	8*1024*1024	// 8mb#define PRE_BUFF_SIZE		4*1024*1024	//4 // 4mb#define POST_BUFF_SIZE		( RESERVE_POST_MEM - PRE_BUFF_SIZE )#define POST_BUFF_BASE_ADDR	POST_RESERVED_MEM_START#define USE_DEDICATED_MEM	1static struct resource *s3c_pp_mem;static void __iomem *s3c_pp_base;static int s3c_pp_irq = NO_IRQ;static struct clk *pp_clock;static struct clk *h_clk;static struct mutex *h_mutex;static wait_queue_head_t waitq;void set_scaler_register(scaler_info_t * scaler_info, pp_params *pParams){	__raw_writel((scaler_info->pre_v_ratio<<7)|(scaler_info->pre_h_ratio<<0), s3c_pp_base + S3C_VPP_PRESCALE_RATIO);	__raw_writel((scaler_info->pre_dst_height<<12)|(scaler_info->pre_dst_width<<0), s3c_pp_base + S3C_VPP_PRESCALEIMGSIZE);	__raw_writel(scaler_info->sh_factor, s3c_pp_base + S3C_VPP_PRESCALE_SHFACTOR);	__raw_writel(scaler_info->dx, s3c_pp_base + S3C_VPP_MAINSCALE_H_RATIO);	__raw_writel(scaler_info->dy, s3c_pp_base + S3C_VPP_MAINSCALE_V_RATIO);	__raw_writel((pParams->SrcHeight<<12)|(pParams->SrcWidth), s3c_pp_base + S3C_VPP_SRCIMGSIZE);	__raw_writel((pParams->DstHeight<<12)|(pParams->DstWidth), s3c_pp_base + S3C_VPP_DSTIMGSIZE);}void set_buf_addr_register(buf_addr_t *buf_addr, pp_params *pParams){	__raw_writel(buf_addr->src_start_y, s3c_pp_base + S3C_VPP_ADDRSTART_Y);	__raw_writel(buf_addr->offset_y, s3c_pp_base + S3C_VPP_OFFSET_Y);	__raw_writel(buf_addr->src_end_y, s3c_pp_base + S3C_VPP_ADDREND_Y);	if(pParams->SrcCSpace == YC420) {		__raw_writel(buf_addr->src_start_cb, s3c_pp_base + S3C_VPP_ADDRSTART_CB);		__raw_writel(buf_addr->offset_cr, s3c_pp_base + S3C_VPP_OFFSET_CB);		__raw_writel(buf_addr->src_end_cb, s3c_pp_base + S3C_VPP_ADDREND_CB);		__raw_writel(buf_addr->src_start_cr, s3c_pp_base + S3C_VPP_ADDRSTART_CR);		__raw_writel(buf_addr->offset_cb, s3c_pp_base + S3C_VPP_OFFSET_CR);		__raw_writel(buf_addr->src_end_cr, s3c_pp_base + S3C_VPP_ADDREND_CR);		}	if(pParams->OutPath == POST_DMA) {		__raw_writel(buf_addr->dst_start_rgb, s3c_pp_base + S3C_VPP_ADDRSTART_RGB);		__raw_writel(buf_addr->offset_rgb, s3c_pp_base + S3C_VPP_OFFSET_RGB);		__raw_writel(buf_addr->dst_end_rgb, s3c_pp_base + S3C_VPP_ADDREND_RGB);		if(pParams->DstCSpace == YC420) {			__raw_writel(buf_addr->out_src_start_cb, s3c_pp_base + S3C_VPP_ADDRSTART_OCB);			__raw_writel(buf_addr->out_offset_cb, s3c_pp_base + S3C_VPP_OFFSET_OCB);			__raw_writel(buf_addr->out_src_end_cb, s3c_pp_base + S3C_VPP_ADDREND_OCB);			__raw_writel(buf_addr->out_src_start_cr, s3c_pp_base + S3C_VPP_ADDRSTART_OCR);			__raw_writel(buf_addr->out_offset_cr, s3c_pp_base + S3C_VPP_OFFSET_OCR);			__raw_writel(buf_addr->out_src_end_cr, s3c_pp_base + S3C_VPP_ADDREND_OCR);		}	}}void set_data_format_register(pp_params *pParams){	u32 tmp;	tmp = __raw_readl(s3c_pp_base + S3C_VPP_MODE);	tmp |= (0x1<<16);	tmp |= (0x2<<10);	// set the source color space	switch(pParams->SrcCSpace) {		case YC420:			tmp &=~((0x1<<3)|(0x1<<2));			tmp |= (0x1<<8)|(0x1<<1);			break;		case YCBYCR:			tmp &= ~((0x1<<15)|(0x1<<8)|(0x1<<3)|(0x1<<0));			tmp |= (0x1<<2)|(0x1<<1);			break;		case YCRYCB:			tmp &= ~((0x1<<8)|(0x1<<3)|(0x1<<0));			tmp |= (0x1<<15)|(0x1<<2)|(0x1<<1);			break;		case CBYCRY:			tmp &= ~((0x1<<15)|(0x1<<8)|(0x1<<3));			tmp |= (0x1<<2)|(0x1<<1)|(0x1<<0);			break;		case CRYCBY:			tmp &= ~((0x1<<8)|(0x1<<3));			tmp |= (0x1<<15)|(0x1<<2)|(0x1<<1)|(0x1<<0);				break;		case RGB24:			tmp &= ~(0x1<<8);			tmp |=  (0x1<<3)|(0x1<<2)|(0x1<<1);			break;		case RGB16:			tmp &= ~((0x1<<8)|(0x1<<1));			tmp |=  (0x1<<3)|(0x1<<2);			break;		default:			break;	}	// set the destination color space	if(pParams->OutPath == POST_DMA) {		switch(pParams->DstCSpace) {			case YC420:				tmp &= ~(0x1<<18);				tmp |= (0x1<<17);				break;			case YCBYCR:				tmp &= ~((0x1<<20)|(0x1<<19)|(0x1<<18)|(0x1<<17));				break;			case YCRYCB:				tmp &= ~((0x1<<19)|(0x1<<18)|(0x1<<17));				tmp |= (0x1<<20);				break;			case CBYCRY:				tmp &= ~((0x1<<20)|(0x1<<18)|(0x1<<17));				tmp |= (0x1<<19);				break;			case CRYCBY:				tmp &= ~((0x1<<18)|(0x1<<17));				tmp |= (0x1<<20)|(0x1<<19);					break;			case RGB24:				tmp |= (0x1<<18)|(0x1<<4);				break;			case RGB16:				tmp &= ~(0x1<<4);				tmp |= (0x1<<18);				break;			default:				break;		}	}	else if(pParams->OutPath == POST_FIFO) {		if(pParams->DstCSpace == RGB30) {			tmp |= (0x1<<18)|(0x1<<13); 		} else if(pParams->DstCSpace == YUV444) {			tmp |= (0x1<<13);			tmp &= ~(0x1<<18)|(0x1<<17);		} 		}	__raw_writel(tmp, s3c_pp_base + S3C_VPP_MODE);}static void set_clock_src(pp_clk_src_t clk_src){	u32 tmp;	tmp = __raw_readl(s3c_pp_base + S3C_VPP_MODE);	if(clk_src == HCLK) {		if((unsigned int)h_clk > 66000000) {			tmp &= ~(0x7f<<23);			tmp |= (1<<24);			tmp |= (1<<23);		} else {			tmp &=~ (0x7f<<23);		}	} else if(clk_src == PLL_EXT) {	} else {		tmp &=~(0x7f<<23);	}	tmp = (tmp &~ (0x3<<21)) | (clk_src<<21);	__raw_writel(tmp, s3c_pp_base + S3C_VPP_MODE);}static void set_data_path(pp_params *pParams){	u32 tmp;			tmp = __raw_readl(s3c_pp_base + S3C_VPP_MODE);		tmp &=~(0x1<<12);	// 0: progressive mode, 1: interlace mode	tmp &=~(0x1<<31);	if(pParams->OutPath == POST_FIFO) {		s3c_fb_enable_local_post(0);		tmp |= (0x1<<13);	} else if(pParams->OutPath == POST_DMA) {		tmp &=~(0x1<<13);	}	__raw_writel(tmp, s3c_pp_base + S3C_VPP_MODE);}static void set_interlace_mode(u32 on_off){	u32 tmp;	tmp = __raw_readl(s3c_pp_base + S3C_VPP_MODE);	if(on_off == 1) tmp |=(1<<12);	else tmp &=~(1<<12);	__raw_writel(tmp, s3c_pp_base + S3C_VPP_MODE);}static void set_auto_load(pp_params *pParams){	u32 tmp;	tmp = __raw_readl(s3c_pp_base + S3C_VPP_MODE);	if(pParams->Mode == FREE_RUN) {		tmp |= (1<<14);	} else if(pParams->Mode == ONE_SHOT) {		tmp &=~(1<<14);	}	__raw_writel(tmp, s3c_pp_base + S3C_VPP_MODE);}static void post_int_enable(u32 int_type){	u32 tmp;	tmp = __raw_readl(s3c_pp_base + S3C_VPP_MODE);	if(int_type == 0) {		//Edge triggering		tmp &= ~(S3C_MODE_IRQ_LEVEL);	} else if(int_type == 1) {	//level triggering		tmp |= S3C_MODE_IRQ_LEVEL;	}	tmp |= S3C_MODE_POST_INT_ENABLE;	__raw_writel(tmp, s3c_pp_base + S3C_VPP_MODE);}static void post_int_disable(void){	u32 tmp;	tmp = __raw_readl(s3c_pp_base + S3C_VPP_MODE);	tmp &=~ S3C_MODE_POST_INT_ENABLE;	__raw_writel(tmp, s3c_pp_base + S3C_VPP_MODE);}static void start_processing(void){	__raw_writel(0x1<<31, s3c_pp_base + S3C_VPP_POSTENVID);}static void stop_processing_free_run(void){	u32 tmp;	tmp = __raw_readl(s3c_pp_base + S3C_VPP_MODE);	tmp &=~(1<<14);	__raw_writel(tmp, s3c_pp_base + S3C_VPP_MODE);}s3c_pp_state_t post_get_processing_state(void){	s3c_pp_state_t	state;	u32 tmp;	tmp = __raw_readl(s3c_pp_base + S3C_VPP_POSTENVID);	if (tmp & S3C_VPP_POSTENVID)	{		state = POST_BUSY;	}	else	{		state = POST_IDLE;	}	printk("Post processing state = %d\n", state);	return state;}static void config_pp(pp_params	*pParams){	u32 tmp;	tmp = __raw_readl(s3c_pp_base + S3C_VPP_POSTENVID);	tmp &= ~S3C_POSTENVID_ENABLE;	__raw_writel(tmp, s3c_pp_base + S3C_VPP_POSTENVID);	tmp = S3C_MODE2_ADDR_CHANGE_DISABLE |S3C_MODE2_CHANGE_AT_FRAME_END |S3C_MODE2_SOFTWARE_TRIGGER;	__raw_writel(tmp, s3c_pp_base + S3C_VPP_MODE_2);#ifdef NO_PIP_MODE	pParams->SrcStartX	= pParams->SrcStartY = 0;	pParams->DstStartX	= pParams->DstStartY = 0;	pParams->SrcWidth	= pParams->SrcFullWidth;	pParams->SrcHeight	= pParams->SrcFullHeight;	pParams->DstWidth	= pParams->DstFullWidth;	pParams->DstHeight	= pParams->DstFullHeight;#endif	set_clock_src(HCLK);	// setting the output data path (DMA or FIFO)	set_data_path(pParams);	// setting the src/dst color space	set_data_format(pParams);	// setting the src/dst size 	set_scaler(pParams);	// setting the src/dst buffer address	set_buf_addr(pParams);		set_auto_load(pParams);}irqreturn_t s3c_pp_isr(int irq, void *dev_id,		struct pt_regs *regs){	u32 mode;	mode = __raw_readl(s3c_pp_base + S3C_VPP_MODE);	mode &= ~(1 << 6);			/* Clear Source in POST Processor */	__raw_writel(mode, s3c_pp_base + S3C_VPP_MODE);	wake_up_interruptible(&waitq);	return IRQ_HANDLED;}

⌨️ 快捷键说明

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