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

📄 cim_vg.c

📁 LX 800 WindowsCE 6.0 BSP
💻 C
📖 第 1 页 / 共 5 页
字号:
		else if (query->hz == 60)  hz_flag = VG_SUPPORTFLAG_60HZ;
		else if (query->hz == 70)  hz_flag = VG_SUPPORTFLAG_70HZ;
		else if (query->hz == 72)  hz_flag = VG_SUPPORTFLAG_72HZ;
		else if (query->hz == 75)  hz_flag = VG_SUPPORTFLAG_75HZ;
		else if (query->hz == 85)  hz_flag = VG_SUPPORTFLAG_85HZ;
        else if (query->hz == 90)  hz_flag = VG_SUPPORTFLAG_90HZ;
        else if (query->hz == 100) hz_flag = VG_SUPPORTFLAG_100HZ;
		else                       hz_flag = 0;
	}
	
	if (query->query_flags & VG_QUERYFLAG_BPP)
	{
		/* SET BPP FLAGS TO LIMIT MODE SELECTION */

		if      (query->bpp == 8)  bpp_flag = VG_SUPPORTFLAG_8BPP;
		else if (query->bpp == 12) bpp_flag = VG_SUPPORTFLAG_12BPP;
		else if (query->bpp == 15) bpp_flag = VG_SUPPORTFLAG_15BPP;
		else if (query->bpp == 16) bpp_flag = VG_SUPPORTFLAG_16BPP;
		else if (query->bpp == 24) bpp_flag = VG_SUPPORTFLAG_24BPP;
		else if (query->bpp == 32) bpp_flag = VG_SUPPORTFLAG_32BPP;
		else                       bpp_flag = 0;
	}

    if (query->query_flags & VG_QUERYFLAG_ENCODER)
    {
        /* SET ENCODER FLAGS TO LIMIT MODE SELECTION */

        if      (query->encoder == VG_ENCODER_ADV7171) enc_flag = VG_SUPPORTFLAG_ADV7171;
        else if (query->encoder == VG_ENCODER_SAA7127) enc_flag = VG_SUPPORTFLAG_SAA7127;
        else if (query->encoder == VG_ENCODER_FS454)   enc_flag = VG_SUPPORTFLAG_FS454;
        else if (query->encoder == VG_ENCODER_ADV7300) enc_flag = VG_SUPPORTFLAG_ADV7300;
        else                                           enc_flag = 0;
    }

    if (query->query_flags & VG_QUERYFLAG_TVMODE)
    {
        /* SET ENCODER FLAGS TO LIMIT MODE SELECTION */

        if      (query->tvmode == VG_TVMODE_NTSC)      tv_flag = VG_SUPPORTFLAG_NTSC;
        else if (query->tvmode == VG_TVMODE_PAL)       tv_flag = VG_SUPPORTFLAG_PAL;
        else if (query->tvmode == VG_TVMODE_480P)      tv_flag = VG_SUPPORTFLAG_480P;
        else if (query->tvmode == VG_TVMODE_720P)      tv_flag = VG_SUPPORTFLAG_720P;
        else if (query->tvmode == VG_TVMODE_1080I)     tv_flag = VG_SUPPORTFLAG_1080I;
        else if (query->tvmode == VG_TVMODE_6X4_NTSC)  tv_flag = VG_SUPPORTFLAG_6X4_NTSC;
        else if (query->tvmode == VG_TVMODE_8X6_NTSC)  tv_flag = VG_SUPPORTFLAG_8X6_NTSC;
        else if (query->tvmode == VG_TVMODE_10X7_NTSC) tv_flag = VG_SUPPORTFLAG_10X7_NTSC;
        else if (query->tvmode == VG_TVMODE_6X4_PAL)   tv_flag = VG_SUPPORTFLAG_6X4_PAL;
        else if (query->tvmode == VG_TVMODE_8X6_PAL)   tv_flag = VG_SUPPORTFLAG_8X6_PAL;
        else if (query->tvmode == VG_TVMODE_10X7_PAL)  tv_flag = VG_SUPPORTFLAG_10X7_PAL;
        else                                           tv_flag = 0xFFFFFFFF;
    }

    /* SET APPROPRIATE TV AND VOP FLAGS */

    if (query->query_flags & VG_QUERYFLAG_INTERLACED)
        interlaced = query->interlaced ? VG_MODEFLAG_INTERLACED : 0;
    if (query->query_flags & VG_QUERYFLAG_HALFCLOCK)
        halfclock = query->halfclock  ? VG_MODEFLAG_HALFCLOCK  : 0;

	/* CHECK FOR INVALID REQUEST */

	if (!hz_flag || !bpp_flag || !enc_flag || tv_flag == 0xFFFFFFFF)
		return -1;

	/* LOOP THROUGH THE AVAILABLE MODES TO FIND A MATCH */

	for (mode = 0; mode < NUM_CIMARRON_DISPLAY_MODES; mode++)
	{
		if ( (!(query->query_flags & VG_QUERYFLAG_PANEL)        ||
			   (CimarronDisplayModes[mode].internal_flags & VG_SUPPORTFLAG_PANEL))          &&
			 (!(query->query_flags & VG_QUERYFLAG_TVOUT)        ||
			   (CimarronDisplayModes[mode].internal_flags & VG_SUPPORTFLAG_TVOUT))          &&
			 (!(query->query_flags & VG_QUERYFLAG_INTERLACED)   ||
			   (CimarronDisplayModes[mode].flags & VG_MODEFLAG_INTERLACED) == interlaced)   &&
             (!(query->query_flags & VG_QUERYFLAG_HALFCLOCK)    ||
			   (CimarronDisplayModes[mode].flags & VG_MODEFLAG_HALFCLOCK) == halfclock)     &&
			 (!(query->query_flags & VG_QUERYFLAG_PANELWIDTH)   ||
			   (CimarronDisplayModes[mode].panel_width == query->panel_width))              &&
			 (!(query->query_flags & VG_QUERYFLAG_PANELHEIGHT)  ||
			   (CimarronDisplayModes[mode].panel_height == query->panel_height))            &&
			 (!(query->query_flags & VG_QUERYFLAG_ACTIVEWIDTH)  ||
			   (CimarronDisplayModes[mode].hactive == query->active_width))                 &&
			 (!(query->query_flags & VG_QUERYFLAG_ACTIVEHEIGHT) ||
			   (CimarronDisplayModes[mode].vactive == query->active_height))                &&
			 (!(query->query_flags & VG_QUERYFLAG_TOTALWIDTH)   ||
			   (CimarronDisplayModes[mode].htotal == query->total_width))                   &&
			 (!(query->query_flags & VG_QUERYFLAG_TOTALHEIGHT)  ||
			   (CimarronDisplayModes[mode].vtotal == query->total_height))                  &&
			 (!(query->query_flags & VG_QUERYFLAG_BPP)          ||
			   (CimarronDisplayModes[mode].internal_flags & bpp_flag))                      &&
			 (!(query->query_flags & VG_QUERYFLAG_REFRESH)      ||
			   (CimarronDisplayModes[mode].internal_flags & hz_flag))                       &&
             (!(query->query_flags & VG_QUERYFLAG_ENCODER)      ||
			   (CimarronDisplayModes[mode].internal_flags & enc_flag))                      &&
             (!(query->query_flags & VG_QUERYFLAG_TVMODE)       ||
			  ((CimarronDisplayModes[mode].internal_flags & VG_SUPPORTFLAG_TVMODEMASK) == tv_flag)) &&
			 (!(query->query_flags & VG_QUERYFLAG_PIXELCLOCK)   ||
			   (CimarronDisplayModes[mode].frequency == query->frequency)))
		{
            /* ALLOW SEARCHING BASED ON AN APPROXIMATE PIXEL CLOCK */

            if (query->query_flags & VG_QUERYFLAG_PIXELCLOCK_APPROX)
            {
                diff = query->frequency - CimarronDisplayModes[mode].frequency;
                if (diff < 0)
                    diff = -diff;

                if (diff < minimum)
                {
                    minimum = diff;
                    match = mode;
                }
            }
            else
            {
                match = mode;
                break;
            }
		}
	}

    /* RETURN DISPLAY MODE INDEX */

	return match;
}

