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

📄 cim_df.c

📁 LX 800 WindowsCE 6.0 BSP
💻 C
📖 第 1 页 / 共 5 页
字号:
 /*
  * <LIC_AMD_STD>
  * Copyright (C) 2005 Advanced Micro Devices, Inc.  All Rights Reserved.
  * </LIC_AMD_STD>
  *
  * <CTL_AMD_STD>
  * </CTL_AMD_STD>
  *
  * <DOC_AMD_STD>
  * Cimarron display filter routines.  These routines program the video hardware.
  * </DOC_AMD_STD>
  *
  */

/*---------------------------------------------------------------------------
 * df_set_crt_enable
 *
 * This routine enables or disables CRT output.
 *---------------------------------------------------------------------------*/

int df_set_crt_enable (int crt_output)
{
	unsigned long config, misc;
	
	config = READ_VID32 (DF_DISPLAY_CONFIG);
	misc   = READ_VID32 (DF_VID_MISC);
	
	switch (crt_output)
	{
		/* DISABLE DISPLAY */

	    case DF_CRT_DISABLE:

			config &= ~(DF_DCFG_DIS_EN   | DF_DCFG_HSYNC_EN |
				        DF_DCFG_VSYNC_EN | DF_DCFG_DAC_BL_EN);
			misc |= DF_DAC_POWER_DOWN;
			break;

		/* ENABLE THE DISPLAY */

		case DF_CRT_ENABLE:

			config |= (DF_DCFG_DIS_EN   | DF_DCFG_HSYNC_EN |
				       DF_DCFG_VSYNC_EN | DF_DCFG_DAC_BL_EN);
			misc &= ~(DF_DAC_POWER_DOWN  | DF_ANALOG_POWER_DOWN);
			break;

		/* HSYNC:OFF VSYNC:ON */

		case DF_CRT_STANDBY:

			config = (config & ~(DF_DCFG_DIS_EN | DF_DCFG_HSYNC_EN | DF_DCFG_DAC_BL_EN)) |
				DF_DCFG_VSYNC_EN;
			misc |= DF_DAC_POWER_DOWN;
			break;

		/* HSYNC:ON VSYNC:OFF */

		case DF_CRT_SUSPEND:

			config = (config & ~(DF_DCFG_DIS_EN | DF_DCFG_VSYNC_EN | DF_DCFG_DAC_BL_EN)) |
				DF_DCFG_HSYNC_EN;
			misc |= DF_DAC_POWER_DOWN;
			break;

		default:
			return CIM_STATUS_INVALIDPARAMS;
	}

	WRITE_VID32 (DF_DISPLAY_CONFIG, config);
	WRITE_VID32 (DF_VID_MISC, misc);

	return CIM_STATUS_OK;
}

/*---------------------------------------------------------------------------
 * df_set_panel_enable
 *
 * This routine enables or disables panel output.
 *---------------------------------------------------------------------------*/

int df_set_panel_enable (int enable)
{
	unsigned long pm;
	
	pm = READ_VID32 (DF_POWER_MANAGEMENT);

	if (enable) pm |=  DF_PM_PANEL_ON;
	else        pm &= ~DF_PM_PANEL_ON;

	WRITE_VID32 (DF_POWER_MANAGEMENT, pm);
	
	return CIM_STATUS_OK;
}

/*---------------------------------------------------------------------------
 * df_configure_video_source
 *
 * This routine initializes all aspects of the source buffer for a video overlay.
 *---------------------------------------------------------------------------*/

