blob: 9aadc97080d4d403c4609a8622564547f90b6627 [file] [log] [blame]
// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
/*
* Copyright (c) 2019 Amlogic, Inc. All rights reserved.
*/
#include <linux/version.h>
#include <linux/module.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/device.h>
#include <linux/mm.h>
#include <linux/major.h>
#include <linux/platform_device.h>
#include <linux/mutex.h>
#include <linux/cdev.h>
#include <linux/slab.h>
#include <linux/uaccess.h>
#include <linux/delay.h>
#include <linux/clk.h>
#include <linux/amlogic/media/vout/vinfo.h>
#include <linux/amlogic/media/vout/hdmi_tx21/enc_clk_config.h>
#include <linux/amlogic/media/vout/hdmi_tx21/hdmi_info_global.h>
#include <linux/amlogic/media/vout/hdmi_tx21/hdmi_tx_module.h>
#include "common.h"
#include "register.h"
#include "../hdmi_tx.h"
/* ENCP_VIDEO_H/V are used for fetching video data from VPP
* and send data to ENCP_DVI/DE_H/V* via a fifo (pixel delay)
* The input timing of HDMITx is from ENCP_DVI/DE_H/V*
*/
static void config_tv_enc_calc(struct hdmitx_dev *hdev, enum hdmi_vic vic)
{
const struct hdmi_timing *tp = NULL;
struct hdmi_timing timing = {0};
const u32 hsync_st = 4; // hsync start pixel count
const u32 vsync_st = 1; // vsync start line count
// Latency in pixel clock from ENCP_VFIFO2VD request to data ready to HDMI
const u32 vfifo2vd_to_hdmi_latency = 2;
u32 de_h_begin = 0;
u32 de_h_end = 0;
u32 de_v_begin = 0;
u32 de_v_end = 0;
bool y420_mode = 0;
if (hdev->para && hdev->para->cs == HDMI_COLORSPACE_YUV420)
y420_mode = 1;
tp = hdmitx21_gettiming_from_vic(vic);
if (!tp) {
pr_info("not find hdmitx vic %d timing\n", vic);
return;
}
pr_info("%s[%d] vic = %d\n", __func__, __LINE__, tp->vic);
timing = *tp;
tp = &timing;
de_h_end = tp->h_total - (tp->h_front - hsync_st);
de_h_begin = de_h_end - tp->h_active;
de_v_end = tp->v_total - (tp->v_front - vsync_st);
de_v_begin = de_v_end - tp->v_active;
// set DVI/HDMI transfer timing
// generate hsync
hd21_write_reg(ENCP_DVI_HSO_BEGIN, hsync_st);
hd21_write_reg(ENCP_DVI_HSO_END, hsync_st + tp->h_sync);
// generate vsync
hd21_write_reg(ENCP_DVI_VSO_BLINE_EVN, vsync_st + y420_mode);
hd21_write_reg(ENCP_DVI_VSO_ELINE_EVN,
vsync_st + tp->v_sync + y420_mode);
hd21_write_reg(ENCP_DVI_VSO_BEGIN_EVN, hsync_st);
hd21_write_reg(ENCP_DVI_VSO_END_EVN, hsync_st);
// generate data valid
hd21_write_reg(ENCP_DE_H_BEGIN, de_h_begin);
hd21_write_reg(ENCP_DE_H_END, de_h_end);
hd21_write_reg(ENCP_DE_V_BEGIN_EVEN, de_v_begin);
hd21_write_reg(ENCP_DE_V_END_EVEN, de_v_end);
// set mode
// Enable Hsync and equalization pulse switch in center; bit[14] cfg_de_v = 1
hd21_write_reg(ENCP_VIDEO_MODE, 0x0040 | (1 << 14));
hd21_write_reg(ENCP_VIDEO_MODE_ADV, 0x18); // Sampling rate: 1
// hd21_write_reg(ENCP_VIDEO_YFP1_HTIME, 140);
// hd21_write_reg(ENCP_VIDEO_YFP2_HTIME, 2060);
// set active region
hd21_write_reg(ENCP_VIDEO_HAVON_BEGIN, de_h_begin - vfifo2vd_to_hdmi_latency);
hd21_write_reg(ENCP_VIDEO_HAVON_END, de_h_end - vfifo2vd_to_hdmi_latency - 1);
hd21_write_reg(ENCP_VIDEO_VAVON_BLINE, de_v_begin);
hd21_write_reg(ENCP_VIDEO_VAVON_ELINE, de_v_end - 1);
//set hsync
hd21_write_reg(ENCP_VIDEO_HSO_BEGIN, hsync_st - vfifo2vd_to_hdmi_latency);
hd21_write_reg(ENCP_VIDEO_HSO_END, hsync_st + tp->h_sync - vfifo2vd_to_hdmi_latency);
//set vsync
hd21_write_reg(ENCP_VIDEO_VSO_BEGIN, 0);
hd21_write_reg(ENCP_VIDEO_VSO_END, 0);
hd21_write_reg(ENCP_VIDEO_VSO_BLINE, vsync_st);
hd21_write_reg(ENCP_VIDEO_VSO_ELINE, vsync_st + tp->v_sync);
//set vtotal & htotal
hd21_write_reg(ENCP_VIDEO_MAX_PXCNT, tp->h_total - 1);
hd21_write_reg(ENCP_VIDEO_MAX_LNCNT, tp->v_total - 1);
// set vfifo2vd
// if(vfifo2vd_en) {
// hd21_write_reg(ENCP_VFIFO2VD_CTL, vfifo2vd_en);
// hd21_write_reg(ENCP_VFIFO2VD_PIXEL_START, de_h_begin - 2);
// hd21_write_reg(ENCP_VFIFO2VD_PIXEL_END, de_h_end - 2);
// hd21_write_reg(ENCP_VFIFO2VD_LINE_TOP_START, de_v_begin);
// hd21_write_reg(ENCP_VFIFO2VD_LINE_TOP_END, de_v_end);
// }
}
static unsigned long modulo(unsigned long a, unsigned long b)
{
if (a >= b)
return a - b;
else
return a;
}
static signed int to_signed(unsigned int a)
{
if (a <= 7)
return a;
else
return a - 16;
}
#define MREG_END_MARKER 0xffff
static const struct reg_s tvregs_1080i60[] = {
{ENCP_VIDEO_EN, 0},
{ENCI_VIDEO_EN, 0},
{VENC_DVI_SETTING, 0x2029},
{ENCP_VIDEO_MAX_PXCNT, 2199},
{ENCP_VIDEO_MAX_LNCNT, 1124},
{ENCP_VIDEO_HSPULS_BEGIN, 88},
{ENCP_VIDEO_HSPULS_END, 264},
{ENCP_VIDEO_HSPULS_SWITCH, 88},
{ENCP_VIDEO_HAVON_BEGIN, 192},
{ENCP_VIDEO_HAVON_END, 2111},
{ENCP_VIDEO_HSO_BEGIN, 0},
{ENCP_VIDEO_HSO_END, 44},
{ENCP_VIDEO_EQPULS_BEGIN, 2288},
{ENCP_VIDEO_EQPULS_END, 2464},
{ENCP_VIDEO_VSPULS_BEGIN, 440},
{ENCP_VIDEO_VSPULS_END, 2200},
{ENCP_VIDEO_VSPULS_BLINE, 0},
{ENCP_VIDEO_VSPULS_ELINE, 4},
{ENCP_VIDEO_EQPULS_BLINE, 0},
{ENCP_VIDEO_EQPULS_ELINE, 4},
{ENCP_VIDEO_VAVON_BLINE, 20},
{ENCP_VIDEO_VAVON_ELINE, 559},
{ENCP_VIDEO_VSO_BEGIN, 30},
{ENCP_VIDEO_VSO_END, 50},
{ENCP_VIDEO_VSO_BLINE, 0},
{ENCP_VIDEO_VSO_ELINE, 5},
{ENCP_VIDEO_YFP1_HTIME, 516},
{ENCP_VIDEO_YFP2_HTIME, 4355},
{VENC_VIDEO_PROG_MODE, 0x100},
{ENCP_VIDEO_OFLD_VOAV_OFST, 0x11},
{ENCP_VIDEO_MODE, 0x5ffc},
{ENCP_VIDEO_MODE_ADV, 0x0018},
{ENCP_VIDEO_SYNC_MODE, 0x207},
{ENCI_VIDEO_EN, 0},
{MREG_END_MARKER, 0},
};
static const struct reg_s tvregs_1080i50[] = {
{ENCP_VIDEO_EN, 0},
{ENCI_VIDEO_EN, 0},
{VENC_DVI_SETTING, 0x202d},
{ENCP_VIDEO_MAX_PXCNT, 2639},
{ENCP_VIDEO_MAX_LNCNT, 1124},
{ENCP_VIDEO_HSPULS_BEGIN, 88},
{ENCP_VIDEO_HSPULS_END, 264},
{ENCP_VIDEO_HSPULS_SWITCH, 88},
{ENCP_VIDEO_HAVON_BEGIN, 192},
{ENCP_VIDEO_HAVON_END, 2111},
{ENCP_VIDEO_HSO_BEGIN, 0},
{ENCP_VIDEO_HSO_END, 44},
{ENCP_VIDEO_VSPULS_BEGIN, 440},
{ENCP_VIDEO_VSPULS_END, 2200},
{ENCP_VIDEO_VSPULS_BLINE, 0},
{ENCP_VIDEO_VSPULS_ELINE, 4},
{ENCP_VIDEO_VAVON_BLINE, 20},
{ENCP_VIDEO_VAVON_ELINE, 559},
{ENCP_VIDEO_VSO_BEGIN, 30},
{ENCP_VIDEO_VSO_END, 50},
{ENCP_VIDEO_VSO_BLINE, 0},
{ENCP_VIDEO_VSO_ELINE, 5},
{ENCP_VIDEO_YFP1_HTIME, 526},
{ENCP_VIDEO_YFP2_HTIME, 4365},
{VENC_VIDEO_PROG_MODE, 0x100},
{ENCP_VIDEO_OFLD_VOAV_OFST, 0x11},
{ENCP_VIDEO_MODE, 0x5ffc},
{ENCP_VIDEO_MODE_ADV, 0x0018},
{ENCP_VIDEO_SYNC_MODE, 0x7},
{ENCI_VIDEO_EN, 0},
{MREG_END_MARKER, 0},
};
static void set_vmode_enc_hw(const struct reg_s *s)
{
if (!s)
return;
while (s->reg != MREG_END_MARKER) {
hd21_write_reg(s->reg, s->val);
s++;
}
}
static void hdmi_tvenc1080i_set(enum hdmi_vic vic)
{
unsigned long VFIFO2VD_TO_HDMI_LATENCY = 2;
unsigned long TOTAL_PIXELS = 0, PIXEL_REPEAT_HDMI = 0,
PIXEL_REPEAT_VENC = 0, ACTIVE_PIXELS = 0;
unsigned int FRONT_PORCH = 88, HSYNC_PIXELS = 0, ACTIVE_LINES = 0,
INTERLACE_MODE = 0, TOTAL_LINES = 0, SOF_LINES = 0,
VSYNC_LINES = 0;
unsigned int LINES_F0 = 0, LINES_F1 = 563, BACK_PORCH = 0,
EOF_LINES = 2, TOTAL_FRAMES = 0;
unsigned long total_pixels_venc = 0;
unsigned long active_pixels_venc = 0;
unsigned long front_porch_venc = 0;
unsigned long hsync_pixels_venc = 0;
unsigned long de_h_begin = 0, de_h_end = 0;
unsigned long de_v_begin_even = 0, de_v_end_even = 0,
de_v_begin_odd = 0, de_v_end_odd = 0;
unsigned long hs_begin = 0, hs_end = 0;
unsigned long vs_adjust = 0;
unsigned long vs_bline_evn = 0, vs_eline_evn = 0,
vs_bline_odd = 0, vs_eline_odd = 0;
unsigned long vso_begin_evn = 0, vso_begin_odd = 0;
const struct hdmi_timing *tp = NULL;
tp = hdmitx21_gettiming_from_vic(vic);
if (!tp) {
pr_info("not find hdmitx vic %d timing\n", vic);
return;
}
pr_info("%s[%d] vic = %d\n", __func__, __LINE__, tp->vic);
switch (vic) {
case HDMI_5_1920x1080i60_16x9:
case HDMI_46_1920x1080i120_16x9:
INTERLACE_MODE = 1;
PIXEL_REPEAT_VENC = 0;
PIXEL_REPEAT_HDMI = 0;
ACTIVE_PIXELS = (1920 * (1 + PIXEL_REPEAT_HDMI));
ACTIVE_LINES = (1080 / (1 + INTERLACE_MODE));
LINES_F0 = 562;
LINES_F1 = 563;
FRONT_PORCH = 88;
HSYNC_PIXELS = 44;
BACK_PORCH = 148;
EOF_LINES = 2;
VSYNC_LINES = 5;
SOF_LINES = 15;
TOTAL_FRAMES = 4;
set_vmode_enc_hw(tvregs_1080i60);
break;
case HDMI_20_1920x1080i50_16x9:
case HDMI_40_1920x1080i100_16x9:
INTERLACE_MODE = 1;
PIXEL_REPEAT_VENC = 0;
PIXEL_REPEAT_HDMI = 0;
ACTIVE_PIXELS = (1920 * (1 + PIXEL_REPEAT_HDMI));
ACTIVE_LINES = (1080 / (1 + INTERLACE_MODE));
LINES_F0 = 562;
LINES_F1 = 563;
FRONT_PORCH = 528;
HSYNC_PIXELS = 44;
BACK_PORCH = 148;
EOF_LINES = 2;
VSYNC_LINES = 5;
SOF_LINES = 15;
TOTAL_FRAMES = 4;
set_vmode_enc_hw(tvregs_1080i50);
break;
default:
break;
}
TOTAL_PIXELS = FRONT_PORCH + HSYNC_PIXELS + BACK_PORCH + ACTIVE_PIXELS;
TOTAL_LINES = LINES_F0 + LINES_F1 * INTERLACE_MODE;
total_pixels_venc = (TOTAL_PIXELS / (1 + PIXEL_REPEAT_HDMI)) *
(1 + PIXEL_REPEAT_VENC);
active_pixels_venc = (ACTIVE_PIXELS / (1 + PIXEL_REPEAT_HDMI)) *
(1 + PIXEL_REPEAT_VENC);
front_porch_venc = (FRONT_PORCH / (1 + PIXEL_REPEAT_HDMI)) *
(1 + PIXEL_REPEAT_VENC);
hsync_pixels_venc =
(HSYNC_PIXELS / (1 + PIXEL_REPEAT_HDMI)) * (1 + PIXEL_REPEAT_VENC);
hd21_write_reg(ENCP_VIDEO_MODE, hd21_read_reg(ENCP_VIDEO_MODE)
| (1 << 14));
/* Program DE timing */
de_h_begin = modulo(hd21_read_reg(ENCP_VIDEO_HAVON_BEGIN) +
VFIFO2VD_TO_HDMI_LATENCY, total_pixels_venc);
de_h_end = modulo(de_h_begin + active_pixels_venc, total_pixels_venc);
hd21_write_reg(ENCP_DE_H_BEGIN, de_h_begin);
hd21_write_reg(ENCP_DE_H_END, de_h_end);
/* Program DE timing for even field */
de_v_begin_even = hd21_read_reg(ENCP_VIDEO_VAVON_BLINE);
de_v_end_even = de_v_begin_even + ACTIVE_LINES;
hd21_write_reg(ENCP_DE_V_BEGIN_EVEN, de_v_begin_even);
hd21_write_reg(ENCP_DE_V_END_EVEN, de_v_end_even);
/* Program DE timing for odd field if needed */
if (INTERLACE_MODE) {
de_v_begin_odd =
to_signed((hd21_read_reg(ENCP_VIDEO_OFLD_VOAV_OFST) & 0xf0)
>> 4) + de_v_begin_even + (TOTAL_LINES - 1) / 2;
de_v_end_odd = de_v_begin_odd + ACTIVE_LINES;
hd21_write_reg(ENCP_DE_V_BEGIN_ODD, de_v_begin_odd);/* 583 */
hd21_write_reg(ENCP_DE_V_END_ODD, de_v_end_odd); /* 1123 */
}
/* Program Hsync timing */
if (de_h_end + front_porch_venc >= total_pixels_venc) {
hs_begin = de_h_end + front_porch_venc - total_pixels_venc;
vs_adjust = 1;
} else {
hs_begin = de_h_end + front_porch_venc;
vs_adjust = 0;
}
hs_end = modulo(hs_begin + hsync_pixels_venc, total_pixels_venc);
hd21_write_reg(ENCP_DVI_HSO_BEGIN, hs_begin);
hd21_write_reg(ENCP_DVI_HSO_END, hs_end);
/* Program Vsync timing for even field */
if (de_v_begin_even >= SOF_LINES + VSYNC_LINES + (1 - vs_adjust))
vs_bline_evn = de_v_begin_even - SOF_LINES - VSYNC_LINES
- (1 - vs_adjust);
else
vs_bline_evn = TOTAL_LINES + de_v_begin_even - SOF_LINES
- VSYNC_LINES - (1 - vs_adjust);
vs_eline_evn = modulo(vs_bline_evn + VSYNC_LINES, TOTAL_LINES);
hd21_write_reg(ENCP_DVI_VSO_BLINE_EVN, vs_bline_evn); /* 0 */
hd21_write_reg(ENCP_DVI_VSO_ELINE_EVN, vs_eline_evn); /* 5 */
vso_begin_evn = hs_begin; /* 2 */
hd21_write_reg(ENCP_DVI_VSO_BEGIN_EVN, vso_begin_evn); /* 2 */
hd21_write_reg(ENCP_DVI_VSO_END_EVN, vso_begin_evn); /* 2 */
/* Program Vsync timing for odd field if needed */
if (INTERLACE_MODE) {
vs_bline_odd = de_v_begin_odd - 1 - SOF_LINES - VSYNC_LINES;
vs_eline_odd = de_v_begin_odd - 1 - SOF_LINES;
vso_begin_odd = modulo(hs_begin + (total_pixels_venc >> 1),
total_pixels_venc);
hd21_write_reg(ENCP_DVI_VSO_BLINE_ODD, vs_bline_odd);
hd21_write_reg(ENCP_DVI_VSO_ELINE_ODD, vs_eline_odd);
hd21_write_reg(ENCP_DVI_VSO_BEGIN_ODD, vso_begin_odd);
hd21_write_reg(ENCP_DVI_VSO_END_ODD, vso_begin_odd);
}
hd21_write_reg(VPU_HDMI_SETTING, (0 << 0) |
(0 << 1) |
(tp->h_pol << 2) |
(tp->v_pol << 3) |
(0 << 4) |
(4 << 5) |
(0 << 8) |
(0 << 12)
);
hd21_set_reg_bits(VPU_HDMI_SETTING, 1, 1, 1);
}
void set_tv_encp_new(struct hdmitx_dev *hdev, u32 enc_index, enum hdmi_vic vic,
u32 enable)
{
u32 reg_offset;
// VENC0A 0x1b
// VENC1A 0x21
// VENC2A 0x23
reg_offset = enc_index == 0 ? 0 : enc_index == 1 ? 0x600 : 0x800;
switch (vic) {
case HDMI_5_1920x1080i60_16x9:
case HDMI_46_1920x1080i120_16x9:
case HDMI_20_1920x1080i50_16x9:
case HDMI_40_1920x1080i100_16x9:
hdmi_tvenc1080i_set(vic);
break;
default:
config_tv_enc_calc(hdev, vic);
break;
}
} /* set_tv_encp_new */
static void config_tv_enci(enum hdmi_vic vic)
{
switch (vic) {
/* for 480i */
case HDMI_6_720x480i60_4x3:
case HDMI_7_720x480i60_16x9:
case HDMI_10_2880x480i60_4x3:
case HDMI_11_2880x480i60_16x9:
case HDMI_50_720x480i120_4x3:
case HDMI_51_720x480i120_16x9:
case HDMI_58_720x480i240_4x3:
case HDMI_59_720x480i240_16x9:
hd21_write_reg(VENC_SYNC_ROUTE, 0); // Set sync route on vpins
// Set hsync/vsync source from interlace vencoder
hd21_write_reg(VENC_VIDEO_PROG_MODE, 0xf0);
hd21_write_reg(ENCI_YC_DELAY, 0x22); // both Y and C delay 2 clock
hd21_write_reg(ENCI_VFIFO2VD_PIXEL_START, 233);
hd21_write_reg(ENCI_VFIFO2VD_PIXEL_END, 233 + 720 * 2);
hd21_write_reg(ENCI_VFIFO2VD_LINE_TOP_START, 17);
hd21_write_reg(ENCI_VFIFO2VD_LINE_TOP_END, 17 + 240);
hd21_write_reg(ENCI_VFIFO2VD_LINE_BOT_START, 18);
hd21_write_reg(ENCI_VFIFO2VD_LINE_BOT_END, 18 + 240);
hd21_write_reg(ENCI_VFIFO2VD_CTL, (0x4e << 8) | 1); // enable vfifo2vd
hd21_write_reg(ENCI_DBG_FLDLN_RST, 0x0f05);
hd21_write_reg(ENCI_SYNC_VSO_EVNLN, 0x0508);
hd21_write_reg(ENCI_SYNC_VSO_ODDLN, 0x0508);
hd21_write_reg(ENCI_SYNC_HSO_BEGIN, 11 - 2);
hd21_write_reg(ENCI_SYNC_HSO_END, 31 - 2);
hd21_write_reg(ENCI_DBG_FLDLN_RST, 0xcf05);
// delay fldln rst to make sure it synced by clk27
hd21_read_reg(ENCI_DBG_FLDLN_RST);
hd21_read_reg(ENCI_DBG_FLDLN_RST);
hd21_read_reg(ENCI_DBG_FLDLN_RST);
hd21_read_reg(ENCI_DBG_FLDLN_RST);
hd21_write_reg(ENCI_DBG_FLDLN_RST, 0x0f05);
break;
/* for 576i */
default:
hd21_write_reg(ENCI_CFILT_CTRL, 0x0800);
hd21_write_reg(ENCI_CFILT_CTRL2, 0x0010);
// adjust the hsync start point and end point
hd21_write_reg(ENCI_SYNC_HSO_BEGIN, 1);
hd21_write_reg(ENCI_SYNC_HSO_END, 127);
// adjust the vsync start line and end line
hd21_write_reg(ENCI_SYNC_VSO_EVNLN, (0 << 8) | 3);
hd21_write_reg(ENCI_SYNC_VSO_ODDLN, (0 << 8) | 3);
// adjust for interlace output, Horizontal offset after HSI in slave mode
hd21_write_reg(ENCI_SYNC_HOFFST, 0x16);
hd21_write_reg(ENCI_MACV_MAX_AMP, 0x8107); // ENCI_MACV_MAX_AMP
hd21_write_reg(VENC_VIDEO_PROG_MODE, 0xff); /* Set for interlace mode */
hd21_write_reg(ENCI_VIDEO_MODE, 0x13); /* Set for PAL mode */
hd21_write_reg(ENCI_VIDEO_MODE_ADV, 0x26); /* Set for High Bandwidth for CBW&YBW */
hd21_write_reg(ENCI_VIDEO_SCH, 0x28); /* Set SCH */
hd21_write_reg(ENCI_SYNC_MODE, 0x07); /* Set for master mode */
/* Set hs/vs out timing */
hd21_write_reg(ENCI_YC_DELAY, 0x341);
hd21_write_reg(ENCI_VFIFO2VD_PIXEL_START, 267);
hd21_write_reg(ENCI_VFIFO2VD_PIXEL_END, 267 + 1440);
hd21_write_reg(ENCI_VFIFO2VD_LINE_TOP_START, 21);
hd21_write_reg(ENCI_VFIFO2VD_LINE_TOP_END, 21 + 288);
hd21_write_reg(ENCI_VFIFO2VD_LINE_BOT_START, 22);
hd21_write_reg(ENCI_VFIFO2VD_LINE_BOT_END, 22 + 288);
hd21_write_reg(ENCI_VFIFO2VD_CTL, (0x4e << 8) | 1); // enable vfifo2vd
hd21_write_reg(ENCI_DBG_PX_RST, 0x0); /* Enable TV encoder */
break;
}
}
void set_tv_enci_new(struct hdmitx_dev *hdev, u32 enc_index, enum hdmi_vic vic,
u32 enable)
{
u32 reg_offset;
reg_offset = enc_index == 0 ? 0 : enc_index == 1 ? 0x600 : 0x800;
config_tv_enci(vic);
} /* set_tv_enci_new */
void hdmitx21_venc_en(bool en, bool pi_mode)
{
if (en == 0) {
hd21_write_reg(ENCP_VIDEO_EN, en);
hd21_write_reg(ENCI_VIDEO_EN, en);
return;
}
if (pi_mode == 1) {
hd21_write_reg(ENCP_VIDEO_EN, 1);
hd21_write_reg(ENCI_VIDEO_EN, 0);
} else {
hd21_write_reg(ENCP_VIDEO_EN, 0);
hd21_write_reg(ENCI_VIDEO_EN, 1);
}
}