/*---------------------------------------------------------------------------
 * vg_get_display_mode_information
 *
 * This routine retrieves all information for a display mode contained
 * within Cimarron's mode tables.
 *---------------------------------------------------------------------------*/

int vg_get_display_mode_information (unsigned int index, VG_DISPLAY_MODE *vg_mode)
{
	if (index > NUM_CIMARRON_DISPLAY_MODES)
		return CIM_STATUS_INVALIDPARAMS;

	*vg_mode = CimarronDisplayModes[index];
	return CIM_STATUS_OK;
}

/*---------------------------------------------------------------------------
 * vg_get_display_mode_count
 *
 * This routine retrieves the count of all predefined Cimarron modes.
 *---------------------------------------------------------------------------*/

int vg_get_display_mode_count (void)
{
	return NUM_CIMARRON_DISPLAY_MODES;
}

/*---------------------------------------------------------------------------
 * vg_get_current_display_mode
 *
 * This routine retrieves the settings for the current display.  This includes
 * any panel settings.
 *---------------------------------------------------------------------------*/

int vg_get_current_display_mode (VG_DISPLAY_MODE *current_display, int *bpp)
{
	Q_WORD msr_value;
	unsigned long active, blank, sync;
	unsigned long i, m, n, p;
	unsigned long genlk, irq, temp;
	unsigned long flags  = 0;
    unsigned long iflags = 0;

	/* READ THE CURRENT HORIZONTAL DISPLAY TIMINGS */

	active = READ_REG32 (DC3_H_ACTIVE_TIMING);
	blank  = READ_REG32 (DC3_H_BLANK_TIMING);
	sync   = READ_REG32 (DC3_H_SYNC_TIMING);

	current_display->hactive     = (active & 0xFFF) + 1;
	current_display->hblankstart = (blank  & 0xFFF) + 1;
	current_display->hsyncstart  = (sync   & 0xFFF) + 1;
	
	current_display->htotal    = ((active >> 16) & 0xFFF) + 1;
	current_display->hblankend = ((blank  >> 16) & 0xFFF) + 1;
	current_display->hsyncend  = ((sync   >> 16) & 0xFFF) + 1;

	/* READ THE CURRENT VERTICAL DISPLAY TIMINGS */

	active = READ_REG32 (DC3_V_ACTIVE_TIMING);
	blank  = READ_REG32 (DC3_V_BLANK_TIMING);
	sync   = READ_REG32 (DC3_V_SYNC_TIMING);

	current_display->vactive     = (active & 0x7FF) + 1;
	current_display->vblankstart = (blank  & 0x7FF) + 1;
	current_display->vsyncstart  = (sync   & 0x7FF) + 1;
	
	current_display->vtotal    = ((active >> 16) & 0x7FF) + 1;
	current_display->vblankend = ((blank  >> 16) & 0x7FF) + 1;
	current_display->vsyncend  = ((sync   >> 16) & 0x7FF) + 1;

    /* READ THE CURRENT EVEN FIELD VERTICAL DISPLAY TIMINGS */

	active = READ_REG32 (DC3_V_ACTIVE_EVEN);
	blank  = READ_REG32 (DC3_V_BLANK_EVEN);
	sync   = READ_REG32 (DC3_V_SYNC_EVEN);

	current_display->vactive_even     = (active & 0x7FF) + 1;
	current_display->vblankstart_even = (blank  & 0x7FF) + 1;
	current_display->vsyncstart_even  = (sync   & 0x7FF) + 1;
	
	current_display->vtotal_even    = ((active >> 16) & 0x7FF) + 1;
	current_display->vblankend_even = ((blank  >> 16) & 0x7FF) + 1;
	current_display->vsyncend_even  = ((sync   >> 16) & 0x7FF) + 1;

	/* READ THE CURRENT SOURCE DIMENSIONS                      */
	/* The DC3_FB_ACTIVE register is only used when scaling is enabled.   */
	/* As the goal of this routine is to return a structure that can be   */
	/* passed to vg_set_custom_mode to exactly recreate the current mode, */
	/* we must check the status of the scaler/filter.                     */

    genlk = READ_REG32 (DC3_GENLK_CTL);
	irq   = READ_REG32 (DC3_IRQ_FILT_CTL);
	temp  = READ_REG32 (DC3_FB_ACTIVE);
	
	current_display->src_height = (temp & 0xFFFF) + 1;
    current_display->src_width = ((temp >> 16) & 0xFFF8) + 8;
	
	/* READ THE CURRENT PANEL CONFIGURATION */
	/* We can only infer some of the panel settings based on hardware */
	/* (like when panning).  We will instead assume that the current  */
	/* mode was set using Cimarron and use the panel variables inside */
	/* Cimarron when returning the current mode information.          */

	if (vg3_panel_enable)
	{
        Q_WORD msr_value;

		flags |= VG_MODEFLAG_PANELOUT;

		current_display->panel_width  = vg3_panel_width;
		current_display->panel_height = vg3_panel_height;
		current_display->mode_width   = vg3_mode_width;
		current_display->mode_height  = vg3_mode_height;

		if (READ_REG32 (DC3_DISPLAY_CFG) & DC3_DCFG_DCEN)
			flags |= VG_MODEFLAG_CENTERED;

        msr_read64 (MSR_DEVICE_GEODELX_DF, DF_MSR_PAD_SEL, &msr_value);
        current_display->panel_tim1         = READ_VID32 (DF_VIDEO_PANEL_TIM1);
        current_display->panel_tim2         = READ_VID32 (DF_VIDEO_PANEL_TIM2);
        current_display->panel_dither_ctl   = READ_VID32 (DF_DITHER_CONTROL);
        current_display->panel_pad_sel_low  = msr_value.low;
        current_display->panel_pad_sel_high = msr_value.high;
	}
	
	/* SET MISCELLANEOUS MODE FLAGS */
	
	/* INTERLACED */

	if (irq & DC3_IRQFILT_INTL_EN)
    {
        flags |= VG_MODEFLAG_INTERLACED;
        if (irq & DC3_IRQFILT_INTL_ADDR)
            flags |= VG_MODEFLAG_INT_ADDRESS;
        else if (genlk & DC3_GC_FLICKER_FILTER_ENABLE)
            flags |= VG_MODEFLAG_INT_FLICKER;
        else
            flags |= VG_MODEFLAG_INT_LINEDOUBLE;
    }
	
	/* POLARITIES */

	temp = READ_VID32 (DF_DISPLAY_CONFIG);
	if (temp & DF_DCFG_CRT_HSYNC_POL)
		flags |= VG_MODEFLAG_NEG_HSYNC;
	if (temp & DF_DCFG_CRT_VSYNC_POL)
		flags |= VG_MODEFLAG_NEG_VSYNC;

	/* BPP */

	temp = READ_REG32 (DC3_DISPLAY_CFG) & DC3_DCFG_DISP_MODE_MASK;
	if (temp == DC3_DCFG_DISP_MODE_8BPP)
    {
		iflags |= VG_SUPPORTFLAG_8BPP;
        *bpp = 8;
    }
	else if (temp == DC3_DCFG_DISP_MODE_24BPP)
    {
        iflags |= VG_SUPPORTFLAG_24BPP;
        *bpp = 24;
    }
	else if (temp == DC3_DCFG_DISP_MODE_32BPP)
    {
        iflags |= VG_SUPPORTFLAG_32BPP;
        *bpp = 32;
    }
	else if (temp == DC3_DCFG_DISP_MODE_16BPP)
	{
		temp = READ_REG32 (DC3_DISPLAY_CFG) & DC3_DCFG_16BPP_MODE_MASK;
		if (temp == DC3_DCFG_16BPP)
        {
            iflags |= VG_SUPPORTFLAG_16BPP;
            *bpp = 16;
        }
		else if (temp == DC3_DCFG_15BPP)
        {
            iflags |= VG_SUPPORTFLAG_15BPP;
            *bpp = 15;
        }
		else if (temp == DC3_DCFG_12BPP)
        {
            iflags |= VG_SUPPORTFLAG_12BPP;
            *bpp = 12;
        }
	}

    /* TV RELATED FLAGS */

    msr_read64 (MSR_DEVICE_GEODELX_DF, DF_MSR_PAD_SEL, &msr_value);
    if (msr_value.high & DF_INVERT_VOP_CLOCK)
        flags |= VG_MODEFLAG_TVOUT;

    /* LINEAR PITCH */

    temp = (READ_REG32 (DC3_GFX_PITCH) & 0x0000FFFF) << 3;
    if (temp != 1024 && temp != 2048 && temp != 4096 && temp != 8192)
        flags |= VG_MODEFLAG_LINEARPITCH;

    /* SIMULTANEOUS CRT/FP */

    msr_read64 (MSR_DEVICE_GEODELX_DF, MSR_GEODELINK_CONFIG, &msr_value);
    if (msr_value.low & DF_SIMULTANEOUS_CRT_FP)
        flags |= VG_MODEFLAG_CRT_AND_FP;

    /* SET PLL-RELATED FLAGS */

    msr_read64 (MSR_DEVICE_GEODELX_GLCP, GLCP_DOTPLL, &msr_value);
    if (msr_value.high & GLCP_DOTPLL_DIV4)
        flags |= VG_MODEFLAG_QVGA;
    if (msr_value.low & GLCP_DOTPLL_HALFPIX)
        flags |= VG_MODEFLAG_HALFCLOCK;

    /* SAVE THE FLAGS IN THE MODE STRUCTURE */

    current_display->internal_flags = iflags;
    current_display->flags = flags;

	/* READ PIXEL CLOCK FREQUENCY */
	/* We first search for an exact match.  If none is found, we try */
	/* a fixed point calculation and return CIM_STATUS_INEXACTMATCH. */
	
	for (i = 0; i < NUM_CIMARRON_PLL_FREQUENCIES; i++)
	{
		if (CimarronPLLFrequencies[i].pll_value == msr_value.high)
			break;
	}

	if (i == NUM_CIMARRON_PLL_FREQUENCIES)
	{
		/* ATTEMPT 16.16 CALCULATION */

⌨️ 快捷键说明

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