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

📄 cim_vg.c

📁 LX 800 WindowsCE 6.0 BSP
💻 C
📖 第 1 页 / 共 5 页
字号:
           !(temp & GP3_BS_CB_EMPTY))
    {
        ;
    }

	/* SET THE DOT CLOCK FREQUENCY */

    if (!(mode_params->flags & VG_MODEFLAG_EXCLUDEPLL))
    {
	    if (mode_params->flags & VG_MODEFLAG_HALFCLOCK)
		    flags = VG_PLL_DIVIDE_BY_2;
	    else if (mode_params->flags & VG_MODEFLAG_QVGA)
		    flags = VG_PLL_DIVIDE_BY_4;
	    else
		    flags = 0;

        /* ALLOW DOTREF TO BE USED AS THE PLL            */
        /* This is useful for some external TV encoders. */

        if (mode_params->flags & VG_MODEFLAG_PLL_BYPASS)
            flags |= VG_PLL_BYPASS;

        /* ALLOW THE USER TO MANUALLY ENTER THE MSR VALUE */

        if (mode_params->flags & VG_MODEFLAG_MANUAL_FREQUENCY)
            flags |= VG_PLL_MANUAL;
        if (mode_params->flags & VG_MODEFLAG_VIP_TO_DOT_CLOCK)
            flags |= VG_PLL_VIP_CLOCK;

	    vg_set_clock_frequency (mode_params->frequency, flags);
    }
	
	/* CLEAR ALL BUFFER OFFSETS */

	WRITE_REG32 (DC3_FB_ST_OFFSET,   0);
	WRITE_REG32 (DC3_CB_ST_OFFSET,   0);
	WRITE_REG32 (DC3_CURS_ST_OFFSET, 0);

    genlk_ctl = READ_REG32 (DC3_GENLK_CTL) & ~(DC3_GC_ALPHA_FLICK_ENABLE |
        DC3_GC_FLICKER_FILTER_ENABLE | DC3_GC_FLICKER_FILTER_MASK);

	/* ENABLE INTERLACING */

    if (mode_params->flags & VG_MODEFLAG_INTERLACED)
    {
        irq_ctl |= DC3_IRQFILT_INTL_EN;

        if ((mode_params->flags & VG_MODEFLAG_INT_MASK) == VG_MODEFLAG_INT_ADDRESS)
            irq_ctl |= DC3_IRQFILT_INTL_ADDR;
        else if ((mode_params->flags & VG_MODEFLAG_INT_MASK) == VG_MODEFLAG_INT_FLICKER)
        {
            genlk_ctl |= DC3_GC_FLICKER_FILTER_1_8 | DC3_GC_FLICKER_FILTER_ENABLE |
                DC3_GC_ALPHA_FLICK_ENABLE;
        }
    }
	
	WRITE_REG32 (DC3_GFX_SCALE, (vscale << 16) | (hscale & 0xFFFF));
	WRITE_REG32 (DC3_IRQ_FILT_CTL, irq_ctl);
    WRITE_REG32 (DC3_GENLK_CTL, genlk_ctl);

	/* SET LINE SIZE AND PITCH */
	/* The line size and pitch are calculated from the src_width parameter    */
	/* passed in to this routine.  All other parameters are ignored.          */
	/* The pitch is set either to a power of 2 to allow efficient             */
	/* compression or to a linear value to allow efficient memory management. */
	
    switch (bpp)
    {
        case 8:
            size = mode_params->src_width;
            line_size = starting_width;
            break;

        case 12:
        case 15:
        case 16:

            size = mode_params->src_width << 1;
            line_size = starting_width << 1;
            break;

        case 24:
        case 32:
        default:

            size = mode_params->src_width << 2;
            line_size = starting_width << 2; break;
    }
		
	/* CALCULATE DV RAM SETTINGS AND POWER OF 2 PITCH */

	pitch = 1024;
	dv_size = DC3_DV_LINE_SIZE_1024;
	
	if (size > 1024) { pitch = 2048; dv_size = DC3_DV_LINE_SIZE_2048; }
	if (size > 2048) { pitch = 4096; dv_size = DC3_DV_LINE_SIZE_4096; }
	if (size > 4096) { pitch = 8192; dv_size = DC3_DV_LINE_SIZE_8192; }
	
	/* OVERRIDE SETTINGS FOR LINEAR PITCH */

	if (mode_params->flags & VG_MODEFLAG_LINEARPITCH)
	{
        unsigned long max;
        if (pitch != size)
        {
            /* CALCULATE MAXIMUM ADDRESS (1K ALIGNED) */

            max = size * output_height;
            max = (max + 0x3FF) & 0xFFFFFC00;
            WRITE_REG32 (DC3_DV_TOP, max | DC3_DVTOP_ENABLE);

		    gcfg  |= DC3_GCFG_FDTY;
		    pitch  = size;
        }
        else
        {
            WRITE_REG32 (DC3_DV_TOP, 0);
        }
	}

	/* WRITE PITCH AND DV RAM SETTINGS */
	/* The DV RAM line length is programmed at a power of 2 boundary */
	/* in case the user wants to toggle back to a power of 2 pitch   */
	/* later.  It could happen...                                    */

	temp = READ_REG32 (DC3_DV_CTL);
	WRITE_REG32 (DC3_GFX_PITCH, pitch >> 3);
	WRITE_REG32 (DC3_DV_CTL, (temp & ~DC3_DV_LINE_SIZE_MASK) | dv_size);

	/* SET THE LINE SIZE */

	WRITE_REG32 (DC3_LINE_SIZE, (line_size + 7) >> 3);

	/* ALWAYS ENABLE VIDEO AND GRAPHICS DATA            */
	/* These bits are relics from a previous design and */
	/* should always be enabled.                        */

	dcfg |= (DC3_DCFG_VDEN | DC3_DCFG_GDEN);
	
	/* SET PIXEL FORMAT */	

	dcfg |= bpp_mask;

	/* ENABLE TIMING GENERATOR, TIM. REG. UPDATES, PALETTE BYPASS */
	/* AND VERT. INT. SELECT                                      */

    dcfg |= (unsigned long)(DC3_DCFG_TGEN | DC3_DCFG_TRUP | DC3_DCFG_PALB | DC3_DCFG_VISL);

    /* SET FIFO PRIORITIES AND DISPLAY FIFO LOAD ENABLE */
    /* Note that the bandwidth setting gets upgraded when scaling or flicker */
    /* filtering are enabled, as they require more data throughput.          */

    msr_read64 (MSR_DEVICE_GEODELX_VG, DC3_SPARE_MSR, &msr_value);
    msr_value.low &= ~(DC3_SPARE_DISABLE_CFIFO_HGO    | DC3_SPARE_VFIFO_ARB_SELECT |
                       DC3_SPARE_LOAD_WM_LPEN_MASK    | DC3_SPARE_WM_LPEN_OVRD     |
                       DC3_SPARE_DISABLE_INIT_VID_PRI | DC3_SPARE_DISABLE_VFIFO_WM);

    if ((mode_params->flags & VG_MODEFLAG_BANDWIDTHMASK) == VG_MODEFLAG_HIGH_BAND  ||
       ((mode_params->flags & VG_MODEFLAG_INTERLACED) &&
           (mode_params->flags & VG_MODEFLAG_INT_MASK) == VG_MODEFLAG_INT_FLICKER) ||
        (irq_ctl & DC3_IRQFILT_GFX_FILT_EN))
    {
        /* HIGH BANDWIDTH */
        /* Set agressive watermarks and disallow forced low priority */

        gcfg |= 0x0000BA01;
        dcfg |= 0x000EA000;
        acfg  = 0x001A0201;

        msr_value.low |= DC3_SPARE_DISABLE_CFIFO_HGO | DC3_SPARE_VFIFO_ARB_SELECT |
                         DC3_SPARE_WM_LPEN_OVRD;
    }
    else if ((mode_params->flags & VG_MODEFLAG_BANDWIDTHMASK) == VG_MODEFLAG_AVG_BAND)
    {
        /* AVERAGE BANDWIDTH */
        /* Set average watermarks and allow small regions of forced low priority. */

        gcfg |= 0x0000B601;
        dcfg |= 0x00009000;
        acfg  = 0x00160001;

        msr_value.low |= DC3_SPARE_DISABLE_CFIFO_HGO | DC3_SPARE_VFIFO_ARB_SELECT |
                         DC3_SPARE_WM_LPEN_OVRD;

        /* SET THE NUMBER OF LOW PRIORITY LINES TO 1/2 THE TOTAL AVAILABLE */

        temp  = ((READ_REG32 (DC3_V_ACTIVE_TIMING) >> 16) & 0x7FF) + 1;
        temp -=  (READ_REG32 (DC3_V_SYNC_TIMING) & 0x7FF) + 1;
	    temp >>= 1;
        if (temp > 127)
            temp = 127;

        acfg |= temp << 9;
    }
    else if ((mode_params->flags & VG_MODEFLAG_BANDWIDTHMASK) == VG_MODEFLAG_LOW_BAND)
    {
        /* LOW BANDWIDTH */
        /* Set low watermarks and allow larger regions of forced low priority. */

        gcfg |= 0x00009501;
        dcfg |= 0x00008000;
        acfg  = 0x00150001;

        msr_value.low |= DC3_SPARE_DISABLE_CFIFO_HGO | DC3_SPARE_VFIFO_ARB_SELECT |
                         DC3_SPARE_WM_LPEN_OVRD;

        /* SET THE NUMBER OF LOW PRIORITY LINES TO 3/4 THE TOTAL AVAILABLE */

        temp  = ((READ_REG32 (DC3_V_ACTIVE_TIMING) >> 16) & 0x7FF) + 1;
        temp -=  (READ_REG32 (DC3_V_SYNC_TIMING) & 0x7FF) + 1;
	    temp  = (temp * 3) >> 2;
        if (temp > 127)
            temp = 127;

        acfg |= temp << 9;
    }
    else
    {
        /* LEGACY CHARACTERISTICS */
        /* Arbitration from a single set of watermarks. */

        gcfg |= 0x0000B601;
        msr_value.low |= DC3_SPARE_DISABLE_VFIFO_WM | DC3_SPARE_DISABLE_INIT_VID_PRI;
        acfg = 0;
    }

    msr_write64 (MSR_DEVICE_GEODELX_VG, DC3_SPARE_MSR, &msr_value);

	/* ENABLE FLAT PANEL CENTERING                          */
	/* For panel modes having a resolution smaller than the */
	/* panel resolution, turn on data centering.            */

	if (mode_params->flags & VG_MODEFLAG_CENTERED)
	    dcfg |= DC3_DCFG_DCEN;

	/* COMBINE AND SET TIMING VALUES */

	temp = (mode_params->hactive - 1) | ((mode_params->htotal - 1) << 16);
	WRITE_REG32(DC3_H_ACTIVE_TIMING, temp);
	temp = (mode_params->hblankstart - 1) | ((mode_params->hblankend - 1) << 16);
	WRITE_REG32(DC3_H_BLANK_TIMING, temp);
	temp = (mode_params->hsyncstart - 1) | ((mode_params->hsyncend - 1) << 16);
	WRITE_REG32(DC3_H_SYNC_TIMING, temp);
	temp = (mode_params->vactive - 1) | ((mode_params->vtotal - 1) << 16);
	WRITE_REG32(DC3_V_ACTIVE_TIMING, temp);
	temp =	(mode_params->vblankstart - 1) | ((mode_params->vblankend - 1) << 16);
	WRITE_REG32(DC3_V_BLANK_TIMING, temp);
	temp = (mode_params->vsyncstart - 1) | ((mode_params->vsyncend - 1) << 16);
	WRITE_REG32(DC3_V_SYNC_TIMING, temp);
    temp = (mode_params->vactive_even - 1) | ((mode_params->vtotal_even - 1) << 16);
	WRITE_REG32(DC3_V_ACTIVE_EVEN, temp);
	temp =	(mode_params->vblankstart_even - 1) | ((mode_params->vblankend_even - 1) << 16);
	WRITE_REG32(DC3_V_BLANK_EVEN, temp);
	temp = (mode_params->vsyncstart_even - 1) | ((mode_params->vsyncend_even - 1) << 16);
	WRITE_REG32(DC3_V_SYNC_EVEN, temp);
	
    /* SET THE VIDEO REQUEST REGISTER */

    WRITE_VID32 (DF_VIDEO_REQUEST, 0);

	/* SET SOURCE DIMENSIONS */

	WRITE_REG32 (DC3_FB_ACTIVE, ((starting_width - 1) << 16) |
		(starting_height - 1));

	/* SET SYNC POLARITIES */

	temp = READ_VID32 (DF_DISPLAY_CONFIG);

	temp &= ~(DF_DCFG_CRT_SYNC_SKW_MASK | DF_DCFG_PWR_SEQ_DLY_MASK |
		      DF_DCFG_CRT_HSYNC_POL     | DF_DCFG_CRT_VSYNC_POL);

    temp |= (DF_DCFG_CRT_SYNC_SKW_INIT |
			 DF_DCFG_PWR_SEQ_DLY_INIT  |
             DF_DCFG_GV_PAL_BYP);

	if (mode_params->flags & VG_MODEFLAG_NEG_HSYNC)
		temp |= DF_DCFG_CRT_HSYNC_POL;
	if (mode_params->flags & VG_MODEFLAG_NEG_VSYNC)
		temp |= DF_DCFG_CRT_VSYNC_POL;

	WRITE_VID32 (DF_DISPLAY_CONFIG, temp);

    WRITE_REG32 (DC3_DISPLAY_CFG, dcfg);
    WRITE_REG32 (DC3_ARB_CFG, acfg);
	WRITE_REG32 (DC3_GENERAL_CFG, gcfg);

	/* RESTORE VALUE OF DC3_UNLOCK */

	WRITE_REG32(DC3_UNLOCK, unlock);

	return CIM_STATUS_OK;
}