int df_configure_video_source (DF_VIDEO_SOURCE_PARAMS *video_source_odd,
	DF_VIDEO_SOURCE_PARAMS *video_source_even)
{
	unsigned long pitch, ctrl, vcfg;
	unsigned long lock, vg_line, gcfg;
	unsigned long width, size, scale;
    unsigned long misc;

	lock    = READ_REG32 (DC3_UNLOCK);
	vg_line = READ_REG32 (DC3_LINE_SIZE);
	gcfg    = READ_REG32 (DC3_GENERAL_CFG);
	vcfg    = READ_VID32 (DF_VIDEO_CONFIG);
	ctrl    = READ_VID32 (DF_VID_ALPHA_CONTROL);
	scale   = READ_VID32 (DF_VIDEO_SCALER);

    /* STORE THE DESIRED SCALING PROCEDURE */
    /* Cimarron supports two modes when programming the scale and position  */
    /* of the video window.  The first mode is designed to implicitly apply */
    /* the graphics scale to any video operations.  The second applys the   */
    /* video unchanged, allowing complete control by the user.  To allow    */
    /* visibility between modules, the current mode is stored in a spare    */
    /* bit in the DF miscellaneous register.                                */

    misc = READ_VID32 (DF_VID_MISC);
    if (video_source_odd->flags & DF_SOURCEFLAG_IMPLICITSCALING)
        misc |= DF_USER_IMPLICIT_SCALING;
    else
        misc &= DF_USER_IMPLICIT_SCALING;
    WRITE_VID32 (DF_VID_MISC, misc);

	/* PARAMETER - VIDEO PITCH */

	pitch = (video_source_odd->y_pitch >> 3) | ((video_source_odd->uv_pitch >> 3) << 16);
	
	/* PARAMETER - VIDEO FORMAT */

	gcfg &= ~DC3_GCFG_YUV_420;
	vcfg &= ~(DF_VCFG_VID_INP_FORMAT | DF_VCFG_4_2_0_MODE);
	ctrl &= ~(DF_VIDEO_INPUT_IS_RGB  | DF_CSC_VIDEO_YUV_TO_RGB | DF_HD_VIDEO |
		DF_YUV_CSC_EN);
		
	/* SELECT PIXEL ORDERING */

	switch (video_source_odd->video_format & 3)
	{
		case 0: vcfg |= DF_VCFG_UYVY_FORMAT; break;
		case 1: vcfg |= DF_VCFG_Y2YU_FORMAT; break;
		case 2: vcfg |= DF_VCFG_YUYV_FORMAT; break;
		case 3: vcfg |= DF_VCFG_YVYU_FORMAT; break;
	}

	/* SELECT SOURCE FORMAT (4:2:2, 4:2:0, RGB) */

	switch (video_source_odd->video_format >> 2)
	{
		case 0:  ctrl |= DF_CSC_VIDEO_YUV_TO_RGB; break;
		
		case 1:  ctrl |= DF_CSC_VIDEO_YUV_TO_RGB;
			     vcfg |= DF_VCFG_4_2_0_MODE;
				 gcfg |= DC3_GCFG_YUV_420;
				 break;
		
		case 2:  ctrl |= DF_VIDEO_INPUT_IS_RGB; break;
		
		default: return CIM_STATUS_INVALIDPARAMS;
	}

	/* ALIGN TO APPROPRIATE OUTPUT COLOR SPACE                             */
	/* We have assumed until this point that the output color space is RGB */
	/* and the input (if YUV) is always SDTV video.                        */

	if (video_source_odd->flags & DF_SOURCEFLAG_HDTVSOURCE)
		ctrl |= DF_HD_VIDEO;

	if (ctrl & DF_CSC_GRAPHICS_RGB_TO_YUV)
	{
		/* YUV OUTPUT - DISABLE YUV->RGB AND ENABLE YUV->YUV */

		ctrl &= ~DF_CSC_VIDEO_YUV_TO_RGB;

		if ((!(ctrl & DF_HD_VIDEO) &&  (ctrl & DF_HD_GRAPHICS)) ||
			 ((ctrl & DF_HD_VIDEO) && !(ctrl & DF_HD_GRAPHICS)))
		{
			ctrl |= DF_YUV_CSC_EN;
		}
	}

	/* PARAMETER - DISPLAY FILTER BUFFER SIZE                        */
	/* The line size in the video generator must be 32-byte aligned. */
	/* However, smaller alignments are managed by setting the        */
	/* appropriate pitch and clipping the video window.              */
	
	vcfg &= ~(DF_VCFG_LINE_SIZE_LOWER_MASK | DF_VCFG_LINE_SIZE_BIT8 |
		      DF_VCFG_LINE_SIZE_BIT9);

	size  = ((video_source_odd->width >> 1) + 7) & 0xFFF8;

	vcfg |= (size & 0x00FF) << 8;
	if (size & 0x0100) vcfg |= DF_VCFG_LINE_SIZE_BIT8;
	if (size & 0x0200) vcfg |= DF_VCFG_LINE_SIZE_BIT9;

	scale = (scale & ~0x7FF) | video_source_odd->height;

	/* PARAMETER - VIDEO GENERATOR BUFFER SIZE */
	
	vg_line &= ~DC3_LINE_SIZE_VLS_MASK;

	if (gcfg & DC3_GCFG_YUV_420)
		width = ((video_source_odd->width >> 1) + 7) & 0xFFF8;
	else
		width = ((video_source_odd->width << 1) + 31) & 0xFFE0;

	vg_line |= (width >> 3) << DC3_LINE_SIZE_VB_SHIFT;

	/* WRITE ALL PARAMETERS AT ONCE */
	
	WRITE_REG32 (DC3_UNLOCK, DC3_UNLOCK_VALUE);
	WRITE_VID32 (DF_VIDEO_CONFIG, vcfg);
	WRITE_VID32 (DF_VID_ALPHA_CONTROL, ctrl);
	WRITE_VID32 (DF_VIDEO_SCALER, scale);
	WRITE_REG32 (DC3_GENERAL_CFG, gcfg);
	WRITE_REG32 (DC3_LINE_SIZE, vg_line);
	WRITE_REG32 (DC3_VID_YUV_PITCH, pitch);

	/* WRITE EVEN OR ODD BUFFER OFFSETS                            */
	/* The even buffer is only valid inside an interlaced display. */
	
    if (READ_REG32 (DC3_IRQ_FILT_CTL) & DC3_IRQFILT_INTL_EN)
	{
		WRITE_REG32 (DC3_VID_EVEN_Y_ST_OFFSET, video_source_even->y_offset);
		WRITE_REG32 (DC3_VID_EVEN_U_ST_OFFSET, video_source_even->u_offset);
		WRITE_REG32 (DC3_VID_EVEN_V_ST_OFFSET, video_source_even->v_offset);
	}

	WRITE_REG32 (DC3_VID_Y_ST_OFFSET, video_source_odd->y_offset);
	WRITE_REG32 (DC3_VID_U_ST_OFFSET, video_source_odd->u_offset);
	WRITE_REG32 (DC3_VID_V_ST_OFFSET, video_source_odd->v_offset);

    WRITE_REG32 (DC3_UNLOCK, lock);

	return CIM_STATUS_OK;
}

