📄 cim_vip.c
字号:
buffer->flags = 0;
if (vip_control3 & VIP_CONTROL3_VSYNC_POLARITY) buffer->flags |= VIP_MODEFLAG_VSYNCACTIVEHIGH;
if (vip_control3 & VIP_CONTROL3_HSYNC_POLARITY) buffer->flags |= VIP_MODEFLAG_HSYNCACTIVEHIGH;
buffer->horz_start = READ_VIP32 (VIP_601_HORZ_START);
buffer->vbi_start = READ_VIP32 (VIP_601_VBI_START);
buffer->vbi_height = READ_VIP32 (VIP_601_VBI_END) - buffer->vbi_start + 1;
buffer->vert_start_even = READ_VIP32 (VIP_601_EVEN_START_STOP) & 0xFFFF;
buffer->even_height = (READ_VIP32 (VIP_601_EVEN_START_STOP) >> 16) - buffer->vert_start_even + 1;
buffer->vert_start_odd = READ_VIP32 (VIP_601_ODD_START_STOP) & 0xFFFF;
buffer->odd_height = (READ_VIP32 (VIP_601_ODD_START_STOP) >> 16) - buffer->vert_start_odd + 1;
buffer->odd_detect_start = READ_VIP32 (VIP_ODD_FIELD_DETECT) & 0xFFFF;
buffer->odd_detect_end = READ_VIP32 (VIP_ODD_FIELD_DETECT) >> 16;
/* SPECIAL CASE FOR HORIZONTAL DATA */
/* 601 horizontal parameters are based on the number of clocks and not the */
/* number of pixels. */
if ((vip_control1 & VIP_CONTROL1_MODE_MASK) == VIP_MODE_16BIT601)
buffer->width = (READ_VIP32 (VIP_601_HORZ_END) - buffer->horz_start - 3) >> 1;
else
buffer->width = (READ_VIP32 (VIP_601_HORZ_END) - buffer->horz_start - 3);
return CIM_STATUS_OK;
}
/*---------------------------------------------------------------------------
* vip_get_buffer_configuration
*
* This routine reads the current buffer configuration for Task A, Task B,
* ancillary or message data. The current_buffer member indicates which
* array index should hold the new values for Task A or Task B data.
*---------------------------------------------------------------------------*/
int vip_get_buffer_configuration (int buffer_type, VIPINPUTBUFFER *buffer)
{
unsigned long cur_buffer = buffer->current_buffer;
VIPINPUTBUFFER_ADDR *offsets;
if (!buffer)
return CIM_STATUS_INVALIDPARAMS;
if (buffer_type == VIP_BUFFER_A)
{
offsets = &buffer->offsets[VIP_BUFFER_TASK_A];
/* READ VIDEO PITCH */
offsets->y_pitch = READ_VIP32 (VIP_TASKA_VID_PITCH) & 0xFFFF;
offsets->uv_pitch = READ_VIP32 (VIP_TASKA_VID_PITCH) >> 16;
/* READ BASE OFFSETS */
if (buffer->flags & VIP_INPUTFLAG_INVERTPOLARITY)
{
offsets->even_base[cur_buffer] = READ_VIP32 (VIP_TASKA_VID_ODD_BASE);
offsets->odd_base[cur_buffer] = READ_VIP32 (VIP_TASKA_VID_EVEN_BASE);
if (buffer->flags & VIP_INPUTFLAG_VBI)
{
offsets->vbi_even_base = READ_VIP32 (VIP_TASKA_VBI_ODD_BASE);
offsets->vbi_odd_base = READ_VIP32 (VIP_TASKA_VBI_EVEN_BASE);
}
}
else
{
offsets->even_base[cur_buffer] = READ_VIP32 (VIP_TASKA_VID_EVEN_BASE);
offsets->odd_base[cur_buffer] = READ_VIP32 (VIP_TASKA_VID_ODD_BASE);
if (buffer->flags & VIP_INPUTFLAG_VBI)
{
offsets->vbi_even_base = READ_VIP32 (VIP_TASKA_VBI_EVEN_BASE);
offsets->vbi_odd_base = READ_VIP32 (VIP_TASKA_VBI_ODD_BASE);
}
}
/* READ 4:2:0 OFFSETS */
if (buffer->flags & VIP_INPUTFLAG_PLANAR)
{
offsets->odd_uoffset = READ_VIP32 (VIP_TASKA_U_OFFSET);
offsets->odd_voffset = READ_VIP32 (VIP_TASKA_V_OFFSET);
offsets->even_uoffset = READ_VIP32 (VIP_TASKA_U_EVEN_OFFSET);
offsets->even_voffset = READ_VIP32 (VIP_TASKA_V_EVEN_OFFSET);
}
}
else if (buffer_type == VIP_BUFFER_B)
{
offsets = &buffer->offsets[VIP_BUFFER_TASK_B];
/* READ VIDEO PITCH */
offsets->y_pitch = READ_VIP32 (VIP_TASKB_VID_PITCH) & 0xFFFF;
offsets->uv_pitch = READ_VIP32 (VIP_TASKB_VID_PITCH) >> 16;
/* READ BASE OFFSETS */
if (buffer->flags & VIP_INPUTFLAG_INVERTPOLARITY)
{
offsets->even_base[cur_buffer] = READ_VIP32 (VIP_TASKB_VID_ODD_BASE);
offsets->odd_base[cur_buffer] = READ_VIP32 (VIP_TASKB_VID_EVEN_BASE);
if (buffer->flags & VIP_INPUTFLAG_VBI)
{
offsets->vbi_even_base = READ_VIP32 (VIP_TASKB_VBI_ODD_BASE);
offsets->vbi_odd_base = READ_VIP32 (VIP_TASKB_VBI_EVEN_BASE);
}
}
else
{
offsets->even_base[cur_buffer] = READ_VIP32 (VIP_TASKB_VID_EVEN_BASE);
offsets->odd_base[cur_buffer] = READ_VIP32 (VIP_TASKB_VID_ODD_BASE);
if (buffer->flags & VIP_INPUTFLAG_VBI)
{
offsets->vbi_even_base = READ_VIP32 (VIP_TASKB_VBI_EVEN_BASE);
offsets->vbi_odd_base = READ_VIP32 (VIP_TASKB_VBI_ODD_BASE);
}
}
/* READ 4:2:0 OFFSETS */
if (buffer->flags & VIP_INPUTFLAG_PLANAR)
{
offsets->odd_uoffset = READ_VIP32 (VIP_TASKB_U_OFFSET);
offsets->odd_voffset = READ_VIP32 (VIP_TASKB_V_OFFSET);
}
}
else if (buffer_type == VIP_BUFFER_ANC || buffer_type == VIP_BUFFER_MSG)
{
buffer->ancillaryData.msg1_base = READ_VIP32(VIP_ANC_MSG1_BASE);
buffer->ancillaryData.msg2_base = READ_VIP32(VIP_ANC_MSG2_BASE);
buffer->ancillaryData.msg_size = READ_VIP32(VIP_ANC_MSG_SIZE);
}
else
{
return CIM_STATUS_INVALIDPARAMS;
}
return CIM_STATUS_OK;
}
/*---------------------------------------------------------------------------
* vip_get_genlock_configuration
*
* This routine reads the current genlock configuration.
*---------------------------------------------------------------------------*/
int vip_get_genlock_configuration (VIPGENLOCKBUFFER *buffer)
{
unsigned long vip_control1, vip_control2;
unsigned long genlk_ctl;
if (!buffer)
return CIM_STATUS_INVALIDPARAMS;
genlk_ctl = READ_REG32 (DC3_GENLK_CTL);
vip_control1 = READ_VIP32 (VIP_CONTROL1);
vip_control2 = READ_VIP32 (VIP_CONTROL2);
/* READ ERROR DETECTION, CURRENT FIELD AND CURRENT VSYNC */
/* These flags are used to indicate the ways in which the VIP signal can */
/* be considered 'lost'. */
buffer->vip_signal_loss = vip_control1 & VIP_CONTROL1_VDE_FF_MASK;
buffer->field_to_vg = vip_control2 & VIP_CONTROL2_FIELD2VG_MASK;
buffer->vsync_to_vg = vip_control2 & VIP_CONTROL2_SYNC2VG_MASK;
/* GENLOCK TIMEOUT ENABLE */
buffer->enable_timeout = 0;
if (genlk_ctl & DC3_GC_GENLOCK_TO_ENABLE)
buffer->enable_timeout = 1;
/* GENLOCK SKEW */
buffer->genlock_skew = genlk_ctl & DC3_GC_GENLOCK_SKEW_MASK;
return CIM_STATUS_OK;
}
/*---------------------------------------------------------------------------
* vip_get_genlock_enable
*
* This routine returns the current enable status of genlock in the VG.
*---------------------------------------------------------------------------*/
int vip_get_genlock_enable (void)
{
if (READ_REG32 (DC3_GENLK_CTL) & DC3_GC_GENLOCK_ENABLE)
return 1;
return 0;
}
/*---------------------------------------------------------------------------
* vip_is_buffer_update_latched
*
* This routine indicates whether changes to the VIP offsets have been latched by
* the hardware.
*---------------------------------------------------------------------------*/
int vip_is_buffer_update_latched (void)
{
return (!(READ_VIP32(VIP_STATUS) & VIP_STATUS_BASEREG_NOTUPDT));
}
/*---------------------------------------------------------------------------
* vip_get_capture_state
*
* This routine reads the current capture status of the VIP hardware.
*---------------------------------------------------------------------------*/
unsigned long vip_get_capture_state (void)
{
return ((READ_VIP32(VIP_CONTROL1) & VIP_CONTROL1_RUNMODE_MASK) >> VIP_CONTROL1_RUNMODE_SHIFT);
}
/*---------------------------------------------------------------------------
* vip_get_current_line
*
* This routine returns the current line that is being processed.
*---------------------------------------------------------------------------*/
unsigned long vip_get_current_line (void)
{
return (READ_VIP32(VIP_CURRENT_TARGET) & VIP_CTARGET_CLINE_MASK);
}
/*---------------------------------------------------------------------------
* vip_read_fifo
*
* This routine reads from the specified fifo address. As the fifo access
* enable should be disabled when running in normal vip mode, this routine
* enables and disables access around the read.
* DIAGNOSTIC USE ONLY
*---------------------------------------------------------------------------*/
unsigned long vip_read_fifo(unsigned long dwFifoAddress)
{
unsigned long fifo_data;
/* ENABLE FIFO ACCESS */
vip_enable_fifo_access (1);
/* NOW READ THE DATA */
WRITE_VIP32(VIP_FIFO_ADDRESS, dwFifoAddress);
fifo_data = READ_VIP32(VIP_FIFO_DATA);
/* DISABLE FIFO ACCESS */
vip_enable_fifo_access (0);
return fifo_data;
}
/*---------------------------------------------------------------------------
* vip_write_fifo
*
* SYNOPSIS:
* This routine writes to the specified fifo address. As the fifo access
* enable should be disabled when running in normal vip mode, this routine
* enables and disables access around the write.
* DIAGNOSTIC USE ONLY
*---------------------------------------------------------------------------*/
int vip_write_fifo (unsigned long dwFifoAddress, unsigned long dwFifoData)
{
/* ENABLE FIFO ACCESS */
vip_enable_fifo_access(1);
/* WRITE THE FIFO DATA */
WRITE_VIP32(VIP_FIFO_ADDRESS, dwFifoAddress);
WRITE_VIP32(VIP_FIFO_DATA, dwFifoData);
/* DISABLE FIFO ACCESS */
vip_enable_fifo_access(0);
return CIM_STATUS_OK;
}
/*---------------------------------------------------------------------------
* vip_enable_fifo_access
*
* This routine enables/disables access to the vip fifo.
* DIAGNOSTIC USE ONLY
*---------------------------------------------------------------------------*/
int vip_enable_fifo_access (int enable)
{
unsigned long cw2;
cw2 = READ_VIP32(VIP_CONTROL2);
if (enable) cw2 |= VIP_CONTROL2_FIFO_ACCESS;
else cw2 &= ~VIP_CONTROL2_FIFO_ACCESS;
WRITE_VIP32(VIP_CONTROL2, cw2);
return CIM_STATUS_OK;
}
/*---------------------------------------------------------------------------
* vip_get_power_characteristics
*
* This routine returns the current VIP clock gating state in a VIPPOWERBUFFER.
*---------------------------------------------------------------------------*/
int vip_get_power_characteristics(VIPPOWERBUFFER *buffer)
{
Q_WORD q_word;
if (!buffer)
return CIM_STATUS_INVALIDPARAMS;
/* READ THE EXISTING STATE */
msr_read64(MSR_DEVICE_GEODELX_VIP, MSR_GEODELINK_PM, &q_word);
/* DECODE THE CLOCK GATING BITS */
buffer->glink_clock_mode = (int)(q_word.low & VIP_MSR_POWER_GLINK);
buffer->vip_clock_mode = (int)(q_word.low & VIP_MSR_POWER_CLOCK);
return CIM_STATUS_OK;
}
/*---------------------------------------------------------------------------
* vip_get_priority_characteristics
*
* This routine returns the priority characteristics in the supplied
* VIPPRIORITYBUFFER.
*---------------------------------------------------------------------------*/
int vip_get_priority_characteristics(VIPPRIORITYBUFFER *buffer)
{
Q_WORD q_word;
if (!buffer)
return CIM_STATUS_INVALIDPARAMS;
/* READ THE CURRENT STATE */
msr_read64 (MSR_DEVICE_GEODELX_VIP, MSR_GEODELINK_CONFIG, &q_word);
/* DECODE THE PRIORITIES */
buffer->secondary = (q_word.low & VIP_MSR_MCR_SECOND_PRIORITY_MASK) >> VIP_MSR_MCR_SECOND_PRIORITY_SHIFT;
buffer->primary = (q_word.low & VIP_MSR_MCR_PRIMARY_PRIORITY_MASK) >> VIP_MSR_MCR_PRIMARY_PRIORITY_SHIFT;
buffer->pid = q_word.low & VIP_MSR_MCR_PID_MASK;
return CIM_STATUS_OK;
}
/*---------------------------------------------------------------------------
* vip_get_capability_characteristics
*
* This routine returns revision information for the device.
*---------------------------------------------------------------------------*/
int vip_get_capability_characteristics(VIPCAPABILITIESBUFFER *buffer)
{
Q_WORD q_word ;
if (!buffer)
return CIM_STATUS_INVALIDPARAMS;
/* READ THE CURRENT MSR CONTENTS */
msr_read64 (MSR_DEVICE_GEODELX_VIP, MSR_GEODELINK_CAP, &q_word);
/* DECODE THE REVISIONS */
buffer->revision_id = (q_word.low & VIP_MSR_CAP_REVID_MASK) >> VIP_MSR_CAP_REVID_SHIFT;
buffer->device_id = (q_word.low & VIP_MSR_CAP_DEVID_MASK) >> VIP_MSR_CAP_DEVID_SHIFT;
buffer->n_clock_domains = (q_word.low & VIP_MSR_CAP_NCLK_MASK) >> VIP_MSR_CAP_NCLK_SHIFT;
buffer->n_smi_registers = (q_word.low & VIP_MSR_CAP_NSMI_MASK) >> VIP_MSR_CAP_NSMI_SHIFT;
return CIM_STATUS_OK;
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -