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

📄 cim_vip.c

📁 LX 800 WindowsCE 6.0 BSP
💻 C
📖 第 1 页 / 共 4 页
字号:
}

/*---------------------------------------------------------------------------
 * vip_set_capture_state
 *
 * This routine takes the current control word definition ( stored in locals )
 * adds in the specified state, and writes the control word.
 *---------------------------------------------------------------------------*/

int vip_set_capture_state (unsigned long state)
{
    unsigned long vip_control1, vip_control3;

    /* UPDATE THE CURRENT CAPTURE MODE */

    vip_control1  =  READ_VIP32 (VIP_CONTROL1);
    vip_control3  =  READ_VIP32 (VIP_CONTROL3);
	vip_control1 &= ~VIP_CONTROL1_RUNMODE_MASK;
	vip_control1 |= (state << VIP_CONTROL1_RUNMODE_SHIFT);

	WRITE_VIP32 (VIP_CONTROL1, vip_control1);
	
    if (state >= VIP_STARTCAPTUREATNEXTLINE)
    {
        /* WHACK VIP RESET */
        /* The VIP can get confused when switching between capture settings, such as */
        /* between linear and planar.  We will thus whack VIP reset when enabling    */
        /* capture to ensure a pristine VIP state.                                   */

        WRITE_VIP32 (VIP_CONTROL1, vip_control1 | VIP_CONTROL1_RESET);
        WRITE_VIP32 (VIP_CONTROL1, vip_control1 & ~VIP_CONTROL1_RESET);
        WRITE_VIP32 (VIP_CONTROL3, vip_control3 | VIP_CONTROL3_FIFO_RESET);
    }

    return CIM_STATUS_OK;
}

/*---------------------------------------------------------------------------
 * vip_terminate
 *
 * This routine stops VIP capture and resets the VIP internal state.
 *---------------------------------------------------------------------------*/

int vip_terminate (void)
{
    unsigned long timeout = 50000;

    /* DISABLE AND CLEAR ALL VIP INTERRUPTS */

    WRITE_VIP32 (VIP_INTERRUPT, VIP_ALL_INTERRUPTS | (VIP_ALL_INTERRUPTS >> 16));

    /* DISABLE VIP CAPTURE */
    /* We will try to let the VIP FIFO flush before shutting it down. */

    WRITE_VIP32 (VIP_CONTROL1, 0);
    while (timeout)
    {
        timeout--;
        if (READ_VIP32 (VIP_STATUS) & VIP_STATUS_WRITES_COMPLETE)
            break;
    }

	/* RESET THE HARDWARE REGISTERS */
    /* Note that we enable VIP reset to allow clock gating to lower VIP */
    /* power consumption.                                               */
	
    WRITE_VIP32 (VIP_CONTROL1, VIP_CONTROL1_RESET);
    WRITE_VIP32 (VIP_CONTROL3, VIP_CONTROL3_FIFO_RESET);
	WRITE_VIP32 (VIP_CONTROL2, 0);

	return CIM_STATUS_OK;
}

/*---------------------------------------------------------------------------
 * vip_configure_fifo
 *
 * This routine sets the desired threshold or flush for the specified fifo.
 *---------------------------------------------------------------------------*/

