mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-07 11:26:02 +09:00
media: rockchip: hdmirx: Enhance stability when signal changes
1. Modify the polarity configuration. 2. Monitor timing changes using VMON_VMEAS/VMON_HMEAS interrupts. 3. Add sip_hdmirx_config operation, cooperate with bl31 reset controller logic. 4. Configure the HPD low time to 1 second to enhance compatibility. Signed-off-by: Dingxian Wen <shawn.wen@rock-chips.com> Change-Id: I4f55e0ece74df7c9e82391bae6afb4154fec96d9
This commit is contained in:
@@ -766,6 +766,9 @@ static void hdmirx_get_timings(struct rk_hdmirx_dev *hdmirx_dev,
|
||||
vfp = vtotal - vact - vs - vbp;
|
||||
}
|
||||
|
||||
if (!from_dma)
|
||||
hact = (hact * 24) / hdmirx_dev->color_depth;
|
||||
|
||||
fps = (bt->pixelclock + (htotal * vtotal) / 2) / (htotal * vtotal);
|
||||
if (hdmirx_dev->pix_fmt == HDMIRX_YUV420)
|
||||
fps *= 2;
|
||||
@@ -863,41 +866,10 @@ static int hdmirx_get_detected_timings(struct rk_hdmirx_dev *hdmirx_dev,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void hdmirx_set_negative_pol(struct rk_hdmirx_dev *hdmirx_dev, bool en)
|
||||
{
|
||||
if (en) {
|
||||
hdmirx_update_bits(hdmirx_dev, DMA_CONFIG6,
|
||||
VSYNC_TOGGLE_EN|
|
||||
HSYNC_TOGGLE_EN,
|
||||
VSYNC_TOGGLE_EN|
|
||||
HSYNC_TOGGLE_EN);
|
||||
hdmirx_update_bits(hdmirx_dev, VIDEO_CONFIG2,
|
||||
VPROC_VSYNC_POL_OVR_VALUE|
|
||||
VPROC_VSYNC_POL_OVR_EN|
|
||||
VPROC_HSYNC_POL_OVR_VALUE|
|
||||
VPROC_HSYNC_POL_OVR_EN,
|
||||
VPROC_VSYNC_POL_OVR_EN|
|
||||
VPROC_HSYNC_POL_OVR_EN);
|
||||
return;
|
||||
}
|
||||
|
||||
hdmirx_update_bits(hdmirx_dev, DMA_CONFIG6,
|
||||
VSYNC_TOGGLE_EN|
|
||||
HSYNC_TOGGLE_EN,
|
||||
0);
|
||||
|
||||
hdmirx_update_bits(hdmirx_dev, VIDEO_CONFIG2,
|
||||
VPROC_VSYNC_POL_OVR_VALUE|
|
||||
VPROC_VSYNC_POL_OVR_EN|
|
||||
VPROC_HSYNC_POL_OVR_VALUE|
|
||||
VPROC_HSYNC_POL_OVR_EN,
|
||||
0);
|
||||
}
|
||||
|
||||
static int hdmirx_try_to_get_timings(struct rk_hdmirx_dev *hdmirx_dev,
|
||||
struct v4l2_dv_timings *timings, int try_cnt)
|
||||
{
|
||||
int i, cnt = 0, fail_cnt = 0, ret = 0;
|
||||
int i, cnt = 0, ret = 0;
|
||||
bool from_dma = false;
|
||||
struct v4l2_device *v4l2_dev = &hdmirx_dev->v4l2_dev;
|
||||
u32 last_w, last_h;
|
||||
@@ -905,7 +877,6 @@ static int hdmirx_try_to_get_timings(struct rk_hdmirx_dev *hdmirx_dev,
|
||||
|
||||
last_w = 0;
|
||||
last_h = 0;
|
||||
hdmirx_set_negative_pol(hdmirx_dev, false);
|
||||
for (i = 0; i < try_cnt; i++) {
|
||||
ret = hdmirx_get_detected_timings(hdmirx_dev, timings, from_dma);
|
||||
|
||||
@@ -914,16 +885,10 @@ static int hdmirx_try_to_get_timings(struct rk_hdmirx_dev *hdmirx_dev,
|
||||
last_h = bt->height;
|
||||
}
|
||||
|
||||
if (ret || (last_w != bt->width) || (last_h != bt->height)) {
|
||||
if (ret || (last_w != bt->width) || (last_h != bt->height))
|
||||
cnt = 0;
|
||||
fail_cnt++;
|
||||
if (fail_cnt > 3) {
|
||||
hdmirx_set_negative_pol(hdmirx_dev, true);
|
||||
from_dma = true;
|
||||
}
|
||||
} else {
|
||||
else
|
||||
cnt++;
|
||||
}
|
||||
|
||||
if (cnt >= 8)
|
||||
break;
|
||||
@@ -933,7 +898,7 @@ static int hdmirx_try_to_get_timings(struct rk_hdmirx_dev *hdmirx_dev,
|
||||
usleep_range(10*1000, 10*1100);
|
||||
}
|
||||
|
||||
if (try_cnt > 8 && cnt < 5)
|
||||
if (try_cnt > 8 && cnt < 8)
|
||||
v4l2_dbg(1, debug, v4l2_dev, "%s: res not stable!\n", __func__);
|
||||
|
||||
return ret;
|
||||
@@ -957,13 +922,7 @@ static int hdmirx_query_dv_timings(struct file *file, void *_fh,
|
||||
return -ENOLCK;
|
||||
}
|
||||
|
||||
/*
|
||||
* query dv timings is during preview, dma's timing is stable,
|
||||
* so we can get from DMA. If the current resolution is negative,
|
||||
* get timing from CTRL need to change polarity of sync,
|
||||
* maybe cause DMA errors.
|
||||
*/
|
||||
ret = hdmirx_get_detected_timings(hdmirx_dev, timings, true);
|
||||
ret = hdmirx_get_detected_timings(hdmirx_dev, timings, false);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
@@ -1012,6 +971,8 @@ static void hdmirx_hpd_config(struct rk_hdmirx_dev *hdmirx_dev, bool en)
|
||||
v4l2_dbg(1, debug, v4l2_dev, "%s: %sable, hpd_trigger_level:%d\n",
|
||||
__func__, en ? "en" : "dis",
|
||||
hdmirx_dev->hpd_trigger_level);
|
||||
if (!en)
|
||||
sip_hdmirx_config(HDMIRX_INFO_NOTIFY, 0, DMA_CONFIG6, 0);
|
||||
hdmirx_update_bits(hdmirx_dev, SCDC_CONFIG, HPDLOW, en ? 0 : HPDLOW);
|
||||
level = hdmirx_dev->hpd_trigger_level ? en : !en;
|
||||
hdmirx_writel(hdmirx_dev, CORE_CONFIG, level);
|
||||
@@ -1133,7 +1094,7 @@ static int hdmirx_set_edid(struct file *file, void *fh,
|
||||
sip_fiq_control(RK_SIP_FIQ_CTRL_FIQ_EN, RK_IRQ_HDMIRX_HDMI, 0);
|
||||
schedule_delayed_work_on(hdmirx_dev->bound_cpu,
|
||||
&hdmirx_dev->delayed_work_hotplug,
|
||||
msecs_to_jiffies(500));
|
||||
msecs_to_jiffies(1000));
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1417,6 +1378,17 @@ static void hdmirx_controller_init(struct rk_hdmirx_dev *hdmirx_dev)
|
||||
if (i == WAIT_TIMER_LOCK_TIME)
|
||||
dev_err(dev, "%s wait timer base lock failed!\n", __func__);
|
||||
|
||||
hdmirx_update_bits(hdmirx_dev, VIDEO_CONFIG2,
|
||||
VPROC_VSYNC_POL_OVR_VALUE |
|
||||
VPROC_VSYNC_POL_OVR_EN |
|
||||
VPROC_HSYNC_POL_OVR_VALUE |
|
||||
VPROC_HSYNC_POL_OVR_EN,
|
||||
VPROC_VSYNC_POL_OVR_VALUE |
|
||||
VPROC_VSYNC_POL_OVR_EN |
|
||||
VPROC_HSYNC_POL_OVR_VALUE |
|
||||
VPROC_HSYNC_POL_OVR_EN);
|
||||
hdmirx_update_bits(hdmirx_dev, VMON_CONTROL,
|
||||
VMON_SOURCE_SEL_MASK, VMON_SOURCE_SEL_DEFRAMER(0x2));
|
||||
hdmirx_update_bits(hdmirx_dev, CMU_CONFIG0,
|
||||
TMDSQPCLK_STABLE_FREQ_MARGIN_MASK |
|
||||
AUDCLK_STABLE_FREQ_MARGIN_MASK,
|
||||
@@ -1435,9 +1407,6 @@ static void hdmirx_controller_init(struct rk_hdmirx_dev *hdmirx_dev)
|
||||
CED_GBCHECKEN_QST |
|
||||
CED_CTRLCHECKEN_QST |
|
||||
CED_CHLOCKMAXER_QST(0x10));
|
||||
hdmirx_update_bits(hdmirx_dev, DEFRAMER_CONFIG0,
|
||||
VS_REMAPFILTER_EN_QST | VS_FILTER_ORDER_QST_MASK,
|
||||
VS_REMAPFILTER_EN_QST | VS_FILTER_ORDER_QST(0x3));
|
||||
}
|
||||
|
||||
static void hdmirx_format_change(struct rk_hdmirx_dev *hdmirx_dev)
|
||||
@@ -1453,7 +1422,7 @@ static void hdmirx_format_change(struct rk_hdmirx_dev *hdmirx_dev)
|
||||
if (hdmirx_try_to_get_timings(hdmirx_dev, &timings, 20)) {
|
||||
schedule_delayed_work_on(hdmirx_dev->bound_cpu,
|
||||
&hdmirx_dev->delayed_work_hotplug,
|
||||
msecs_to_jiffies(20));
|
||||
msecs_to_jiffies(1000));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1559,6 +1528,7 @@ static int hdmirx_wait_lock_and_get_timing(struct rk_hdmirx_dev *hdmirx_dev)
|
||||
PKTDEC_AVIIF_RCV_IRQ, 0);
|
||||
}
|
||||
|
||||
hdmirx_reset_dma(hdmirx_dev);
|
||||
usleep_range(200*1000, 200*1010);
|
||||
hdmirx_format_change(hdmirx_dev);
|
||||
|
||||
@@ -1965,7 +1935,18 @@ static void hdmirx_stop_streaming(struct vb2_queue *queue)
|
||||
}
|
||||
|
||||
hdmirx_update_bits(hdmirx_dev, DMA_CONFIG6, HDMIRX_DMA_EN, 0);
|
||||
hdmirx_writel(hdmirx_dev, DMA_CONFIG5, 0xffffffff);
|
||||
hdmirx_update_bits(hdmirx_dev, DMA_CONFIG4,
|
||||
LINE_FLAG_INT_EN |
|
||||
HDMIRX_DMA_IDLE_INT |
|
||||
HDMIRX_LOCK_DISABLE_INT |
|
||||
LAST_FRAME_AXI_UNFINISH_INT_EN |
|
||||
FIFO_OVERFLOW_INT_EN |
|
||||
FIFO_UNDERFLOW_INT_EN |
|
||||
HDMIRX_AXI_ERROR_INT_EN, 0);
|
||||
return_all_buffers(stream, VB2_BUF_STATE_ERROR);
|
||||
sip_hdmirx_config(HDMIRX_INFO_NOTIFY, 0, DMA_CONFIG6, 0);
|
||||
sip_hdmirx_config(HDMIRX_AUTO_TOUCH_EN, 0, 0, 0);
|
||||
mutex_unlock(&hdmirx_dev->stream_lock);
|
||||
v4l2_info(v4l2_dev, "stream stopping finished\n");
|
||||
}
|
||||
@@ -1986,6 +1967,7 @@ static int hdmirx_start_streaming(struct vb2_queue *queue, unsigned int count)
|
||||
}
|
||||
|
||||
mutex_lock(&hdmirx_dev->stream_lock);
|
||||
sip_hdmirx_config(HDMIRX_AUTO_TOUCH_EN, 0, 1, 100);
|
||||
stream->frame_idx = 0;
|
||||
stream->line_flag_int_cnt = 0;
|
||||
stream->curr_buf = NULL;
|
||||
@@ -2031,6 +2013,7 @@ static int hdmirx_start_streaming(struct vb2_queue *queue, unsigned int count)
|
||||
v4l2_err(v4l2_dev, "height err: %d\n", bt->height);
|
||||
}
|
||||
|
||||
sip_hdmirx_config(HDMIRX_INFO_NOTIFY, 0, DMA_CONFIG6, HDMIRX_DMA_EN);
|
||||
hdmirx_writel(hdmirx_dev, DMA_CONFIG5, 0xffffffff);
|
||||
hdmirx_writel(hdmirx_dev, CED_DYN_CONTROL, 0x1);
|
||||
hdmirx_update_bits(hdmirx_dev, DMA_CONFIG4,
|
||||
@@ -2118,7 +2101,7 @@ static long hdmirx_ioctl_default(struct file *file, void *fh,
|
||||
hdmirx_reset_all(hdmirx_dev);
|
||||
schedule_delayed_work_on(hdmirx_dev->bound_cpu,
|
||||
&hdmirx_dev->delayed_work_hotplug,
|
||||
msecs_to_jiffies(10));
|
||||
msecs_to_jiffies(1000));
|
||||
break;
|
||||
case RK_HDMIRX_CMD_GET_HDCP_STATUS:
|
||||
*(int *)arg = hdmirx_get_hdcp_auth_status(hdmirx_dev);
|
||||
@@ -2274,6 +2257,8 @@ static void process_signal_change(struct rk_hdmirx_dev *hdmirx_dev)
|
||||
.type = RK_HDMIRX_V4L2_EVENT_SIGNAL_LOST,
|
||||
};
|
||||
|
||||
hdmirx_dev->get_timing = false;
|
||||
sip_hdmirx_config(HDMIRX_INFO_NOTIFY, 0, DMA_CONFIG6, 0);
|
||||
hdmirx_update_bits(hdmirx_dev, DMA_CONFIG6, HDMIRX_DMA_EN, 0);
|
||||
hdmirx_update_bits(hdmirx_dev, DMA_CONFIG4,
|
||||
LINE_FLAG_INT_EN |
|
||||
@@ -2284,13 +2269,12 @@ static void process_signal_change(struct rk_hdmirx_dev *hdmirx_dev)
|
||||
FIFO_UNDERFLOW_INT_EN |
|
||||
HDMIRX_AXI_ERROR_INT_EN, 0);
|
||||
hdmirx_reset_dma(hdmirx_dev);
|
||||
hdmirx_dev->get_timing = false;
|
||||
v4l2_event_queue(&stream->vdev, &evt_signal_lost);
|
||||
if (hdmirx_dev->hdcp && hdmirx_dev->hdcp->hdcp_stop)
|
||||
hdmirx_dev->hdcp->hdcp_stop(hdmirx_dev->hdcp);
|
||||
schedule_delayed_work_on(hdmirx_dev->bound_cpu,
|
||||
&hdmirx_dev->delayed_work_res_change,
|
||||
msecs_to_jiffies(800));
|
||||
msecs_to_jiffies(1000));
|
||||
}
|
||||
|
||||
static void avpunit_0_int_handler(struct rk_hdmirx_dev *hdmirx_dev,
|
||||
@@ -2301,7 +2285,6 @@ static void avpunit_0_int_handler(struct rk_hdmirx_dev *hdmirx_dev,
|
||||
if (status & (CED_DYN_CNT_CH2_IRQ |
|
||||
CED_DYN_CNT_CH1_IRQ |
|
||||
CED_DYN_CNT_CH0_IRQ)) {
|
||||
process_signal_change(hdmirx_dev);
|
||||
v4l2_dbg(2, debug, v4l2_dev, "%s: avp0_st:%#x\n",
|
||||
__func__, status);
|
||||
*handled = true;
|
||||
@@ -2316,6 +2299,13 @@ static void avpunit_1_int_handler(struct rk_hdmirx_dev *hdmirx_dev,
|
||||
{
|
||||
struct v4l2_device *v4l2_dev = &hdmirx_dev->v4l2_dev;
|
||||
|
||||
if (status & (VMON_VMEAS_IRQ | VMON_HMEAS_IRQ)) {
|
||||
process_signal_change(hdmirx_dev);
|
||||
v4l2_dbg(2, debug, v4l2_dev, "%s: avp1_st:%#x\n",
|
||||
__func__, status);
|
||||
*handled = true;
|
||||
}
|
||||
|
||||
if (status & DEFRAMER_VSYNC_THR_REACHED_IRQ) {
|
||||
v4l2_info(v4l2_dev, "Vertical Sync threshold reached interrupt %#x", status);
|
||||
hdmirx_update_bits(hdmirx_dev, AVPUNIT_1_INT_MASK_N,
|
||||
@@ -2325,6 +2315,9 @@ static void avpunit_1_int_handler(struct rk_hdmirx_dev *hdmirx_dev,
|
||||
&hdmirx_dev->delayed_work_audio, HZ / 2);
|
||||
*handled = true;
|
||||
}
|
||||
|
||||
hdmirx_clear_interrupt(hdmirx_dev, AVPUNIT_1_INT_CLEAR, 0xffffffff);
|
||||
hdmirx_writel(hdmirx_dev, AVPUNIT_1_INT_FORCE, 0x0);
|
||||
}
|
||||
static void mainunit_0_int_handler(struct rk_hdmirx_dev *hdmirx_dev,
|
||||
int status, bool *handled)
|
||||
@@ -2596,24 +2589,25 @@ static irqreturn_t hdmirx_dma_irq_handler(int irq, void *dev_id)
|
||||
v4l2_dbg(3, debug, v4l2_dev, "dma_irq st1:%#x, st13:%d\n",
|
||||
dma_stat1, dma_stat13);
|
||||
|
||||
if (stream->stopping) {
|
||||
v4l2_dbg(1, debug, v4l2_dev, "%s: stop stream!\n", __func__);
|
||||
stream->stopping = false;
|
||||
hdmirx_writel(hdmirx_dev, DMA_CONFIG5, 0xffffffff);
|
||||
hdmirx_update_bits(hdmirx_dev, DMA_CONFIG4,
|
||||
LINE_FLAG_INT_EN |
|
||||
HDMIRX_DMA_IDLE_INT |
|
||||
HDMIRX_LOCK_DISABLE_INT |
|
||||
LAST_FRAME_AXI_UNFINISH_INT_EN |
|
||||
FIFO_OVERFLOW_INT_EN |
|
||||
FIFO_UNDERFLOW_INT_EN |
|
||||
HDMIRX_AXI_ERROR_INT_EN, 0);
|
||||
wake_up(&stream->wq_stopped);
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
if (dma_stat1 & HDMIRX_DMA_IDLE_INT) {
|
||||
if (stream->stopping) {
|
||||
v4l2_dbg(1, debug, v4l2_dev, "%s: stop stream!\n", __func__);
|
||||
stream->stopping = false;
|
||||
hdmirx_writel(hdmirx_dev, DMA_CONFIG5, 0xffffffff);
|
||||
hdmirx_update_bits(hdmirx_dev, DMA_CONFIG4,
|
||||
LINE_FLAG_INT_EN |
|
||||
HDMIRX_DMA_IDLE_INT |
|
||||
HDMIRX_LOCK_DISABLE_INT |
|
||||
LAST_FRAME_AXI_UNFINISH_INT_EN |
|
||||
FIFO_OVERFLOW_INT_EN |
|
||||
FIFO_UNDERFLOW_INT_EN |
|
||||
HDMIRX_AXI_ERROR_INT_EN, 0);
|
||||
wake_up(&stream->wq_stopped);
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
if (dma_stat1 & HDMIRX_DMA_IDLE_INT)
|
||||
dma_idle_int_handler(hdmirx_dev, &handled);
|
||||
}
|
||||
|
||||
if (dma_stat1 & LINE_FLAG_INT_EN)
|
||||
line_flag_int_handler(hdmirx_dev, &handled);
|
||||
@@ -2645,12 +2639,43 @@ static void hdmirx_audio_interrupts_setup(struct rk_hdmirx_dev *hdmirx_dev, bool
|
||||
|
||||
static void hdmirx_interrupts_setup(struct rk_hdmirx_dev *hdmirx_dev, bool en)
|
||||
{
|
||||
struct v4l2_bt_timings *bt = &hdmirx_dev->timings.bt;
|
||||
|
||||
v4l2_dbg(1, debug, &hdmirx_dev->v4l2_dev, "%s: %sable\n",
|
||||
__func__, en ? "en" : "dis");
|
||||
|
||||
if (en && bt->pixelclock > 590000000) {
|
||||
hdmirx_update_bits(hdmirx_dev, VMON_CONTROL,
|
||||
VMON_IRQ_THR_MASK, VMON_IRQ_THR_MASK);
|
||||
hdmirx_update_bits(hdmirx_dev, VMON_CONTROL2,
|
||||
VMON_IRQ_VERTICAL_MASK |
|
||||
VMON_IRQ_HORIZONAL_MASK,
|
||||
VMON_IRQ_VERTICAL_SEL(0x1f) |
|
||||
VMON_IRQ_HORIZONAL_SEL(0x1f));
|
||||
hdmirx_update_bits(hdmirx_dev, DEFRAMER_CONFIG0,
|
||||
VS_REMAPFILTER_EN_QST |
|
||||
VS_FILTER_ORDER_QST_MASK |
|
||||
HS_FILTER_ORDER_QST_MASK,
|
||||
VS_REMAPFILTER_EN_QST |
|
||||
VS_FILTER_ORDER_QST(0x3) |
|
||||
HS_FILTER_ORDER_QST(0x0));
|
||||
} else {
|
||||
hdmirx_update_bits(hdmirx_dev, VMON_CONTROL,
|
||||
VMON_IRQ_THR_MASK, 0);
|
||||
hdmirx_update_bits(hdmirx_dev, VMON_CONTROL2,
|
||||
VMON_IRQ_VERTICAL_MASK |
|
||||
VMON_IRQ_HORIZONAL_MASK,
|
||||
VMON_IRQ_VERTICAL_SEL(0x1f) |
|
||||
VMON_IRQ_HORIZONAL_SEL(0x0));
|
||||
hdmirx_update_bits(hdmirx_dev, DEFRAMER_CONFIG0,
|
||||
HS_FILTER_ORDER_QST_MASK,
|
||||
HS_FILTER_ORDER_QST(0x3));
|
||||
}
|
||||
|
||||
hdmirx_clear_interrupt(hdmirx_dev, MAINUNIT_0_INT_CLEAR, 0xffffffff);
|
||||
hdmirx_clear_interrupt(hdmirx_dev, MAINUNIT_2_INT_CLEAR, 0xffffffff);
|
||||
hdmirx_clear_interrupt(hdmirx_dev, AVPUNIT_0_INT_CLEAR, 0xffffffff);
|
||||
hdmirx_clear_interrupt(hdmirx_dev, AVPUNIT_1_INT_CLEAR, 0xffffffff);
|
||||
|
||||
if (en) {
|
||||
hdmirx_update_bits(hdmirx_dev, MAINUNIT_0_INT_MASK_N,
|
||||
@@ -2658,18 +2683,20 @@ static void hdmirx_interrupts_setup(struct rk_hdmirx_dev *hdmirx_dev, bool en)
|
||||
TMDSQPCLK_OFF_CHG | TMDSQPCLK_LOCKED_CHG);
|
||||
hdmirx_update_bits(hdmirx_dev, MAINUNIT_2_INT_MASK_N,
|
||||
TMDSVALID_STABLE_CHG, TMDSVALID_STABLE_CHG);
|
||||
hdmirx_update_bits(hdmirx_dev, AVPUNIT_0_INT_MASK_N,
|
||||
CED_DYN_CNT_CH2_IRQ |
|
||||
CED_DYN_CNT_CH1_IRQ |
|
||||
CED_DYN_CNT_CH0_IRQ,
|
||||
CED_DYN_CNT_CH2_IRQ |
|
||||
CED_DYN_CNT_CH1_IRQ |
|
||||
CED_DYN_CNT_CH0_IRQ);
|
||||
hdmirx_update_bits(hdmirx_dev, AVPUNIT_1_INT_MASK_N,
|
||||
VMON_VMEAS_IRQ | VMON_HMEAS_IRQ,
|
||||
VMON_VMEAS_IRQ | VMON_HMEAS_IRQ);
|
||||
} else {
|
||||
hdmirx_writel(hdmirx_dev, MAINUNIT_0_INT_MASK_N, 0);
|
||||
hdmirx_writel(hdmirx_dev, MAINUNIT_2_INT_MASK_N, 0);
|
||||
hdmirx_writel(hdmirx_dev, AVPUNIT_0_INT_MASK_N, 0);
|
||||
hdmirx_writel(hdmirx_dev, AVPUNIT_1_INT_MASK_N, 0);
|
||||
}
|
||||
|
||||
sip_hdmirx_config(HDMIRX_REG_PRE_FETCH, 0, MAINUNIT_0_INT_MASK_N, 0);
|
||||
sip_hdmirx_config(HDMIRX_REG_PRE_FETCH, 0, MAINUNIT_2_INT_MASK_N, 0);
|
||||
sip_hdmirx_config(HDMIRX_REG_PRE_FETCH, 0, AVPUNIT_0_INT_MASK_N, 0);
|
||||
sip_hdmirx_config(HDMIRX_REG_PRE_FETCH, 0, AVPUNIT_1_INT_MASK_N, 0);
|
||||
}
|
||||
|
||||
static void hdmirx_plugin(struct rk_hdmirx_dev *hdmirx_dev)
|
||||
@@ -2682,6 +2709,7 @@ static void hdmirx_plugin(struct rk_hdmirx_dev *hdmirx_dev)
|
||||
&hdmirx_dev->delayed_work_heartbeat, msecs_to_jiffies(10));
|
||||
sip_wdt_config(WDT_START, 0, 0, 0);
|
||||
hdmirx_set_cpu_limit_freq(hdmirx_dev);
|
||||
hdmirx_interrupts_setup(hdmirx_dev, false);
|
||||
hdmirx_submodule_init(hdmirx_dev);
|
||||
hdmirx_update_bits(hdmirx_dev, SCDC_CONFIG, POWERPROVIDED,
|
||||
POWERPROVIDED);
|
||||
@@ -2695,7 +2723,7 @@ static void hdmirx_plugin(struct rk_hdmirx_dev *hdmirx_dev)
|
||||
hdmirx_plugout(hdmirx_dev);
|
||||
schedule_delayed_work_on(hdmirx_dev->bound_cpu,
|
||||
&hdmirx_dev->delayed_work_hotplug,
|
||||
msecs_to_jiffies(200));
|
||||
msecs_to_jiffies(1000));
|
||||
return;
|
||||
}
|
||||
hdmirx_dma_config(hdmirx_dev);
|
||||
@@ -2749,6 +2777,7 @@ static void hdmirx_delayed_work_hotplug(struct work_struct *work)
|
||||
|
||||
mutex_lock(&hdmirx_dev->work_lock);
|
||||
hdmirx_dev->get_timing = false;
|
||||
sip_hdmirx_config(HDMIRX_INFO_NOTIFY, 0, DMA_CONFIG6, 0);
|
||||
v4l2_event_queue(&stream->vdev, &evt_signal_lost);
|
||||
plugin = tx_5v_power_present(hdmirx_dev);
|
||||
v4l2_ctrl_s_ctrl(hdmirx_dev->detect_tx_5v_ctrl, plugin);
|
||||
@@ -3103,6 +3132,7 @@ static void hdmirx_delayed_work_res_change(struct work_struct *work)
|
||||
int ret;
|
||||
|
||||
mutex_lock(&hdmirx_dev->work_lock);
|
||||
sip_hdmirx_config(HDMIRX_INFO_NOTIFY, 0, DMA_CONFIG6, 0);
|
||||
plugin = tx_5v_power_present(hdmirx_dev);
|
||||
v4l2_dbg(1, debug, v4l2_dev, "%s: plugin:%d\n", __func__, plugin);
|
||||
if (plugin) {
|
||||
@@ -3120,7 +3150,7 @@ static void hdmirx_delayed_work_res_change(struct work_struct *work)
|
||||
hdmirx_plugout(hdmirx_dev);
|
||||
schedule_delayed_work_on(hdmirx_dev->bound_cpu,
|
||||
&hdmirx_dev->delayed_work_hotplug,
|
||||
msecs_to_jiffies(200));
|
||||
msecs_to_jiffies(1000));
|
||||
} else {
|
||||
hdmirx_dma_config(hdmirx_dev);
|
||||
hdmirx_interrupts_setup(hdmirx_dev, true);
|
||||
@@ -3466,7 +3496,7 @@ static ssize_t edid_store(struct device *dev,
|
||||
sip_fiq_control(RK_SIP_FIQ_CTRL_FIQ_EN, RK_IRQ_HDMIRX_HDMI, 0);
|
||||
schedule_delayed_work_on(hdmirx_dev->bound_cpu,
|
||||
&hdmirx_dev->delayed_work_hotplug,
|
||||
msecs_to_jiffies(500));
|
||||
msecs_to_jiffies(1000));
|
||||
}
|
||||
|
||||
return count;
|
||||
|
||||
@@ -142,6 +142,8 @@
|
||||
#define VS_POL_QST_MASK GENMASK(17, 16)
|
||||
#define VS_POL_QST(x) UPDATE(x, 17, 16)
|
||||
#define VS_REMAPFILTER_EN_QST BIT(8)
|
||||
#define HS_FILTER_ORDER_QST_MASK GENMASK(3, 2)
|
||||
#define HS_FILTER_ORDER_QST(x) UPDATE(x, 3, 2)
|
||||
#define VS_FILTER_ORDER_QST_MASK GENMASK(1, 0)
|
||||
#define VS_FILTER_ORDER_QST(x) UPDATE(x, 1, 0)
|
||||
#define DEFRAMER_VSYNC_CNT_CLEAR 0x0278
|
||||
@@ -280,6 +282,15 @@
|
||||
#define PKTFIFO_THR_CONFIG1 0x150c
|
||||
#define PKTFIFO_CONTROL 0x1510
|
||||
|
||||
#define VMON_CONTROL 0x1560
|
||||
#define VMON_SOURCE_SEL_MASK GENMASK(30, 28)
|
||||
#define VMON_SOURCE_SEL_DEFRAMER(x) UPDATE(x, 30, 28)
|
||||
#define VMON_IRQ_THR_MASK BIT(24)
|
||||
#define VMON_CONTROL2 0x1564
|
||||
#define VMON_IRQ_VERTICAL_MASK GENMASK(12, 8)
|
||||
#define VMON_IRQ_VERTICAL_SEL(x) UPDATE(x, 12, 8)
|
||||
#define VMON_IRQ_HORIZONAL_MASK GENMASK(4, 0)
|
||||
#define VMON_IRQ_HORIZONAL_SEL(x) UPDATE(x, 4, 0)
|
||||
#define VMON_STATUS1 0x1580
|
||||
#define VMON_STATUS2 0x1584
|
||||
#define VMON_STATUS3 0x1588
|
||||
@@ -401,12 +412,15 @@
|
||||
#define CED_DYN_CNT_CH1_IRQ BIT(21)
|
||||
#define CED_DYN_CNT_CH0_IRQ BIT(20)
|
||||
#define AVPUNIT_1_INT_STATUS 0x5050
|
||||
#define VMON_VMEAS_IRQ BIT(31)
|
||||
#define VMON_HMEAS_IRQ BIT(30)
|
||||
#define DEFRAMER_VSYNC_THR_REACHED_IRQ BIT(1)
|
||||
#define AVPUNIT_1_INT_MASK_N 0x5054
|
||||
#define DEFRAMER_VSYNC_THR_REACHED_MASK_N BIT(1)
|
||||
#define DEFRAMER_VSYNC_MASK_N BIT(0)
|
||||
#define AVPUNIT_1_INT_CLEAR 0x5058
|
||||
#define DEFRAMER_VSYNC_THR_REACHED_CLEAR BIT(1)
|
||||
#define AVPUNIT_1_INT_FORCE 0x505C
|
||||
#define PKT_0_INT_STATUS 0x5080
|
||||
#define PKTDEC_AUDIF_CHG_IRQ BIT(13)
|
||||
#define PKTDEC_ACR_CHG_IRQ BIT(3)
|
||||
|
||||
Reference in New Issue
Block a user