/*---------------------------------------------------------------------------
 * df_set_video_offsets
 *
 * This routine sets the starting offset for the video buffer(s).  The buffers
 * can also be configured inside df_configure_video_source, but a separate
 * routine is provided here to allow quick buffer flipping.
 *---------------------------------------------------------------------------*/

int df_set_video_offsets (int even, unsigned long y_offset,
	unsigned long u_offset, unsigned long v_offset)
{
	unsigned long lock = READ_REG32 (DC3_UNLOCK);

	WRITE_REG32 (DC3_UNLOCK, DC3_UNLOCK_VALUE);
	
    if (even)
	{		
		WRITE_REG32 (DC3_VID_EVEN_Y_ST_OFFSET, y_offset);
		WRITE_REG32 (DC3_VID_EVEN_U_ST_OFFSET, u_offset);
		WRITE_REG32 (DC3_VID_EVEN_V_ST_OFFSET, v_offset);
	}
	else
	{
		WRITE_REG32 (DC3_VID_Y_ST_OFFSET, y_offset);
		WRITE_REG32 (DC3_VID_U_ST_OFFSET, u_offset);
		WRITE_REG32 (DC3_VID_V_ST_OFFSET, v_offset);
	}

	WRITE_REG32 (DC3_UNLOCK, lock);

	return CIM_STATUS_OK;
}