int vip_configure_fifo (unsigned long fifo_type, unsigned long fifo_size)
{
    unsigned long vip_control1, vip_control2;

    vip_control1 = READ_VIP32 (VIP_CONTROL1);
    vip_control2 = READ_VIP32 (VIP_CONTROL2);

	switch (fifo_type)
    {
		case VIP_VIDEOTHRESHOLD:
			vip_control2 &= ~VIP_CONTROL2_VIDTH_MASK;
			vip_control2 |= (fifo_size << VIP_CONTROL2_VIDTH_SHIFT) & VIP_CONTROL2_VIDTH_MASK;
		    break;

		case VIP_ANCILLARYTHRESHOLD:
			vip_control2 &= ~VIP_CONTROL2_ANCTH_MASK;
			vip_control2 |= (fifo_size << VIP_CONTROL2_ANCTH_SHIFT) & VIP_CONTROL2_ANCTH_MASK;
		    break;

		case VIP_VIDEOFLUSH:
			vip_control1 &= ~VIP_CONTROL1_VID_FF_MASK;
			vip_control1 |= ((fifo_size >> 2) << VIP_CONTROL1_VID_FF_SHIFT) & VIP_CONTROL1_VID_FF_MASK;
		    break;

		case VIP_ANCILLARYFLUSH:
			vip_control1 &= ~VIP_CONTROL1_ANC_FF_MASK;
			vip_control1 |= ((fifo_size >> 2) << VIP_CONTROL1_ANC_FF_SHIFT) & VIP_CONTROL1_ANC_FF_MASK;
		    break;

        default:
            return CIM_STATUS_INVALIDPARAMS;
	}

    WRITE_VIP32 (VIP_CONTROL1, vip_control1);
    WRITE_VIP32 (VIP_CONTROL2, vip_control2);

	return CIM_STATUS_OK;
}

/*---------------------------------------------------------------------------
 * vip_set_interrupt_enable
 *
 * This routine accepts a mask of interrupts to be enabled/disabled and
 * an enable flag.
 *
 * For each mask match, the interrupt will be enabled or disabled based on
 * enable
 *---------------------------------------------------------------------------*/

int vip_set_interrupt_enable (unsigned long mask, int enable)
{
    /* CHECK IF ANY VALID INTERRUPTS ARE BEING CHANGED */

    if (mask & VIP_ALL_INTERRUPTS)
    {
        unsigned long int_enable = READ_VIP32(VIP_INTERRUPT) & 0xFFFF;

        /* SET OR CLEAR THE MASK BITS */
        /* Note that the upper 16-bits of the register are 0 after this */
        /* operation.  This prevents us from indadvertently clearing a  */
        /* pending interrupt by enabling/disabling another one.         */

        if (enable) int_enable &= ~(mask >> 16);
        else        int_enable |=  (mask >> 16);

        WRITE_VIP32 (VIP_INTERRUPT, int_enable);
    }
	
    return CIM_STATUS_OK;
}

/*---------------------------------------------------------------------------
 * vip_set_vsync_error
 *
 * This routine defines a region that is used to determine if the vsync is
 * within an acceptable range. This definition is accomplished using
 * a count and a vertical window.  The count specifies the exact number
 * of clocks expected for one field.  The window parameters specify the number
 * of clocks variation allowed before and after the expected vsync.  For
 * example, if vertical_count is 1000, window_before is 5 and window_after
 * is 12, VSync will be considered valid if it occurs between 995 and 1012
 * clocks after the last VSync.  The total window size (window_before + window_after)
 * cannot exceed 255.
 *---------------------------------------------------------------------------*/

int vip_set_vsync_error (unsigned long vertical_count, unsigned long window_before,
    unsigned long window_after, int enable)
{
    unsigned long vip_control2 = READ_VIP32 (VIP_CONTROL2);
    unsigned long temp;

    if (enable)
    {
        /* CREATE THE VERTICAL WINDOW */
        /* The VIP uses two counters.  The first counter defines the minimum clock count */
        /* before a valid VSync can occur.  The second counter starts after the first    */
        /* completes and defines the acceptable region of variation.                     */

        temp  = ((window_before + window_after) << VIP_VSYNC_ERR_WINDOW_SHIFT) & VIP_VSYNC_ERR_WINDOW_MASK;
	    temp |= (vertical_count - window_before) & VIP_VSYNC_ERR_COUNT_MASK;
    	
        vip_control2 |= VIP_CONTROL2_VERTERROR_ENABLE;

	    WRITE_VIP32(VIP_VSYNC_ERR_COUNT, temp);
    }
    else
    {
        vip_control2 &= ~VIP_CONTROL2_VERTERROR_ENABLE;
    }
    WRITE_VIP32 (VIP_CONTROL2, vip_control2);

    return CIM_STATUS_OK;
}