/*---------------------------------------------------------------------------
 * vg_set_bpp
 *
 * This routine changes the display BPP on the fly.  It is intended only to 
 * switch between pixel depths of the same pixel size 24<->32 or 15<->16, NOT
 * between pixel depths of differing sizes 16<->32
 *---------------------------------------------------------------------------*/

int vg_set_display_bpp (int bpp)
{
    unsigned long unlock, dcfg, bpp_mask;

    switch (bpp)
	{
		case 8:  bpp_mask = DC3_DCFG_DISP_MODE_8BPP;  break;
	    case 24: bpp_mask = DC3_DCFG_DISP_MODE_24BPP; break;
		case 32: bpp_mask = DC3_DCFG_DISP_MODE_32BPP; break;
		case 12: bpp_mask = DC3_DCFG_DISP_MODE_16BPP | DC3_DCFG_12BPP; break;
		case 15: bpp_mask = DC3_DCFG_DISP_MODE_16BPP | DC3_DCFG_15BPP; break;
		case 16: bpp_mask = DC3_DCFG_DISP_MODE_16BPP | DC3_DCFG_16BPP; break;
		default: return CIM_STATUS_INVALIDPARAMS;
	}

    unlock = READ_REG32 (DC3_UNLOCK);
    dcfg = READ_REG32 (DC3_DISPLAY_CFG) & ~(DC3_DCFG_DISP_MODE_MASK | DC3_DCFG_16BPP_MODE_MASK);
    dcfg |= bpp_mask;

    WRITE_REG32 (DC3_UNLOCK, DC3_UNLOCK_VALUE);
    WRITE_REG32 (DC3_DISPLAY_CFG, dcfg);
    WRITE_REG32 (DC3_UNLOCK, unlock);

    return CIM_STATUS_OK;
}

/*---------------------------------------------------------------------------
 * vg_get_display_mode_index
 *
 * This routine searches the Cimarron mode table for a mode that matches the
 * input parameters.  If a match is found, the return value is the index into
 * the mode table.  If no match is found, the return value is -1.
 *---------------------------------------------------------------------------*/

int vg_get_display_mode_index (VG_QUERY_MODE *query)
{
	unsigned int mode;
	unsigned long hz_flag  = 0xFFFFFFFF;
	unsigned long bpp_flag = 0xFFFFFFFF;
    unsigned long enc_flag = 0xFFFFFFFF;
    unsigned long tv_flag  = 0;
    unsigned long interlaced = 0;
    unsigned long halfclock  = 0;
    long minimum = 0x7FFFFFFF;
    long diff;
    int match = -1;

	if (!query || !query->query_flags)
		return -1;

	if (query->query_flags & VG_QUERYFLAG_REFRESH)
	{
		/* SET FLAGS TO MATCH REFRESH RATE */

		if      (query->hz == 56)  hz_flag = VG_SUPPORTFLAG_56HZ;

⌨️ 快捷键说明

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