/*---------------------------------------------------------------------------
 * df_set_video_scale
 *
 * This routine programs the horizontal/vertical scale factors for video.  To
 * disable scaling/filtering, this routine should be called with identical source
 * and destination dimensions.
 *---------------------------------------------------------------------------*/

int df_set_video_scale (unsigned long src_width, unsigned long src_height,
	unsigned long dst_width, unsigned long dst_height, unsigned long flags)
{
	unsigned long temp, misc;
    unsigned long scale, gfxscale;
    unsigned long fbactive, src;
    unsigned long size, downscale;
    unsigned long vcfg, gcfg, unlock;

    /* APPLY THE GRAPHICS SCALE */
    /* When requested by the user, we will adjust the video scale by the  */
    /* current graphics scale factor.  This allows video to be programmed */
    /* in terms of the graphics source resolution.                        */

    misc = READ_VID32 (DF_VID_MISC);
    if (misc & DF_USER_IMPLICIT_SCALING)
    {
        gfxscale = READ_REG32 (DC3_GFX_SCALE);
        fbactive = READ_REG32 (DC3_FB_ACTIVE);

        /* REVERSE ENGINEER THE SCALE FACTOR */
        /* The graphics scale factor is (source / (dst - 1)), so a little */
        /* math is performed to reverse engineer the correct scale for    */
        /* video.                                                         */
        /*                                                                */
        /* F = (0x4000*S)/(D-1)  ->  (D/S) = (((0x4000*S)/F)+1)/S         */

        scale =  gfxscale & 0xFFFF;
        src   = (fbactive >> 16) + 1;
        if (scale != 0x4000)
        {
            dst_width = dst_width * (((0x4000 * src) / scale) + 1);
            dst_width /= src;
        }

        scale =  gfxscale >> 16;
        src   = (fbactive & 0xFFFF) + 1;
        if (scale != 0x4000)
        {
            dst_height = dst_height * (((0x4000 * src) / scale) + 1);
            dst_height /= src;
        }
    }

	/* CHECK FOR VALID SCALING FACTOR */
	/* The display filter/video generator can support up to 8:1  */
    /* horizontal downscale and up to 4:1 vertical downscale.    */
    /* Scale factors above 4:1 horizontal and 2:1 horizontal     */
    /* will have a quality impact.  However, at such large scale */
    /* factors, it might not matter,                             */

	if (((flags & DF_SCALEFLAG_CHANGEX) && dst_width  < (src_width >> 3)) ||
        ((flags & DF_SCALEFLAG_CHANGEY) && dst_height < (src_height >> 2)))
    {
		return CIM_STATUS_INVALIDSCALE;
    }

    /* ENABLE OR DISABLE ADVANCED SCALING FEATURES          */
    /* Scaling above 2:1 vertical and 4:1 horizontal relies */
    /* on mechanisms beside the line filter.                */
    
    if (flags & DF_SCALEFLAG_CHANGEX)
    {
        scale = READ_VID32 (DF_VIDEO_SCALER);
        vcfg  = READ_VID32 (DF_VIDEO_CONFIG);
        vcfg &= ~(DF_VCFG_LINE_SIZE_LOWER_MASK | DF_VCFG_LINE_SIZE_BIT8 |
		      DF_VCFG_LINE_SIZE_BIT9);
        
        if (dst_width < (src_width >> 2))
        {            
            src_width >>= 1;
            WRITE_VID32 (DF_VIDEO_SCALER, scale | DF_SCALE_DOUBLE_H_DOWNSCALE);
        }
        else
        {
            WRITE_VID32 (DF_VIDEO_SCALER, scale & ~DF_SCALE_DOUBLE_H_DOWNSCALE);

⌨️ 快捷键说明

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