/*---------------------------------------------------------------------------
 * vip_max_address_enable
 *
 * This routine specifies the maximum address to which the the hardware should
 * write during data storage. If this value is exceeded an error is generated,
 * (this may be monitored using the appropriate interrupt flags - see
 * vip_set_interrupt_enable)
 *---------------------------------------------------------------------------*/

int vip_max_address_enable (unsigned long max_address, int enable)
{
    unsigned long vip_control2 = READ_VIP32 (VIP_CONTROL2);

	if (enable)
    {
		/* ENABLE THE CONTROL BIT */

		vip_control2 |= VIP_CONTROL2_ADD_ERROR_ENABLE;
		
		WRITE_VIP32(VIP_MAX_ADDRESS, max_address & VIP_MAXADDR_MASK);
	}
	else
    {
		/* DISABLE DETECTION */

		vip_control2 &= ~VIP_CONTROL2_ADD_ERROR_ENABLE;
	}
    WRITE_VIP32 (VIP_CONTROL2, vip_control2);

    return CIM_STATUS_OK;
}

/*---------------------------------------------------------------------------
 * vip_set_loopback_enable
 *
 * This routine enables/disables internal loopback functionality.  When
 * loopback is enabled, the VOP outputs are rerouted to the VIP inputs
 * internal to the chip.  No loopback connector is required.
 *---------------------------------------------------------------------------*/

int vip_set_loopback_enable(int enable)
{
    unsigned long vip_control2 = READ_VIP32 (VIP_CONTROL2);

	if (enable) vip_control2 |=  VIP_CONTROL2_LOOPBACK_ENABLE;
	else         vip_control2 &= ~VIP_CONTROL2_LOOPBACK_ENABLE;
	
    WRITE_VIP32 (VIP_CONTROL2, vip_control2);

    return CIM_STATUS_OK;
}

/*---------------------------------------------------------------------------
 * vip_configure_genlock
 *
 * This routine configures genlock functionality.
 *---------------------------------------------------------------------------*/

int vip_configure_genlock (VIPGENLOCKBUFFER *buffer)
{
	unsigned long vip_control1, vip_control2;
    unsigned long unlock, genlk_ctl;

    if (!buffer)
        return CIM_STATUS_INVALIDPARAMS;

    unlock       = READ_REG32 (DC3_UNLOCK);
    genlk_ctl    = READ_REG32 (DC3_GENLK_CTL);
    vip_control1 = READ_VIP32 (VIP_CONTROL1);
    vip_control2 = READ_VIP32 (VIP_CONTROL2);

    /* UPDATE VIDEO DETECTION */
    /* These flags are used to indicate the ways in which the VIP signal can */
    /* be considered 'lost'.                                                 */

    vip_control1 &= ~VIP_CONTROL1_VDE_FF_MASK;
    vip_control2 &= ~(VIP_CONTROL2_FIELD2VG_MASK | VIP_CONTROL2_SYNC2VG_MASK);
    vip_control1 |= buffer->vip_signal_loss;

    /* UPDATE FIELD AND VSYNC INFORMATION */
    /* These flags control how and when the even/odd field and Vsync */
    /* information is communicated to the VG.                        */

    vip_control2 |= buffer->field_to_vg;
    vip_control2 |= buffer->vsync_to_vg;

    /* ENABLE OR DISABLE GENLOCK TIMEOUT */
    /* Enabling genlock timeout allows the VG to revert to its own sync */
    /* timings when the VIP input is lost.  Note that the VIP will not  */
    /* know the signal is lost unless the appropriate error detection   */
    /* flags have been enabled inside vip_initialize.                   */

	if (buffer->enable_timeout) genlk_ctl |=  DC3_GC_GENLOCK_TO_ENABLE;
	else                        genlk_ctl &= ~DC3_GC_GENLOCK_TO_ENABLE;
	
	genlk_ctl &= ~DC3_GC_GENLOCK_SKEW_MASK;
	genlk_ctl |= buffer->genlock_skew & DC3_GC_GENLOCK_SKEW_MASK;
	
    WRITE_REG32 (DC3_UNLOCK, DC3_UNLOCK_VALUE);
    WRITE_REG32 (DC3_GENLK_CTL, genlk_ctl);
    WRITE_VIP32 (VIP_CONTROL1, vip_control1);
    WRITE_VIP32 (VIP_CONTROL2, vip_control2);
    WRITE_REG32 (DC3_UNLOCK, unlock);
	
	return CIM_STATUS_OK;
}

/*---------------------------------------------------------------------------
 * vip_set_genlock_enable
 *
 * This routine enables/disables genlock inside the VG.
 *---------------------------------------------------------------------------*/

int vip_set_genlock_enable (int enable)
{
	unsigned long unlock, temp;

    unlock = READ_REG32 (DC3_UNLOCK);
    temp   = READ_REG32 (DC3_GENLK_CTL);

	if (enable) temp |=  DC3_GC_GENLOCK_ENABLE;
	else        temp &= ~DC3_GC_GENLOCK_ENABLE;
	
    WRITE_REG32 (DC3_UNLOCK, DC3_UNLOCK_VALUE);
	WRITE_REG32 (DC3_GENLK_CTL, temp);
    WRITE_REG32 (DC3_UNLOCK, unlock);

    return CIM_STATUS_OK;
}

/*---------------------------------------------------------------------------
 * vip_set_power_characteristics
 *
 * This routine takes a VIPPOWERBUFFER structure, and selectively sets the
 * GeodeLink power and/or Vip clock power states.
 *---------------------------------------------------------------------------*/

int vip_set_power_characteristics (VIPPOWERBUFFER *buffer)
{
	Q_WORD q_word;

    if (!buffer)
        return CIM_STATUS_INVALIDPARAMS;
	
	q_word.low = q_word.high = 0;

    /* ENABLE GEODELINK CLOCK GATING */
	
    if (buffer->glink_clock_mode)
		q_word.low |= VIP_MSR_POWER_GLINK;
	
    /* ENABLE VIP CLOCK GATING */

	if (buffer->vip_clock_mode)
		q_word.low |= VIP_MSR_POWER_CLOCK;
	
    /* WRITE THE NEW VALUE */

    msr_write64 (MSR_DEVICE_GEODELX_VIP, MSR_GEODELINK_PM, &q_word);
		
	return CIM_STATUS_OK;
}

/*---------------------------------------------------------------------------
 * vip_set_priority_characteristics
 *
 * This routine programs the VIP GeodeLink priority characteristics
 *---------------------------------------------------------------------------*/

int vip_set_priority_characteristics (VIPPRIORITYBUFFER *buffer)
{
	Q_WORD q_word;

    if (!buffer)
        return CIM_STATUS_INVALIDPARAMS;

	q_word.low = q_word.high = 0;

	q_word.low |= (buffer->secondary << VIP_MSR_MCR_SECOND_PRIORITY_SHIFT)  & VIP_MSR_MCR_SECOND_PRIORITY_MASK;
	q_word.low |= (buffer->primary   << VIP_MSR_MCR_PRIMARY_PRIORITY_SHIFT) & VIP_MSR_MCR_PRIMARY_PRIORITY_MASK;
	q_word.low |= (buffer->pid       << VIP_MSR_MCR_PID_SHIFT)              & VIP_MSR_MCR_PID_MASK;

	msr_write64 (MSR_DEVICE_GEODELX_VIP, MSR_GEODELINK_CONFIG, &q_word);
	
	return CIM_STATUS_OK;
}

/*---------------------------------------------------------------------------
 * vip_set_debug_characteristics
 *
 * This routine configures the debug data that is exposed over the diag bus.
 *---------------------------------------------------------------------------*/

int vip_set_debug_characteristics (VIPDEBUGBUFFER *buffer)
{
	Q_WORD q_word;

    if (!buffer)
        return CIM_STATUS_INVALIDPARAMS;

⌨️ 快捷键说明

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