From 7556ba8a7ef62ef7370910e5e1175e7ffde53799 Mon Sep 17 00:00:00 2001 From: Bencheng Jing Date: Tue, 28 Nov 2017 13:00:01 +0800 Subject: [PATCH] vdin: amlogic: add vdin driver support PD#154260: vdin: amlogic: add vdin driver support Merge from kernel 3.14. Optimize and fix memset error. Change-Id: I0707de5cb6313da4e1ff8a3a1e91dfb098234529 Signed-off-by: Bencheng Jing --- .../media/vin/tvin/tvin_format_table.c | 277 ++- .../media/vin/tvin/tvin_format_table.h | 14 +- .../amlogic/media/vin/tvin/tvin_frontend.c | 3 - drivers/amlogic/media/vin/tvin/tvin_global.h | 53 +- .../amlogic/media/vin/tvin/vdin/vdin_canvas.c | 620 +++++- .../amlogic/media/vin/tvin/vdin/vdin_canvas.h | 17 +- .../amlogic/media/vin/tvin/vdin/vdin_ctl.c | 1897 +++++++++++++---- .../amlogic/media/vin/tvin/vdin/vdin_ctl.h | 67 +- .../amlogic/media/vin/tvin/vdin/vdin_debug.c | 1272 +++++++---- .../amlogic/media/vin/tvin/vdin/vdin_drv.c | 1641 +++++--------- .../amlogic/media/vin/tvin/vdin/vdin_drv.h | 293 +-- .../amlogic/media/vin/tvin/vdin/vdin_regs.h | 137 +- drivers/amlogic/media/vin/tvin/vdin/vdin_sm.c | 287 +-- drivers/amlogic/media/vin/tvin/vdin/vdin_sm.h | 1 + .../amlogic/media/vin/tvin/vdin/vdin_v4l2.c | 8 +- drivers/amlogic/media/vin/tvin/vdin/vdin_vf.c | 133 +- drivers/amlogic/media/vin/tvin/vdin/vdin_vf.h | 53 +- .../amlogic/media/frame_provider/tvin/tvin.h | 19 +- .../media/frame_provider/tvin/tvin_v4l2.h | 6 +- .../linux/amlogic/media/vfm/vframe_provider.h | 1 + 20 files changed, 4392 insertions(+), 2407 deletions(-) diff --git a/drivers/amlogic/media/vin/tvin/tvin_format_table.c b/drivers/amlogic/media/vin/tvin/tvin_format_table.c index a6ee6a073223..6bf9111aac44 100644 --- a/drivers/amlogic/media/vin/tvin/tvin_format_table.c +++ b/drivers/amlogic/media/vin/tvin/tvin_format_table.c @@ -327,6 +327,10 @@ const char *tvin_sig_fmt_str(enum tvin_sig_fmt_e fmt) /* HDMI Formats */ case TVIN_SIG_FMT_HDMI_640X480P_60HZ: return "TVIN_SIG_FMT_HDMI_640x480P_60Hz"; + case TVIN_SIG_FMT_HDMI_640X480P_72HZ: + return "TVIN_SIG_FMT_HDMI_640x480P_72Hz"; + case TVIN_SIG_FMT_HDMI_640X480P_75HZ: + return "TVIN_SIG_FMT_HDMI_720x480P_75Hz"; case TVIN_SIG_FMT_HDMI_720X480P_60HZ: return "TVIN_SIG_FMT_HDMI_720x480P_60Hz"; case TVIN_SIG_FMT_HDMI_1280X720P_60HZ: @@ -497,6 +501,8 @@ const char *tvin_sig_fmt_str(enum tvin_sig_fmt_e fmt) return "TVIN_SIG_FMT_CVBS_PAL_CN"; case TVIN_SIG_FMT_CVBS_SECAM: return "TVIN_SIG_FMT_CVBS_SECAM"; + case TVIN_SIG_FMT_CVBS_NTSC_50: + return "TVIN_SIG_FMT_CVBS_NTSC_50"; /* 656 Formats */ case TVIN_SIG_FMT_BT656IN_576I_50HZ: return "TVIN_SIG_FMT_BT656IN_576I"; @@ -550,19 +556,19 @@ const struct tvin_format_s *tvin_get_fmt_info(enum tvin_sig_fmt_e fmt) return NULL; /* we also can find format table through port */ /* - * if(port != TVIN_PORT_NULL) - * { - * if ((port >= TVIN_PORT_VGA0) && (port < TVIN_PORT_VGA7)) - * return &tvin_vga_fmt_tbl[fmt-TVIN_SIG_FMT_VGA_512X384P_60HZ_D147]; - * else if ((port >= TVIN_PORT_COMP0) && (port < TVIN_PORT_COMP7)) - * return &tvin_comp_fmt_tbl[fmt-TVIN_SIG_FMT_COMP_480P_60HZ_D000]; - * else if ((port >= TVIN_PORT_CVBS0) && (port <= TVIN_PORT_SVIDEO7)) - * return &tvin_cvbs_fmt_tbl[fmt-TVIN_SIG_FMT_CVBS_NTSC_M]; - * else if ((port >= TVIN_PORT_HDMI0) && (port <= TVIN_PORT_HDMI7)) - * return &tvin_hdmi_fmt_tbl[fmt-TVIN_SIG_FMT_HDMI_640X480P_60HZ]; - * else if ((port >= TVIN_PORT_BT656) && (port <= TVIN_PORT_CAMERA)) - * return &tvin_bt601_fmt_tbl[fmt-TVIN_SIG_FMT_BT656IN_576I_50HZ]; - * } + if (port != TVIN_PORT_NULL) + { + if ((port >= TVIN_PORT_VGA0) && (port < TVIN_PORT_VGA7)) + return &tvin_vga_fmt_tbl[fmt-TVIN_SIG_FMT_VGA_512X384P_60HZ_D147]; + else if ((port >= TVIN_PORT_COMP0) && (port < TVIN_PORT_COMP7)) + return &tvin_comp_fmt_tbl[fmt-TVIN_SIG_FMT_COMP_480P_60HZ_D000]; + else if ((port >= TVIN_PORT_CVBS0) && (port <= TVIN_PORT_SVIDEO7)) + return &tvin_cvbs_fmt_tbl[fmt-TVIN_SIG_FMT_CVBS_NTSC_M]; + else if ((port >= TVIN_PORT_HDMI0) && (port <= TVIN_PORT_HDMI7)) + return &tvin_hdmi_fmt_tbl[fmt-TVIN_SIG_FMT_HDMI_640X480P_60HZ]; + else if ((port >= TVIN_PORT_BT656) && (port <= TVIN_PORT_CAMERA)) + return &tvin_bt601_fmt_tbl[fmt-TVIN_SIG_FMT_BT656IN_576I_50HZ]; + } */ } EXPORT_SYMBOL(tvin_get_fmt_info); @@ -570,10 +576,10 @@ EXPORT_SYMBOL(tvin_get_fmt_info); const struct tvin_format_s tvin_vga_fmt_tbl[TVIN_SIG_FMT_VGA_MAX - TVIN_SIG_FMT_VGA_512X384P_60HZ_D147 + 1] = { /* H_Active V_Active H_cnt Hcnt_offset Vcnt_offset Hs_cnt Hscnt_offset - * H_Total V_Total Hs_Front Hs_Width Hs_bp Vs_Front Vs_Width - * Vs_bp Hs_Polarity Vs_Polarity - * Scan_Mode Pixel_Clk(Khz/10) VBIs VBIe duration - */ + * H_Total V_Total Hs_Front Hs_Width Hs_bp Vs_Front Vs_Width + * Vs_bp Hs_Polarity Vs_Polarity + * Scan_Mode Pixel_Clk(Khz/10) VBIs VBIe duration + */ {/* TVIN_SIG_FMT_VGA_512X384P_60D147, */ 512, 384, 0, 10, 10, 49, 10, 640, 407, 16, 32, 80, 1, 3, @@ -1231,10 +1237,10 @@ EXPORT_SYMBOL(tvin_vga_fmt_tbl); const struct tvin_format_s tvin_comp_fmt_tbl[TVIN_SIG_FMT_COMP_MAX - TVIN_SIG_FMT_COMP_480P_60HZ_D000 + 1] = { /* H_Active V_Active H_cnt Hcnt_offset Vcnt_offset Hs_cnt Hscnt_offset - * H_Total V_Total Hs_Front Hs_Width Hs_bp Vs_Front Vs_Width - * Vs_bp Hs_Polarity Vs_Polarity - * Scan_Mode Pixel_Clk(Khz/10) VBIs VBIe duration - */ + * H_Total V_Total Hs_Front Hs_Width Hs_bp Vs_Front Vs_Width + * Vs_bp Hs_Polarity Vs_Polarity + * Scan_Mode Pixel_Clk(Khz/10) VBIs VBIe duration + */ {/* TVIN_SIG_FMT_COMPONENT_480P_60D000, */ 1440, 480, 762, 20, 20, 55, 10, 1716, 525, 32, 124, 120, 9, 6, @@ -1355,10 +1361,10 @@ EXPORT_SYMBOL(tvin_comp_fmt_tbl); const struct tvin_format_s tvin_comp_fmt_tbl[TVIN_SIG_FMT_COMP_MAX - TVIN_SIG_FMT_COMP_480P_60HZ_D000 + 1] = { /* H_Active V_Active H_cnt Hcnt_offset Vcnt_offset Hs_cnt Hscnt_offset - * H_Total V_Total Hs_Front Hs_Width Hs_bp Vs_Front Vs_Width - * Vs_bp Hs_Polarity Vs_Polarity - * Scan_Mode Pixel_Clk(Khz/10) VBIs VBIe duration - */ + * H_Total V_Total Hs_Front Hs_Width Hs_bp Vs_Front Vs_Width + * Vs_bp Hs_Polarity Vs_Polarity + * Scan_Mode Pixel_Clk(Khz/10) VBIs VBIe duration + */ { /* TVIN_SIG_FMT_COMPONENT_480P_60D000, */ 720, 480, 762, 20, 20, 55, 10, 858, 525, 16, 62, 60, 9, 6, @@ -1946,6 +1952,18 @@ const struct tvin_format_s tvin_hdmi_fmt_tbl[TVIN_SIG_FMT_HDMI_MAX - 39, TVIN_SYNC_POL_NEGATIVE, TVIN_SYNC_POL_NEGATIVE, TVIN_SCAN_MODE_PROGRESSIVE, 5400, 0, 0, 1920 }, + {/* TVIN_SIG_FMT_HDMI_640x480P_72Hz, */ + 640, 480, 0, 10, 10, 0, 10, + 800, 525, 16, 96, 48, 10, 2, + 33, TVIN_SYNC_POL_NEGATIVE, TVIN_SYNC_POL_NEGATIVE, + TVIN_SCAN_MODE_PROGRESSIVE, 3000, 0, 0, 1333 + }, + {/* TVIN_SIG_FMT_HDMI_640x480P_75Hz, */ + 640, 480, 0, 10, 10, 0, 10, + 800, 525, 16, 96, 48, 10, 2, + 33, TVIN_SYNC_POL_NEGATIVE, TVIN_SYNC_POL_NEGATIVE, + TVIN_SCAN_MODE_PROGRESSIVE, 3125, 0, 0, 1066 + }, {/* TVIN_SIG_FMT_HDMI_MAX,//227 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -1958,10 +1976,10 @@ EXPORT_SYMBOL(tvin_hdmi_fmt_tbl); const struct tvin_format_s tvin_cvbs_fmt_tbl[TVIN_SIG_FMT_CVBS_MAX - TVIN_SIG_FMT_CVBS_NTSC_M + 1] = { /* H_Active V_Active H_cnt Hcnt_offset Vcnt_offset Hs_cnt Hscnt_offset - * H_Total V_Total Hs_Front Hs_Width Hs_bp Vs_Front Vs_Width - * Vs_bp Hs_Polarity Vs_Polarity - * Scan_Mode Pixel_Clk(Khz/10) VBIs VBIe duration - */ + * H_Total V_Total Hs_Front Hs_Width Hs_bp Vs_Front Vs_Width + * Vs_bp Hs_Polarity Vs_Polarity + * Scan_Mode Pixel_Clk(Khz/10) VBIs VBIe duration + */ { /* TVIN_SIG_FMT_CVBS_NTSC_M, */ 720, 240, 0, 0, 0, 0, 0, @@ -2005,6 +2023,12 @@ const struct tvin_format_s tvin_cvbs_fmt_tbl[TVIN_SIG_FMT_CVBS_MAX - 0, TVIN_SYNC_POL_NEGATIVE, TVIN_SYNC_POL_NEGATIVE, TVIN_SCAN_MODE_INTERLACED, 1350, 0, 0, 1920 }, + { /* TVIN_SIG_FMT_CVBS_NTSC_50, */ + 720, 240, 0, 0, 0, 0, 0, + 858, 263, 16, 62, 0, 4, 3, + 0, TVIN_SYNC_POL_NEGATIVE, TVIN_SYNC_POL_NEGATIVE, + TVIN_SCAN_MODE_INTERLACED, 1350, 0, 0, 1600 + }, { /* TVIN_SIG_FMT_CVBS_MAX, */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -4303,54 +4327,54 @@ EXPORT_SYMBOL(adc_cvbs_table); #define r1f6 (unsigned char)((CVD2_HSYNC_DTO_SECAM >> 0)&0x000000ff) /* 00~3f */ -const unsigned char cvd_part1_table[TVIN_SIG_FMT_CVBS_SECAM - +const unsigned char cvd_part1_table[TVIN_SIG_FMT_CVBS_NTSC_50 - TVIN_SIG_FMT_CVBS_NTSC_M + 1][CVD_PART1_REG_NUM] = { { 0x00, 0x08, 0x43, 0x10, 0xdd, 0x32, 0x80, 0x4e, 0x7b, 0x1c, 0x78, 0x00, 0x90, 0x00, 0x06, 0x00, 0x0a, 0x09, 0x10, 0xb4, 0x80, 0x20, 0xf6, 0x0d, r180, r190, r1a0, r1b0, r1c0, r1d0, r1e0, r1f0, 0x3e, 0x3e, 0x00, 0x80, 0xf3, 0x3e, 0x6d, 0x5a, 0x07, 0x29, 0xd6, 0x4e, - 0x32, 0x46, 0x82, 0x50, 0x22, 0x61, 0x70, 0x0e, 0x6c, 0x10, 0x00, - 0x23, 0x01, 0x8a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 + 0x32, 0x46, 0x82, 0x50, 0x22, 0x61, 0x70, 0x0e, 0x78, 0x10, 0x00, + 0x23, 0x01, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }, /* TVIN_SIG_FMT_CVBS_NTSC_M, */ { 0x00, 0x01, 0x43, 0x82, 0xdd, 0x32, 0x80, 0x40, 0x7e, 0x20, 0x80, 0x00, 0x8a, 0x00, 0x06, 0x00, 0x37, 0x09, 0x10, 0xb4, 0x80, 0x20, 0xf6, 0x0d, r181, r191, r1a1, r1b1, r1c1, r1d1, r1e1, r1f1, 0x3e, 0x3e, 0x00, 0x80, 0xf3, 0x3e, 0x6d, 0x5a, 0x07, 0x29, 0xd6, 0x4e, - 0x32, 0x46, 0x7a, 0x50, 0x22, 0x61, 0x70, 0x0e, 0x6c, 0x10, 0x00, - 0x23, 0x01, 0x8a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 + 0x32, 0x46, 0x7a, 0x50, 0x22, 0x61, 0x70, 0x0e, 0x78, 0x10, 0x00, + 0x23, 0x01, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }, /* TVIN_SIG_FMT_CVBS_NTSC_443, */ { 0x32, 0x04, 0x43, 0x12, 0xdd, 0x32, 0x80, 0x03, 0x7d, 0x20, 0x78, 0x00, 0x90, 0x00, 0x06, 0x00, 0x37, 0x09, 0x10, 0xb4, 0x80, 0x20, 0xf6, 0x0d, r182, r192, r1a2, r1b2, r1c2, r1d2, r1e2, r1f2, 0x3e, 0x3e, 0x00, 0x80, 0xe7, 0x42, 0x6d, 0x5a, 0x1d, 0xb9, 0xd6, 0x4e, - 0x32, 0x46, 0x8c, 0x50, 0x2a, 0xc0, 0x70, 0x0e, 0x6c, 0x10, 0x00, - 0x23, 0x01, 0x8a, 0x2e, 0x00, 0x0d, 0x00, 0x00, 0x01 + 0x32, 0x46, 0x8c, 0x50, 0x2a, 0xc0, 0x70, 0x0e, 0x78, 0x10, 0x00, + 0x23, 0x01, 0x0a, 0x2e, 0x00, 0x0d, 0x00, 0x00, 0x01 }, /* TVIN_SIG_FMT_CVBS_PAL_I, */ { 0x04, 0x01, 0x43, 0x12, 0xdd, 0x32, 0x80, 0x00, 0x7d, 0x20, 0x80, 0x00, 0x8a, 0x00, 0x06, 0x00, 0x37, 0x09, 0x10, 0xb4, 0x80, 0x20, 0xf6, 0x0d, r183, r193, r1a3, r1b3, r1c3, r1d3, r1e3, r1f3, 0x3e, 0x3e, 0x00, 0x80, 0xf3, 0x3e, 0x6d, 0x5a, 0x07, 0x29, 0xd6, 0x4e, - 0x32, 0x46, 0x82, 0x50, 0x22, 0x61, 0x70, 0x0e, 0x6c, 0x10, 0x00, - 0x23, 0x01, 0x8a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 + 0x32, 0x46, 0x82, 0x50, 0x22, 0x61, 0x70, 0x0e, 0x78, 0x10, 0x00, + 0x23, 0x01, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }, /* TVIN_SIG_FMT_CVBS_PAL_M, */ { 0x04, 0x00, 0x43, 0x02, 0xdd, 0x32, 0x80, 0x00, 0x80, 0x20, 0x80, 0x00, 0x67, 0x01, 0x06, 0x00, 0x37, 0x09, 0x10, 0xb4, 0x80, 0x20, - 0xf6, 0x0d, r184, r194, r1a4, r1b4, r1c4, r1d4, r1e4, r1f4, 0x3e, + 0xf6, 0x0b, r184, r194, r1a4, r1b4, r1c4, r1d4, r1e4, r1f4, 0x3e, 0x3e, 0x00, 0x80, 0xf3, 0x3e, 0x6d, 0x5a, 0x07, 0x29, 0xd6, 0x4e, - 0x32, 0x46, 0x84, 0x50, 0x2a, 0x61, 0x70, 0x0e, 0x6c, 0x10, 0x00, - 0x23, 0x01, 0x8a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 + 0x32, 0x46, 0x84, 0x50, 0x2a, 0x61, 0x70, 0x0e, 0x78, 0x10, 0x00, + 0x23, 0x01, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }, /* TVIN_SIG_FMT_CVBS_PAL_60, */ { 0x36, 0x01, 0x43, 0x12, 0xdd, 0x32, 0x80, 0x00, 0x7d, 0x31, 0x80, 0x00, 0x8a, 0x00, 0x06, 0x00, 0x37, 0x09, 0x10, 0xb4, 0x80, 0x20, 0xf6, 0x0d, r185, r195, r1a5, r1b5, r1c5, r1d5, r1e5, r1f5, 0x3e, 0x3e, 0x00, 0x80, 0xf3, 0x3e, 0x6d, 0x5a, 0x07, 0x29, 0xd6, 0x4e, - 0x32, 0x46, 0x8a, 0x50, 0x2d, 0xc1, 0x70, 0x0e, 0x6c, 0x10, 0x00, + 0x32, 0x46, 0x8a, 0x50, 0x2d, 0xc1, 0x70, 0x0e, 0x78, 0x10, 0x00, 0x23, 0x01, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }, /* TVIN_SIG_FMT_CVBS_PAL_CN, */ { @@ -4358,9 +4382,17 @@ const unsigned char cvd_part1_table[TVIN_SIG_FMT_CVBS_SECAM - 0x00, 0xc8, 0x00, 0x06, 0x00, 0x37, 0x09, 0x10, 0xb4, 0x80, 0x20, 0xf6, 0x0d, r186, r196, r1a6, r1b6, r1c6, r1d6, r1e6, r1f6, 0x3e, 0x3e, 0x00, 0x80, 0xf3, 0x3e, 0x6d, 0x5a, 0x07, 0x29, 0xd6, 0x4e, - 0x3c, 0x6e, 0x76, 0x58, 0x29, 0xbf, 0x70, 0x0e, 0x6c, 0x10, 0x00, - 0x23, 0x01, 0x8a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 + 0x3c, 0x6e, 0x76, 0x58, 0x29, 0xbf, 0x70, 0x0e, 0x78, 0x10, 0x00, + 0x23, 0x01, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }, /* TVIN_SIG_FMT_CVBS_SECAM, */ + { + 0x00, 0x08, 0x43, 0x10, 0xdd, 0x32, 0x80, 0x4e, 0x7b, 0x1c, 0x78, + 0x00, 0x90, 0x00, 0x06, 0x00, 0x0a, 0x09, 0x10, 0xb4, 0x80, 0x20, + 0xf6, 0x0d, r180, r190, r1a0, r1b0, r1c0, r1d0, r1e0, r1f0, 0x3e, + 0x3e, 0x00, 0x80, 0xf3, 0x3e, 0x6d, 0x5a, 0x07, 0x29, 0xd6, 0x4e, + 0x32, 0x46, 0x82, 0x50, 0x22, 0x61, 0x70, 0x0e, 0x6c, 0x10, 0x00, + 0x23, 0x01, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 + }, /* TVIN_SIG_FMT_CVBS_NTSC_50, */ }; EXPORT_SYMBOL(cvd_part1_table); @@ -4390,7 +4422,7 @@ EXPORT_SYMBOL(cvd_part1_table); #define r_f8 0x00 #define r_ff 0x00 /* 70~ff */ -const unsigned char cvd_part2_table[TVIN_SIG_FMT_CVBS_SECAM - +const unsigned char cvd_part2_table[TVIN_SIG_FMT_CVBS_NTSC_50 - TVIN_SIG_FMT_CVBS_NTSC_M + 1][CVD_PART2_REG_NUM] = { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -4400,7 +4432,7 @@ const unsigned char cvd_part2_table[TVIN_SIG_FMT_CVBS_SECAM - r_9c, r_9d, r_9e, r_9f, 0xf2, 0x0b, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x16, 0x0f, 0xc1, r_ad, 0xcf, 0x0f, 0x30, 0x2d, 0x04, 0x0b, 0x23, 0xa2, 0x02, 0x00, 0x00, r_b9, 0x24, 0x5f, 0x00, - 0x25, 0x55, r_bf, 0x14, r_c1, 0x40, 0xc0, 0xfe, 0x90, 0x7d, 0xf0, + 0x25, 0x55, r_bf, 0x14, r_c1, 0x40, 0xc0, 0xfe, 0x90, 0x00, 0xf0, 0x01, 0x50, 0x60, 0x90, 0xe3, 0x0c, 0x23, r_cf, 0xc0, 0x08, 0x10, 0x10, 0x0a, 0x00, 0x0d, 0x00, 0x00, 0x05, 0x00, 0x05, 0x50, r_dd, 0x08, r_df, 0x00, 0x00, 0x00, 0x00, 0x6e, 0x50, 0x00, 0x00, 0x04, @@ -4414,7 +4446,7 @@ const unsigned char cvd_part2_table[TVIN_SIG_FMT_CVBS_SECAM - 0x00, 0x00, 0x00, r_89, 0x0a, 0x11, r_8c, 0x0a, 0x00, 0xe2, 0x00, 0x00, 0x01, 0x00, 0x08, 0x00, 0x00, r_97, r_98, r_99, r_9a, r_9b, r_9c, r_9d, r_9e, r_9f, 0xf2, 0x0b, 0x00, 0x00, 0x08, 0x08, 0x00, - 0x00, 0x00, 0x00, 0x16, 0x0f, 0xc1, r_ad, 0xcf, 0x8c, 0xe0, 0x2d, + 0x00, 0x00, 0x00, 0x16, 0x0f, 0xc1, r_ad, 0xcf, 0x8c, 0x3a, 0xf3, 0x8, 0x03, 0x24, 0xa2, 0x02, 0x00, 0x00, r_b9, 0x24, 0x5f, 0x00, 0x25, 0x55, r_bf, 0x17, r_c1, 0x40, 0xc0, 0xfe, 0x90, 0x00, 0x00, 0x01, 0x50, 0x62, 0x90, 0xe3, 0x0c, 0x23, r_cf, 0xc0, 0x08, 0x10, @@ -4504,11 +4536,27 @@ const unsigned char cvd_part2_table[TVIN_SIG_FMT_CVBS_SECAM - 0xe4, r_f5, r_f6, r_f7, r_f8, 0x01, 0x00, 0x50, 0x6e, 0x05, 0xdc, r_ff }, /* TVIN_SIG_FMT_CVBS_SECAM, */ + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, r_81, 0x42, 0x6f, 0x03, 0x00, + 0x00, 0x00, 0x00, r_89, 0x0a, 0x11, r_8c, 0x0a, 0x00, 0xe2, 0x00, + 0x00, 0x01, 0x08, 0x08, 0x00, 0x00, r_97, r_98, r_99, r_9a, r_9b, + r_9c, r_9d, r_9e, r_9f, 0xf2, 0x0b, 0x00, 0x00, 0x08, 0x08, 0x00, + 0x00, 0x00, 0x00, 0x16, 0x0f, 0xc1, r_ad, 0xcf, 0x0f, 0x30, 0x2d, + 0x04, 0x0b, 0x23, 0xa2, 0x02, 0x00, 0x00, r_b9, 0x24, 0x5f, 0x00, + 0x25, 0x55, r_bf, 0x14, r_c1, 0x40, 0xc0, 0xfe, 0x90, 0x7d, 0xf0, + 0x01, 0x50, 0x60, 0x90, 0xe3, 0x0c, 0x23, r_cf, 0xc0, 0x08, 0x10, + 0x10, 0x0a, 0x00, 0x0d, 0x00, 0x00, 0x05, 0x00, 0x05, 0x50, r_dd, + 0x08, r_df, 0x00, 0x00, 0x00, 0x00, 0x6e, 0x50, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, r_ef, 0x20, 0x40, 0x32, 0x46, + 0xe4, r_f5, r_f6, r_f7, r_f8, 0x01, 0x00, 0x32, 0x50, 0x1c, 0x00, + r_ff + }, /* TVIN_SIG_FMT_CVBS_NTSC_50, */ }; EXPORT_SYMBOL(cvd_part2_table); /* 0x87, 0x93, 0x94, 0x95, 0x96, 0xe6, 0xfa */ -const unsigned int cvd_part3_table[TVIN_SIG_FMT_CVBS_SECAM - +const unsigned int cvd_part3_table[TVIN_SIG_FMT_CVBS_NTSC_50 - TVIN_SIG_FMT_CVBS_NTSC_M + 1][CVD_PART3_REG_NUM] = { { 0x00000000, 0x98000000, 0x0000FF08, 0x00000000, 0x8b000000, @@ -4538,11 +4586,15 @@ const unsigned int cvd_part3_table[TVIN_SIG_FMT_CVBS_SECAM - 0x00000000, 0x98000000, 0x0000FF08, 0x00000000, 0x8b000000, 0x0000008c, 0x00000080 }, /* TVIN_SIG_FMT_CVBS_SECAM, */ + { + 0x00000000, 0x98000000, 0x0000FF08, 0x00000000, 0x8b000000, + 0x0000008c, 0x00000000 + }, /* TVIN_SIG_FMT_CVBS_NTSC_50, */ }; EXPORT_SYMBOL(cvd_part3_table); -const unsigned int cvbs_acd_table[TVIN_SIG_FMT_CVBS_SECAM - +const unsigned int cvbs_acd_table[TVIN_SIG_FMT_CVBS_NTSC_50 - TVIN_SIG_FMT_CVBS_NTSC_M + 1][ACD_REG_NUM+1] = { { 0x10101002, 0x0, 0x7f00e110, 0x08881e18, 0xb36d1858, @@ -4620,7 +4672,7 @@ const unsigned int cvbs_acd_table[TVIN_SIG_FMT_CVBS_SECAM - 0x00000000, 0x021000ff, 0x80688030, 0x81f11111, 0x81f85852, 0x00680068, 0x0487101c, 0x00000003, 0x00000000, 0x00012002, 0x00028040, 0x00000000, 0x10000000, 0x7f1ff000, 0x00000000, - 0x10101040, 0x40404040, 0x80000f5c, 0xff000000, 0x00000000, + 0x10101040, 0x40404040, 0x00000000, 0xff000000, 0x00000000, 0x00000000, 0x00ffffff, 0x00000fff, 0x80000000, 0x00000000, 0x00000000, 0xc00833da, 0xba5b0391, 0x000ae232, 0x00000000, 0xf0080610, 0x60001808, 0x00009410, 0x00000003, 0x00000000, @@ -4833,7 +4885,7 @@ const unsigned int cvbs_acd_table[TVIN_SIG_FMT_CVBS_SECAM - 0x00000000, 0x66666442, 0x20e00044, 0x00000101, 0x00000000, 0x80010101, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x08205040, 0x0050c0c0, - 0x00000000, 0x020f00ff, 0x80808020, 0x81f11111, 0x81f24742, + 0xc9000418, 0x020f00ff, 0x80808020, 0x81f11111, 0x81f24742, 0x80200020, 0x03000000, 0x00000003, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x10000000, 0x7f1ff000, 0x00000000, 0x40404040, 0x40404040, 0x00000000, 0xff000000, 0x00000000, @@ -4924,10 +4976,65 @@ const unsigned int cvbs_acd_table[TVIN_SIG_FMT_CVBS_SECAM - 0x90000fff, }, /* TVIN_SIG_FMT_CVBS_SECAM, */ + { + 0x10101002, 0x0, 0x7f00e110, 0x08881e18, 0xb36d1858, + 0x00007612, 0x00000000, 0x77444444, 0x20e000fe, 0x00000101, + 0x0c000100, 0x80010909, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x1010403c, 0x44060606, 0x08080044, 0x00080808, + 0xc006844b, 0x40200808, 0x44440044, 0x00008c80, 0xf0008888, + 0xa0461006, 0x70ff0404, 0x0400208c, 0x48484848, 0x00004444, + 0x00000000, 0x00000000, 0x00000000, 0x08000000, 0x02020000, + 0x0209c832, 0x00000000, 0xeafb4e8e, 0x2, 0xe7f14e8e, + 0x00140008, 0x20070000, 0x0036e946, 0x00001001, 0x10e0474f, + 0x00880358, 0x00130103, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000050, 0x00000000, 0x000003ff, 0x00000000, + 0x00000000, 0x00000000, 0x0004cfb0, 0x00000000, 0x030000f0, + 0x0000000a, 0x0000164e, 0x0003d55e, 0x000000f0, 0x00000001, + 0x00000400, 0x7f00e110, 0x08881e18, 0xb36d1858, 0x00007612, + 0x00000000, 0x77444444, 0x20e000fe, 0x00000101, 0x0c000100, + 0x80010909, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x50502070, 0x401020, + 0xd9801c0c, 0x21f00ff, 0x8080801c, 0x81f11111, 0x81f85852, + 0x00680068, 0x0487101c, 0x00000003, 0x00000000, 0x00012002, + 0x00028040, 0x00000000, 0x08000000, 0x7f1ff000, 0x00000000, + 0x10101040, 0x40404040, 0x80000f5c, 0xff000000, 0x00000000, + 0x00000000, 0x00ffffff, 0x00000fff, 0x80000000, 0x00000000, + 0x00000000, 0xa00833da, 0xba5b0391, 0x000ae232, 0x00000000, + 0xf0080610, 0x3000180a, 0x9c10, 0x00000182, 0x00000000, + 0x81000002, 0x83020010, 0x000121ff, 0x000c0340, 0x40305c1c, + 0x00d63650, 0x00c184af, 0x00c1837f, 0x00c18329, 0x01000100, + 0x43062222, 0x75777577, 0x00000000, 0x00000718, 0x9968edd6, + 0x3553fab0, 0x026f2865, 0x00018018, 0x00040010, 0x00000000, + 0x00000000, 0x002468b5, 0x002fa63a, 0x0143a740, 0x00032864, + 0x00001b10, 0x0371d249, 0x0003ebde, 0x00032864, 0x00001b10, + 0x0371d249, 0x0003ebde, 0X00032864, 0x00001b10, 0x0371d249, + 0x0003ebde, 0x00032864, 0x00001b10, 0x0371d249, 0x0003ebde, + 0x3f000100, 0x0fff0000, 0x3f000100, 0x0fff0000, 0x00000000, + 0x00000000, 0x00000000, 0x90000fff, 0x3f000100, 0x0fff0000, + 0x3f000100, 0x0fff0000, 0x00000000, 0x90000fff, 0x00000000, + 0x90000fff, 0x3f000100, 0x0fff0000, 0x3f000100, 0x0fff0000, + 0x00000000, 0x90000fff, 0x00000000, 0x90000fff, 0x3f000100, + 0x0fff0000, 0x3f000100, 0x0fff0000, 0x00000000, 0x90000fff, + 0x00000000, 0x90000fff, 0x00c1837e, 0x01000100, 0x43062222, + 0x75777577, 0x00000000, 0x00192718, 0x9968edd6, 0x3553fab0, + 0x026f2865, 0x00018018, 0x00040010, 0x00000000, 0x00000000, + 0x00247e04, 0x002fa52a, 0x0143a2ef, 0x000327bf, 0x00001b03, + 0x0371b470, 0x0003f28b, 0x000327bf, 0x00001b03, 0x0371b470, + 0x0003f28b, 0x000327bf, 0x00001b03, 0x0371b470, 0x0003f28b, + 0x000327bf, 0x00001b03, 0x0371b470, 0x00000003, 0x3f000100, + 0x0fff0000, 0x3f000100, 0x0fff0000, 0x00000000, 0x90000fff, + 0x00000000, 0x90000fff, 0x3f000100, 0x0fff0000, 0x3f000100, + 0x0fff0000, 0x00000000, 0x90000fff, 0x00000000, 0x90000fff, + 0x3f000100, 0x0fff0000, 0x0f000100, 0x0fff0000, 0x00000000, + 0x90000fff, 0x00000000, 0x90000fff, 0x3f000100, 0x0fff0000, + 0x3f000100, 0x0fff0000, 0x00000000, 0x90000fff, 0x00000000, + 0x90000fff, + + }, /* TVIN_SIG_FMT_CVBS_NTSC_50, */ }; EXPORT_SYMBOL(cvbs_acd_table); -const unsigned int rf_acd_table[TVIN_SIG_FMT_CVBS_SECAM - +const unsigned int rf_acd_table[TVIN_SIG_FMT_CVBS_NTSC_50 - TVIN_SIG_FMT_CVBS_NTSC_M+1][ACD_REG_NUM+1] = { { 0x10101002, 0x0, 0x7f00e110, 0x08881e18, 0xb36d1858, @@ -5221,7 +5328,7 @@ const unsigned int rf_acd_table[TVIN_SIG_FMT_CVBS_SECAM - 0x00000000, 0x66666442, 0x20e00044, 0x00000101, 0x00000000, 0x80010101, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x08205040, 0x0050c0c0, - 0x00000000, 0x020f00ff, 0x80808020, 0x81f11111, 0x81f24742, + 0xc9000418, 0x020f00ff, 0x80808020, 0x81f11111, 0x81f24742, 0x80200020, 0x03000000, 0x00000003, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x10000000, 0x7f1ff000, 0x00000000, 0x40404040, 0x40404040, 0x00000000, 0xff000000, 0x00000000, @@ -5312,11 +5419,65 @@ const unsigned int rf_acd_table[TVIN_SIG_FMT_CVBS_SECAM - 0x3f000100, 0x0fff0000, 0x00000000, 0x90000fff, 0x00000000, 0x90000fff, }, /* TVIN_SIG_FMT_CVBS_SECAM, */ + { + 0x10101002, 0x0, 0x7f00e110, 0x08881e18, 0xb36d1858, + 0x00007612, 0x00000000, 0x77444444, 0x20e000fe, 0x00000101, + 0x0c000100, 0x80010909, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x1010403c, 0x44060606, 0x08080044, 0x00080808, + 0xc006844b, 0x40200808, 0x44440044, 0x00008c80, 0xf0008888, + 0xa0461006, 0x70ff0404, 0x0400208c, 0x48484848, 0x00004444, + 0x00000000, 0x00000000, 0x00000000, 0x08000000, 0x02020000, + 0x0209c832, 0x00000000, 0xeafb4e8e, 0x2, 0xe7f14e8e, + 0x00140008, 0x20070000, 0x0036e946, 0x00001001, 0x10e0474f, + 0x00880358, 0x00130103, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000050, 0x00000000, 0x000003ff, 0x00000000, + 0x00000000, 0x00000000, 0x0004cfb0, 0x00000000, 0x030000f0, + 0x0000000a, 0x0000164e, 0x0003d55e, 0x000000f0, 0x00000001, + 0x00000400, 0x7f00e110, 0x08881e18, 0xb36d1858, 0x00007612, + 0x00000000, 0x77444444, 0x20e000fe, 0x00000101, 0x0c000100, + 0x80010909, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x50502070, 0x401020, + 0xd9801c0c, 0x21f00ff, 0x8080801c, 0x81f11111, 0x81f85852, + 0x00680068, 0x0487101c, 0x00000003, 0x00000000, 0x00012002, + 0x00028040, 0x00000000, 0x08000000, 0x7f1ff000, 0x00000000, + 0x10101040, 0x40404040, 0x80000f5c, 0xff000000, 0x00000000, + 0x00000000, 0x00ffffff, 0x00000fff, 0x80000000, 0x00000000, + 0x00000000, 0xa00833da, 0xba5b0391, 0x000ae232, 0x00000000, + 0xf0080610, 0x3000180a, 0x9c10, 0x00000182, 0x00000000, + 0x81000002, 0x83020010, 0x000121ff, 0x000c0340, 0x40305c1c, + 0x00d63650, 0x00c184af, 0x00c1837f, 0x00c18329, 0x01000100, + 0x43062222, 0x75777577, 0x00000000, 0x00000718, 0x9968edd6, + 0x3553fab0, 0x026f2865, 0x00018018, 0x00040010, 0x00000000, + 0x00000000, 0x002468b5, 0x002fa63a, 0x0143a740, 0x00032864, + 0x00001b10, 0x0371d249, 0x0003ebde, 0x00032864, 0x00001b10, + 0x0371d249, 0x0003ebde, 0X00032864, 0x00001b10, 0x0371d249, + 0x0003ebde, 0x00032864, 0x00001b10, 0x0371d249, 0x0003ebde, + 0x3f000100, 0x0fff0000, 0x3f000100, 0x0fff0000, 0x00000000, + 0x00000000, 0x00000000, 0x90000fff, 0x3f000100, 0x0fff0000, + 0x3f000100, 0x0fff0000, 0x00000000, 0x90000fff, 0x00000000, + 0x90000fff, 0x3f000100, 0x0fff0000, 0x3f000100, 0x0fff0000, + 0x00000000, 0x90000fff, 0x00000000, 0x90000fff, 0x3f000100, + 0x0fff0000, 0x3f000100, 0x0fff0000, 0x00000000, 0x90000fff, + 0x00000000, 0x90000fff, 0x00c1837e, 0x01000100, 0x43062222, + 0x75777577, 0x00000000, 0x00192718, 0x9968edd6, 0x3553fab0, + 0x026f2865, 0x00018018, 0x00040010, 0x00000000, 0x00000000, + 0x00247e04, 0x002fa52a, 0x0143a2ef, 0x000327bf, 0x00001b03, + 0x0371b470, 0x0003f28b, 0x000327bf, 0x00001b03, 0x0371b470, + 0x0003f28b, 0x000327bf, 0x00001b03, 0x0371b470, 0x0003f28b, + 0x000327bf, 0x00001b03, 0x0371b470, 0x00000003, 0x3f000100, + 0x0fff0000, 0x3f000100, 0x0fff0000, 0x00000000, 0x90000fff, + 0x00000000, 0x90000fff, 0x3f000100, 0x0fff0000, 0x3f000100, + 0x0fff0000, 0x00000000, 0x90000fff, 0x00000000, 0x90000fff, + 0x3f000100, 0x0fff0000, 0x0f000100, 0x0fff0000, 0x00000000, + 0x90000fff, 0x00000000, 0x90000fff, 0x3f000100, 0x0fff0000, + 0x3f000100, 0x0fff0000, 0x00000000, 0x90000fff, 0x00000000, + 0x90000fff + }, /* TVIN_SIG_FMT_CVBS_NTSC_50, */ }; EXPORT_SYMBOL(rf_acd_table); /* 0x00-0x03 */ -const unsigned char cvd_yc_reg_0x00_0x03[TVIN_SIG_FMT_CVBS_SECAM - +const unsigned char cvd_yc_reg_0x00_0x03[TVIN_SIG_FMT_CVBS_NTSC_50 - TVIN_SIG_FMT_CVBS_NTSC_M + 1][4] = { { 0x01, 0x08, 0x42, 0x22, @@ -5339,11 +5500,14 @@ const unsigned char cvd_yc_reg_0x00_0x03[TVIN_SIG_FMT_CVBS_SECAM - { 0x00, 0x08, 0x42, 0x22, }, /* TVIN_SIG_FMT_CVBS_SECAM, */ + { + 0x01, 0x08, 0x42, 0x22, + }, /* TVIN_SIG_FMT_CVBS_NTSC_50, */ }; EXPORT_SYMBOL(cvd_yc_reg_0x00_0x03); /* 0x18-0x1f */ -const unsigned char cvd_yc_reg_0x18_0x1f[TVIN_SIG_FMT_CVBS_SECAM - +const unsigned char cvd_yc_reg_0x18_0x1f[TVIN_SIG_FMT_CVBS_NTSC_50 - TVIN_SIG_FMT_CVBS_NTSC_M + 1][8] = { { 0x21, 0xf0, 0x7c, 0x1f, 0x24, 0x00, 0x00, 0x00, @@ -5366,6 +5530,9 @@ const unsigned char cvd_yc_reg_0x18_0x1f[TVIN_SIG_FMT_CVBS_SECAM - { 0x28, 0xa3, 0x3b, 0xb2, 0x24, 0x00, 0x00, 0x00, }, /* TVIN_SIG_FMT_CVBS_SECAM, */ + { + 0x21, 0xf0, 0x7c, 0x1f, 0x24, 0x00, 0x00, 0x00, + }, /* TVIN_SIG_FMT_CVBS_NTSC_50, */ }; EXPORT_SYMBOL(cvd_yc_reg_0x18_0x1f); diff --git a/drivers/amlogic/media/vin/tvin/tvin_format_table.h b/drivers/amlogic/media/vin/tvin/tvin_format_table.h index 5b4ddd2e343b..764b9d5cb1ae 100644 --- a/drivers/amlogic/media/vin/tvin/tvin_format_table.h +++ b/drivers/amlogic/media/vin/tvin/tvin_format_table.h @@ -40,22 +40,22 @@ extern const unsigned char adc_vga_table[TVIN_SIG_FMT_VGA_MAX - extern const unsigned char adc_component_table[TVIN_SIG_FMT_COMP_MAX - TVIN_SIG_FMT_COMP_480P_60HZ_D000][ADC_REG_NUM]; extern const unsigned char adc_cvbs_table[ADC_REG_NUM]; -extern const unsigned char cvd_part1_table[TVIN_SIG_FMT_CVBS_SECAM - +extern const unsigned char cvd_part1_table[TVIN_SIG_FMT_CVBS_NTSC_50 - TVIN_SIG_FMT_CVBS_NTSC_M + 1][CVD_PART1_REG_NUM]; -extern const unsigned char cvd_part2_table[TVIN_SIG_FMT_CVBS_SECAM - +extern const unsigned char cvd_part2_table[TVIN_SIG_FMT_CVBS_NTSC_50 - TVIN_SIG_FMT_CVBS_NTSC_M + 1][CVD_PART2_REG_NUM]; /* 0x87, 0x93, 0x94, 0x95, 0x96, 0xe6, 0xfa */ -extern const unsigned int cvd_part3_table[TVIN_SIG_FMT_CVBS_SECAM - +extern const unsigned int cvd_part3_table[TVIN_SIG_FMT_CVBS_NTSC_50 - TVIN_SIG_FMT_CVBS_NTSC_M + 1][CVD_PART3_REG_NUM]; -extern const unsigned int cvbs_acd_table[TVIN_SIG_FMT_CVBS_SECAM - +extern const unsigned int cvbs_acd_table[TVIN_SIG_FMT_CVBS_NTSC_50 - TVIN_SIG_FMT_CVBS_NTSC_M + 1][ACD_REG_NUM+1]; -extern const unsigned int rf_acd_table[TVIN_SIG_FMT_CVBS_SECAM - +extern const unsigned int rf_acd_table[TVIN_SIG_FMT_CVBS_NTSC_50 - TVIN_SIG_FMT_CVBS_NTSC_M + 1][ACD_REG_NUM+1]; -extern const unsigned char cvd_yc_reg_0x00_0x03[TVIN_SIG_FMT_CVBS_SECAM - +extern const unsigned char cvd_yc_reg_0x00_0x03[TVIN_SIG_FMT_CVBS_NTSC_50 - TVIN_SIG_FMT_CVBS_NTSC_M + 1][4]; -extern const unsigned char cvd_yc_reg_0x18_0x1f[TVIN_SIG_FMT_CVBS_SECAM - +extern const unsigned char cvd_yc_reg_0x18_0x1f[TVIN_SIG_FMT_CVBS_NTSC_50 - TVIN_SIG_FMT_CVBS_NTSC_M + 1][8]; diff --git a/drivers/amlogic/media/vin/tvin/tvin_frontend.c b/drivers/amlogic/media/vin/tvin/tvin_frontend.c index 40c99f31ebcc..09cd93b9543f 100644 --- a/drivers/amlogic/media/vin/tvin/tvin_frontend.c +++ b/drivers/amlogic/media/vin/tvin/tvin_frontend.c @@ -54,7 +54,6 @@ int tvin_reg_frontend(struct tvin_frontend_s *fe) { ulong flags; struct tvin_frontend_s *f, *t; - if (!strlen(fe->name) || !fe->dec_ops || !fe->dec_ops->support || !fe->sm_ops) return -1; @@ -138,7 +137,6 @@ static ssize_t frontend_name_show(struct class *cls, { size_t len = 0; struct tvin_frontend_s *f = NULL; - list_for_each_entry(f, &head, list) { len += sprintf(buf+len, "%s\n", f->name); } @@ -149,7 +147,6 @@ static CLASS_ATTR(frontend_names, 0444, frontend_name_show, NULL); static int __init tvin_common_init(void) { int ret = 0; - tvcom_clsp = class_create(THIS_MODULE, CLASS_NAME); if (!tvcom_clsp) { pr_err("[tvin_com..]%s: create tvin common class error.\n", diff --git a/drivers/amlogic/media/vin/tvin/tvin_global.h b/drivers/amlogic/media/vin/tvin/tvin_global.h index 3ea8c72a1ef2..a52a52693ea9 100644 --- a/drivers/amlogic/media/vin/tvin/tvin_global.h +++ b/drivers/amlogic/media/vin/tvin/tvin_global.h @@ -27,14 +27,20 @@ #ifdef TVBUS_REG_ADDR #define R_APB_REG(reg) aml_read_reg32(TVBUS_REG_ADDR(reg)) #define W_APB_REG(reg, val) aml_write_reg32(TVBUS_REG_ADDR(reg), val) +#define R_VBI_APB_REG(reg) aml_read_reg32(TVBUS_REG_ADDR(reg)) +#define W_VBI_APB_REG(reg, val) aml_write_reg32(TVBUS_REG_ADDR(reg), val) #define R_APB_BIT(reg, start, len) \ aml_get_reg32_bits(TVBUS_REG_ADDR(reg), start, len) #define W_APB_BIT(reg, val, start, len) \ aml_set_reg32_bits(TVBUS_REG_ADDR(reg), val, start, len) +#define W_VBI_APB_BIT(reg, val, start, len) \ + aml_set_reg32_bits(TVBUS_REG_ADDR(reg), val, start, len) #else #if 1 extern int tvafe_reg_read(unsigned int reg, unsigned int *val); extern int tvafe_reg_write(unsigned int reg, unsigned int val); +extern int tvafe_vbi_reg_read(unsigned int reg, unsigned int *val); +extern int tvafe_vbi_reg_write(unsigned int reg, unsigned int val); extern int tvafe_hiu_reg_read(unsigned int reg, unsigned int *val); extern int tvafe_hiu_reg_write(unsigned int reg, unsigned int val); #else @@ -55,7 +61,6 @@ static int tvafe_reg_write(unsigned int reg, unsigned int val) static inline uint32_t R_APB_REG(uint32_t reg) { unsigned int val; - tvafe_reg_read(reg, &val); return val; } @@ -66,6 +71,30 @@ static inline void W_APB_REG(uint32_t reg, tvafe_reg_write(reg, val); } +static inline uint32_t R_VBI_APB_REG(uint32_t reg) +{ + unsigned int val = 0; + + tvafe_vbi_reg_read(reg, &val); + return val; +} + +static inline void W_VBI_APB_REG(uint32_t reg, + const uint32_t val) +{ + tvafe_vbi_reg_write(reg, val); +} + +static inline void W_VBI_APB_BIT(uint32_t reg, + const uint32_t value, + const uint32_t start, + const uint32_t len) +{ + W_VBI_APB_REG(reg, ((R_VBI_APB_REG(reg) & + ~(((1L << (len)) - 1) << (start))) | + (((value) & ((1L << (len)) - 1)) << (start)))); +} + static inline void W_APB_BIT(uint32_t reg, const uint32_t value, const uint32_t start, @@ -112,7 +141,6 @@ static inline uint32_t R_VCBUS_BIT(uint32_t reg, static inline uint32_t R_HIU_REG(uint32_t reg) { unsigned int val; - tvafe_hiu_reg_read(reg, &val); return val; } @@ -145,13 +173,13 @@ static inline uint32_t R_HIU_BIT(uint32_t reg, } /* - *#define R_APB_REG(reg) READ_APB_REG(reg) - *#define W_APB_REG(reg, val) WRITE_APB_REG(reg, val) - *#define R_APB_BIT(reg, start, len) \ - * READ_APB_REG_BITS(reg, start, len) - *#define W_APB_BIT(reg, val, start, len) \ - * WRITE_APB_REG_BITS(reg, val, start, len) - */ +#define R_APB_REG(reg) READ_APB_REG(reg) +#define W_APB_REG(reg, val) WRITE_APB_REG(reg, val) +#define R_APB_BIT(reg, start, len) \ + READ_APB_REG_BITS(reg, start, len) +#define W_APB_BIT(reg, val, start, len) \ + WRITE_APB_REG_BITS(reg, val, start, len) +*/ #endif @@ -404,11 +432,18 @@ struct tvin_sig_property_s { unsigned int he; /* for horizontal end cut window */ unsigned int vs; /* for vertical start cut window */ unsigned int ve; /* for vertical end cut window */ + unsigned int pre_vs; /* for vertical start cut window */ + unsigned int pre_ve; /* for vertical end cut window */ + unsigned int pre_hs; /* for horizontal start cut window */ + unsigned int pre_he; /* for horizontal end cut window */ unsigned int decimation_ratio; /* for decimation */ unsigned int colordepth; /* for color bit depth */ unsigned int vdin_hdr_Flag; enum tvin_color_fmt_range_e color_fmt_range; struct tvin_hdr_info_s hdr_info; + bool dolby_vision;/*is signal dolby version*/ + uint8_t fps; + unsigned int skip_vf_num;/*skip pre vframe num*/ }; #define TVAFE_VF_POOL_SIZE 6 /* 8 */ diff --git a/drivers/amlogic/media/vin/tvin/vdin/vdin_canvas.c b/drivers/amlogic/media/vin/tvin/vdin/vdin_canvas.c index 5b7580edcd95..392a1ce1a309 100644 --- a/drivers/amlogic/media/vin/tvin/vdin/vdin_canvas.c +++ b/drivers/amlogic/media/vin/tvin/vdin/vdin_canvas.c @@ -18,6 +18,10 @@ /* Standard Linux headers */ #include #include +#include +#include +#include +#include /* Amlogic headers */ #include @@ -26,16 +30,34 @@ #include "../tvin_format_table.h" #include "vdin_drv.h" #include "vdin_canvas.h" +#include "vdin_ctl.h" +/*the value depending on dts config mem limit + *for skip two vframe case,need +2 + */ +static unsigned int max_buf_num = VDIN_CANVAS_MAX_CNT; +static unsigned int min_buf_num = 4; +static unsigned int max_buf_width = VDIN_CANVAS_MAX_WIDTH_HD; +static unsigned int max_buf_height = VDIN_CANVAS_MAX_HEIGH; +/* one frame max metadata size:32x280 bits = 1120bytes(0x460) */ +unsigned int dolby_size_byte = PAGE_SIZE; -#ifndef VDIN_DEBUG -#undef pr_info -#define pr_info(fmt, ...) -#endif - -unsigned int max_buf_num = 4; +#ifdef DEBUG_SUPPORT module_param(max_buf_num, uint, 0664); MODULE_PARM_DESC(max_buf_num, "vdin max buf num.\n"); +module_param(min_buf_num, uint, 0664); +MODULE_PARM_DESC(min_buf_num, "vdin min buf num.\n"); + +module_param(max_buf_width, uint, 0664); +MODULE_PARM_DESC(max_buf_width, "vdin max buf width.\n"); + +module_param(max_buf_height, uint, 0664); +MODULE_PARM_DESC(max_buf_height, "vdin max buf height.\n"); + +module_param(dolby_size_byte, uint, 0664); +MODULE_PARM_DESC(dolby_size_byte, "dolby_size_byte.\n"); +#endif + const unsigned int vdin_canvas_ids[2][VDIN_CANVAS_MAX_CNT] = { { 38, 39, 40, 41, 42, @@ -47,6 +69,11 @@ const unsigned int vdin_canvas_ids[2][VDIN_CANVAS_MAX_CNT] = { }, }; +/*function: + * 1.set canvas_max_w & canvas_max_h + * 2.set canvas_max_size & canvas_max_num + * 3.set canvas_id & canvas_addr + */ void vdin_canvas_init(struct vdin_dev_s *devp) { int i, canvas_id; @@ -63,7 +90,7 @@ void vdin_canvas_init(struct vdin_dev_s *devp) devp->canvas_max_num = VDIN_CANVAS_MAX_CNT; devp->mem_start = roundup(devp->mem_start, 32); - pr_info("vdin.%d cnavas initial table:\n", devp->index); + pr_info("vdin.%d canvas initial table:\n", devp->index); for (i = 0; i < devp->canvas_max_num; i++) { canvas_id = vdin_canvas_ids[devp->index][i]; canvas_addr = devp->mem_start + devp->canvas_max_size * i; @@ -79,84 +106,16 @@ void vdin_canvas_init(struct vdin_dev_s *devp) } } -void vdin_canvas_start_config(struct vdin_dev_s *devp) -{ - int i, canvas_id; - unsigned long canvas_addr; - unsigned int canvas_max_w = 0; - unsigned int canvas_max_h = VDIN_CANVAS_MAX_HEIGH; - unsigned int canvas_num = VDIN_CANVAS_MAX_CNT; - unsigned int chroma_size = 0; - unsigned int canvas_step = 1; - - canvas_max_w = VDIN_CANVAS_MAX_WIDTH_HD << 1; - - if ((devp->format_convert == VDIN_FORMAT_CONVERT_YUV_YUV444) || - (devp->format_convert == VDIN_FORMAT_CONVERT_YUV_RGB) || - (devp->format_convert == VDIN_FORMAT_CONVERT_RGB_YUV444) || - (devp->format_convert == VDIN_FORMAT_CONVERT_RGB_RGB)) { - devp->canvas_w = devp->h_active * 3; - } else if ((devp->prop.dest_cfmt == TVIN_NV12) || - (devp->prop.dest_cfmt == TVIN_NV21)) { - canvas_max_w = VDIN_CANVAS_MAX_WIDTH_HD; - canvas_max_h = VDIN_CANVAS_MAX_HEIGH; - canvas_num >>= 1; - canvas_step = 2; - devp->canvas_w = devp->h_active; - } else{ - devp->canvas_w = devp->h_active * 2; - } - if (devp->source_bitdepth > 8) - devp->canvas_w = devp->canvas_w * 3 / 2; -#if 0 - const struct tvin_format_s *fmt_info = - tvin_get_fmt_info(devp->parm.info.fmt); - if (fmt_info->scan_mode == TVIN_SCAN_MODE_INTERLACED) - devp->canvas_h = devp->v_active * 2; - else - devp->canvas_h = devp->v_active; -#else - devp->canvas_h = devp->v_active; -#endif - if ((devp->prop.dest_cfmt == TVIN_NV12) || - (devp->prop.dest_cfmt == TVIN_NV21)) - chroma_size = canvas_max_w*canvas_max_h/2; - devp->canvas_max_size = - PAGE_ALIGN((canvas_max_w*canvas_max_h+chroma_size)); - devp->canvas_max_num = devp->mem_size / devp->canvas_max_size; - devp->canvas_max_num = min(devp->canvas_max_num, canvas_num); - devp->canvas_max_num = min(devp->canvas_max_num, max_buf_num); - devp->canvas_w = roundup(devp->canvas_w, 32); - devp->mem_start = roundup(devp->mem_start, 32); - pr_info("vdin.%d cnavas configuration table:\n", devp->index); - for (i = 0; i < devp->canvas_max_num; i++) { - canvas_id = vdin_canvas_ids[devp->index][i*canvas_step]; - /* canvas_addr = canvas_get_addr(canvas_id); */ - /*reinitlize the canvas*/ - canvas_addr = devp->mem_start + devp->canvas_max_size * i; - canvas_config(canvas_id, canvas_addr, devp->canvas_w, - devp->canvas_h, - CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_LINEAR); - if (chroma_size) - canvas_config(canvas_id+1, - canvas_addr+devp->canvas_w*devp->canvas_h, - devp->canvas_w, devp->canvas_h/2, - CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_LINEAR); - pr_info("\t0x%2x: 0x%lx-0x%lx %ux%u\n", - canvas_id, canvas_addr, - canvas_addr + devp->canvas_max_size, - devp->canvas_w, devp->canvas_h); - } -} -/* - *this function used for configure canvas base on the input format - *also used for input resalution over 1080p such as camera input 200M,500M - *YUV422-8BIT:1pixel = 2byte; - *YUV422-10BIT:1pixel = 3byte; - *YUV444-8BIT:1pixel = 3byte; - *YUV444-10BIT:1pixel = 4bypte +/*function:canvas_config when canvas_config_mode=1 + * 1.set canvas_w and canvas_h + * 2.set canvas_max_size and canvas_max_num + * 3.when dest_cfmt is TVIN_NV12/TVIN_NV21, + * buf width add canvas_w*canvas_h + *based on parameters: + * format_convert/ source_bitdepth/ + * v_active color_depth_mode/ prop.dest_cfmt */ -void vdin_canvas_auto_config(struct vdin_dev_s *devp) +void vdin_canvas_start_config(struct vdin_dev_s *devp) { int i = 0; int canvas_id; @@ -164,36 +123,47 @@ void vdin_canvas_auto_config(struct vdin_dev_s *devp) unsigned int chroma_size = 0; unsigned int canvas_step = 1; unsigned int canvas_num = VDIN_CANVAS_MAX_CNT; + unsigned int max_buffer_num = max_buf_num; + /* todo: if new add output YUV444 format,this place should add too!!*/ if ((devp->format_convert == VDIN_FORMAT_CONVERT_YUV_YUV444) || (devp->format_convert == VDIN_FORMAT_CONVERT_YUV_RGB) || (devp->format_convert == VDIN_FORMAT_CONVERT_RGB_YUV444) || - (devp->format_convert == VDIN_FORMAT_CONVERT_RGB_RGB)) { - if (devp->source_bitdepth > 8) - devp->canvas_w = devp->h_active * 4; + (devp->format_convert == VDIN_FORMAT_CONVERT_RGB_RGB) || + (devp->format_convert == VDIN_FORMAT_CONVERT_YUV_GBR) || + + (devp->format_convert == VDIN_FORMAT_CONVERT_YUV_BRG) || + (devp->force_yuv444_malloc == 1)) { + if (devp->source_bitdepth > VDIN_MIN_SOURCE_BITDEPTH) + devp->canvas_w = max_buf_width * + VDIN_YUV444_10BIT_PER_PIXEL_BYTE; else - devp->canvas_w = devp->h_active * 3; - } else if (((devp->prop.dest_cfmt == TVIN_NV12) || - (devp->prop.dest_cfmt == TVIN_NV21)) && - (devp->source_bitdepth <= 8)) { - devp->canvas_w = devp->h_active; + devp->canvas_w = max_buf_height * + VDIN_YUV444_8BIT_PER_PIXEL_BYTE; + } else if ((devp->prop.dest_cfmt == TVIN_NV12) || + (devp->prop.dest_cfmt == TVIN_NV21)) { + devp->canvas_w = max_buf_width; canvas_num = canvas_num/2; canvas_step = 2; } else{/*YUV422*/ - /* txl new add yuv422 pack mode:canvas-w=h*2*10/8*/ - if ((devp->source_bitdepth > 8) && + /* txl new add yuv422 pack mode:canvas_w=h*2*10/8*/ + if ((devp->source_bitdepth > VDIN_MIN_SOURCE_BITDEPTH) && ((devp->format_convert == VDIN_FORMAT_CONVERT_YUV_YUV422) || (devp->format_convert == VDIN_FORMAT_CONVERT_RGB_YUV422) || (devp->format_convert == VDIN_FORMAT_CONVERT_GBR_YUV422) || (devp->format_convert == VDIN_FORMAT_CONVERT_BRG_YUV422)) && (devp->color_depth_mode == 1)) - devp->canvas_w = (devp->h_active * 5)/2; - else if ((devp->source_bitdepth > 8) && + devp->canvas_w = (max_buf_width * 5)/2; + else if ((devp->source_bitdepth > VDIN_MIN_SOURCE_BITDEPTH) && (devp->color_depth_mode == 0)) - devp->canvas_w = devp->h_active * 3; + devp->canvas_w = max_buf_width * + VDIN_YUV422_10BIT_PER_PIXEL_BYTE; else - devp->canvas_w = devp->h_active * 2; + devp->canvas_w = max_buf_width * + VDIN_YUV422_8BIT_PER_PIXEL_BYTE; } + /*backup before roundup*/ + devp->canvas_active_w = devp->canvas_w; /*canvas_w must ensure divided exact by 256bit(32byte)*/ devp->canvas_w = roundup(devp->canvas_w, 32); devp->canvas_h = devp->v_active; @@ -207,30 +177,448 @@ void vdin_canvas_auto_config(struct vdin_dev_s *devp) devp->canvas_max_num = devp->mem_size / devp->canvas_max_size; devp->canvas_max_num = min(devp->canvas_max_num, canvas_num); - devp->canvas_max_num = min(devp->canvas_max_num, max_buf_num); + devp->canvas_max_num = min(devp->canvas_max_num, max_buffer_num); - devp->mem_start = roundup(devp->mem_start, 32); + if ((devp->cma_config_en != 1) || !(devp->cma_config_flag & 0x100)) { + /*use_reserved_mem or alloc_from_contiguous*/ + devp->mem_start = roundup(devp->mem_start, 32); #ifdef VDIN_DEBUG - pr_info("vdin%d cnavas auto configuration table:\n", devp->index); + pr_info("vdin%d cnavas start configuration table:\n", + devp->index); #endif - for (i = 0; i < devp->canvas_max_num; i++) { - canvas_id = vdin_canvas_ids[devp->index][i*canvas_step]; - canvas_addr = devp->mem_start + devp->canvas_max_size * i; - canvas_config(canvas_id, canvas_addr, - devp->canvas_w, devp->canvas_h, - CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_LINEAR); - if (chroma_size) - canvas_config(canvas_id+1, - canvas_addr+devp->canvas_w*devp->canvas_h, - devp->canvas_w, - devp->canvas_h/2, + for (i = 0; i < devp->canvas_max_num; i++) { + canvas_id = vdin_canvas_ids[devp->index][i*canvas_step]; + canvas_addr = devp->mem_start + + devp->canvas_max_size * i; + canvas_config(canvas_id, canvas_addr, + devp->canvas_w, devp->canvas_h, CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_LINEAR); + if (chroma_size) + canvas_config(canvas_id+1, + canvas_addr + + devp->canvas_w*devp->canvas_h, + devp->canvas_w, + devp->canvas_h/2, + CANVAS_ADDR_NOWRAP, + CANVAS_BLKMODE_LINEAR); #ifdef VDIN_DEBUG - pr_info("\t%3d: 0x%lx-0x%lx %ux%u\n", - canvas_id, canvas_addr, - canvas_addr + devp->canvas_max_size, - devp->canvas_w, devp->canvas_h); + pr_info("\t%3d: 0x%lx-0x%lx %ux%u\n", + canvas_id, canvas_addr, + canvas_addr + devp->canvas_max_size, + devp->canvas_w, devp->canvas_h); #endif + } + } else if (devp->cma_config_flag & 0x100) { +#ifdef VDIN_DEBUG + pr_info("vdin%d cnavas start configuration table:\n", + devp->index); +#endif + for (i = 0; i < devp->canvas_max_num; i++) { + devp->vfmem_start[i] = + roundup(devp->vfmem_start[i], 32); + canvas_id = vdin_canvas_ids[devp->index][i*canvas_step]; + canvas_addr = devp->vfmem_start[i]; + canvas_config(canvas_id, canvas_addr, + devp->canvas_w, devp->canvas_h, + CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_LINEAR); + if (chroma_size) + canvas_config(canvas_id+1, + canvas_addr + + devp->canvas_w*devp->canvas_h, + devp->canvas_w, + devp->canvas_h/2, + CANVAS_ADDR_NOWRAP, + CANVAS_BLKMODE_LINEAR); +#ifdef VDIN_DEBUG + pr_info("\t%3d: 0x%lx-0x%lx %ux%u\n", + canvas_id, canvas_addr, + canvas_addr + devp->canvas_max_size, + devp->canvas_w, devp->canvas_h); +#endif + } } } +/* +*this function used for configure canvas when canvas_config_mode=2 +*base on the input format +*also used for input resalution over 1080p such as camera input 200M,500M +*YUV422-8BIT:1pixel = 2byte; +*YUV422-10BIT:1pixel = 3byte; +*YUV422-10BIT-FULLPACK:1pixel = 2.5byte; +*YUV444-8BIT:1pixel = 3byte; +*YUV444-10BIT:1pixel = 4byte +*/ +void vdin_canvas_auto_config(struct vdin_dev_s *devp) +{ + int i = 0; + int canvas_id; + unsigned long canvas_addr; + unsigned int chroma_size = 0; + unsigned int canvas_step = 1; + unsigned int canvas_num = VDIN_CANVAS_MAX_CNT; + unsigned int max_buffer_num = max_buf_num; + + /* todo: if new add output YUV444 format,this place should add too!!*/ + if ((devp->format_convert == VDIN_FORMAT_CONVERT_YUV_YUV444) || + (devp->format_convert == VDIN_FORMAT_CONVERT_YUV_RGB) || + (devp->format_convert == VDIN_FORMAT_CONVERT_RGB_YUV444) || + (devp->format_convert == VDIN_FORMAT_CONVERT_RGB_RGB) || + (devp->format_convert == VDIN_FORMAT_CONVERT_YUV_GBR) || + + (devp->format_convert == VDIN_FORMAT_CONVERT_YUV_BRG) || + (devp->force_yuv444_malloc == 1)) { + if (devp->source_bitdepth > VDIN_MIN_SOURCE_BITDEPTH) + devp->canvas_w = devp->h_active * + VDIN_YUV444_10BIT_PER_PIXEL_BYTE; + else + devp->canvas_w = devp->h_active * + VDIN_YUV444_8BIT_PER_PIXEL_BYTE; + } else if ((devp->prop.dest_cfmt == TVIN_NV12) || + (devp->prop.dest_cfmt == TVIN_NV21)) { + canvas_num = canvas_num/2; + canvas_step = 2; + devp->canvas_w = devp->h_active; + /* nv21/nv12 only have 8bit mode */ + } else {/*YUV422*/ + /* txl new add yuv422 pack mode:canvas-w=h*2*10/8*/ + if ((devp->source_bitdepth > VDIN_MIN_SOURCE_BITDEPTH) && + ((devp->format_convert == VDIN_FORMAT_CONVERT_YUV_YUV422) || + (devp->format_convert == VDIN_FORMAT_CONVERT_RGB_YUV422) || + (devp->format_convert == VDIN_FORMAT_CONVERT_GBR_YUV422) || + (devp->format_convert == VDIN_FORMAT_CONVERT_BRG_YUV422)) && + (devp->color_depth_mode == 1)) + devp->canvas_w = (devp->h_active * 5)/2; + else if ((devp->source_bitdepth > VDIN_MIN_SOURCE_BITDEPTH) && + (devp->color_depth_mode == 0)) + devp->canvas_w = devp->h_active * + VDIN_YUV422_10BIT_PER_PIXEL_BYTE; + else + devp->canvas_w = devp->h_active * + VDIN_YUV422_8BIT_PER_PIXEL_BYTE; + } + /*backup before roundup*/ + devp->canvas_active_w = devp->canvas_w; + /*canvas_w must ensure divided exact by 256bit(32byte)*/ + devp->canvas_w = roundup(devp->canvas_w, 32); + devp->canvas_h = devp->v_active; + + if ((devp->prop.dest_cfmt == TVIN_NV12) || + (devp->prop.dest_cfmt == TVIN_NV21)) + chroma_size = devp->canvas_w*devp->canvas_h/2; + + devp->canvas_max_size = PAGE_ALIGN(devp->canvas_w* + devp->canvas_h+chroma_size); + devp->canvas_max_num = devp->mem_size / devp->canvas_max_size; + + devp->canvas_max_num = min(devp->canvas_max_num, canvas_num); + devp->canvas_max_num = min(devp->canvas_max_num, max_buffer_num); + if ((devp->cma_config_en != 1) || !(devp->cma_config_flag & 0x100)) { + /*use_reserved_mem or alloc_from_contiguous*/ + devp->mem_start = roundup(devp->mem_start, 32); +#ifdef VDIN_DEBUG + pr_info("vdin%d cnavas auto configuration table:\n", + devp->index); +#endif + for (i = 0; i < devp->canvas_max_num; i++) { + canvas_id = vdin_canvas_ids[devp->index][i*canvas_step]; + canvas_addr = devp->mem_start + + devp->canvas_max_size * i; + canvas_config(canvas_id, canvas_addr, + devp->canvas_w, devp->canvas_h, + CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_LINEAR); + if (chroma_size) + canvas_config(canvas_id+1, + canvas_addr + + devp->canvas_w*devp->canvas_h, + devp->canvas_w, + devp->canvas_h/2, + CANVAS_ADDR_NOWRAP, + CANVAS_BLKMODE_LINEAR); +#ifdef VDIN_DEBUG + pr_info("\t%3d: 0x%lx-0x%lx %ux%u\n", + canvas_id, canvas_addr, + canvas_addr + devp->canvas_max_size, + devp->canvas_w, devp->canvas_h); +#endif + } + } else if (devp->cma_config_flag & 0x100) { +#ifdef VDIN_DEBUG + pr_info("vdin%d cnavas auto configuration table:\n", + devp->index); +#endif + for (i = 0; i < devp->canvas_max_num; i++) { + devp->vfmem_start[i] = + roundup(devp->vfmem_start[i], 32); + canvas_id = vdin_canvas_ids[devp->index][i*canvas_step]; + canvas_addr = devp->vfmem_start[i]; + canvas_config(canvas_id, canvas_addr, + devp->canvas_w, devp->canvas_h, + CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_LINEAR); + if (chroma_size) + canvas_config(canvas_id+1, + canvas_addr + + devp->canvas_w*devp->canvas_h, + devp->canvas_w, + devp->canvas_h/2, + CANVAS_ADDR_NOWRAP, + CANVAS_BLKMODE_LINEAR); +#ifdef VDIN_DEBUG + pr_info("\t%3d: 0x%lx-0x%lx %ux%u\n", + canvas_id, canvas_addr, + canvas_addr + devp->canvas_max_size, + devp->canvas_w, devp->canvas_h); +#endif + } + } +} + +#ifdef CONFIG_CMA +/* return val:1: fail;0: ok */ +unsigned int vdin_cma_alloc(struct vdin_dev_s *devp) +{ + char vdin_name[6]; + unsigned int mem_size, h_size, v_size; + int flags = CODEC_MM_FLAGS_CMA_FIRST|CODEC_MM_FLAGS_CMA_CLEAR| + CODEC_MM_FLAGS_CPU; + unsigned int max_buffer_num = min_buf_num; + unsigned int i; + + if (devp->rdma_enable && (devp->game_mode == 0)) + max_buffer_num++; + /*todo: need update if vf_skip_cnt used by other port*/ + if (devp->vfp->skip_vf_num && + (((devp->parm.port >= TVIN_PORT_HDMI0) && + (devp->parm.port <= TVIN_PORT_HDMI7)) || + ((devp->parm.port >= TVIN_PORT_CVBS0) && + (devp->parm.port <= TVIN_PORT_CVBS7)))) + max_buffer_num += devp->vfp->skip_vf_num; + if (max_buffer_num > max_buf_num) + max_buffer_num = max_buf_num; + devp->vfmem_max_cnt = max_buffer_num; + + if ((devp->cma_config_en == 0) || + (devp->cma_mem_alloc == 1)) { + pr_info("\nvdin%d %s use_reserved mem or cma already alloced (%d,%d)!!!\n", + devp->index, __func__, devp->cma_config_en, + devp->cma_mem_alloc); + return 0; + } + h_size = devp->h_active; + v_size = devp->v_active; + if (devp->canvas_config_mode == 1) { + h_size = max_buf_width; + v_size = max_buf_height; + } + if ((devp->format_convert == VDIN_FORMAT_CONVERT_YUV_YUV444) || + (devp->format_convert == VDIN_FORMAT_CONVERT_YUV_RGB) || + (devp->format_convert == VDIN_FORMAT_CONVERT_RGB_YUV444) || + (devp->format_convert == VDIN_FORMAT_CONVERT_RGB_RGB) || + (devp->format_convert == VDIN_FORMAT_CONVERT_YUV_GBR) || + (devp->format_convert == VDIN_FORMAT_CONVERT_YUV_BRG) || + (devp->force_yuv444_malloc == 1)) { + if (devp->source_bitdepth > VDIN_MIN_SOURCE_BITDEPTH) { + h_size = roundup(h_size * + VDIN_YUV444_10BIT_PER_PIXEL_BYTE, 32); + devp->canvas_alin_w = h_size / + VDIN_YUV444_10BIT_PER_PIXEL_BYTE; + } else { + h_size = roundup(h_size * + VDIN_YUV444_8BIT_PER_PIXEL_BYTE, 32); + devp->canvas_alin_w = h_size / + VDIN_YUV444_8BIT_PER_PIXEL_BYTE; + } + } else if ((devp->format_convert == VDIN_FORMAT_CONVERT_YUV_NV12) || + (devp->format_convert == VDIN_FORMAT_CONVERT_YUV_NV21) || + (devp->format_convert == VDIN_FORMAT_CONVERT_RGB_NV12) || + (devp->format_convert == VDIN_FORMAT_CONVERT_RGB_NV21)) { + h_size = roundup(h_size, 32); + devp->canvas_alin_w = h_size; + /*todo change with canvas alloc!!*/ + /* nv21/nv12 only have 8bit mode */ + } else { + /* txl new add mode yuv422 pack mode:canvas-w=h*2*10/8 + *canvas_w must ensure divided exact by 256bit(32byte + */ + if ((devp->source_bitdepth > VDIN_MIN_SOURCE_BITDEPTH) && + ((devp->format_convert == VDIN_FORMAT_CONVERT_YUV_YUV422) || + (devp->format_convert == VDIN_FORMAT_CONVERT_RGB_YUV422) || + (devp->format_convert == VDIN_FORMAT_CONVERT_GBR_YUV422) || + (devp->format_convert == VDIN_FORMAT_CONVERT_BRG_YUV422)) && + (devp->color_depth_mode == 1)) { + h_size = roundup((h_size * 5)/2, 32); + devp->canvas_alin_w = (h_size * 2) / 5; + } else if ((devp->source_bitdepth > VDIN_MIN_SOURCE_BITDEPTH) && + (devp->color_depth_mode == 0)) { + h_size = roundup(h_size * + VDIN_YUV422_10BIT_PER_PIXEL_BYTE, 32); + devp->canvas_alin_w = h_size / + VDIN_YUV422_10BIT_PER_PIXEL_BYTE; + } else { + h_size = roundup(h_size * + VDIN_YUV422_8BIT_PER_PIXEL_BYTE, 32); + devp->canvas_alin_w = h_size / + VDIN_YUV422_8BIT_PER_PIXEL_BYTE; + } + } + mem_size = h_size * v_size; + if ((devp->format_convert >= VDIN_FORMAT_CONVERT_YUV_NV12) && + (devp->format_convert <= VDIN_FORMAT_CONVERT_RGB_NV21)) + mem_size = (mem_size * 3)/2; + devp->vfmem_size = PAGE_ALIGN(mem_size) + dolby_size_byte; + devp->vfmem_size = (devp->vfmem_size/PAGE_SIZE + 1)*PAGE_SIZE; + + mem_size = PAGE_ALIGN(mem_size) * max_buffer_num + + dolby_size_byte * max_buffer_num; + mem_size = (mem_size/PAGE_SIZE + 1)*PAGE_SIZE; + if (mem_size > devp->cma_mem_size) + mem_size = devp->cma_mem_size; + if (devp->index == 0) + strcpy(vdin_name, "vdin0"); + else if (devp->index == 1) + strcpy(vdin_name, "vdin1"); + + if (devp->cma_config_flag == 0x101) { + for (i = 0; i < max_buffer_num; i++) { + devp->vfmem_start[i] = codec_mm_alloc_for_dma(vdin_name, + devp->vfmem_size/PAGE_SIZE, 0, flags); + if (devp->vfmem_start[i] == 0) { + pr_err("\nvdin%d buf[%d]codec alloc fail!!!\n", + devp->index, i); + devp->cma_mem_alloc = 0; + return 1; + } + devp->cma_mem_alloc = 1; + pr_info("vdin%d buf[%d] mem_start = 0x%lx, mem_size = 0x%x\n", + devp->index, i, + devp->vfmem_start[i], devp->vfmem_size); + } + pr_info("vdin%d codec cma alloc ok!\n", devp->index); + devp->mem_size = mem_size; + } else if (devp->cma_config_flag == 0x1) { + devp->mem_start = codec_mm_alloc_for_dma(vdin_name, + mem_size/PAGE_SIZE, 0, flags); + devp->mem_size = mem_size; + if (devp->mem_start == 0) { + pr_err("\nvdin%d codec alloc fail!!!\n", + devp->index); + devp->cma_mem_alloc = 0; + return 1; + } + devp->cma_mem_alloc = 1; + pr_info("vdin%d mem_start = 0x%lx, mem_size = 0x%x\n", + devp->index, devp->mem_start, devp->mem_size); + pr_info("vdin%d codec cma alloc ok!\n", devp->index); + } else if (devp->cma_config_flag == 0x100) { + for (i = 0; i < max_buffer_num; i++) { + devp->vfvenc_pages[i] = dma_alloc_from_contiguous( + &(devp->this_pdev->dev), + devp->vfmem_size >> PAGE_SHIFT, 0); + if (devp->vfvenc_pages[i]) { + devp->vfmem_start[i] = + page_to_phys(devp->vfvenc_pages[i]); + pr_info("vdin%d buf[%d]mem_start = 0x%lx, mem_size = 0x%x\n", + devp->index, i, + devp->vfmem_start[i], devp->vfmem_size); + } else { + devp->cma_mem_alloc = 0; + pr_err("\nvdin%d cma mem undefined2.\n", + devp->index); + return 1; + } + } + devp->cma_mem_alloc = 1; + devp->mem_size = mem_size; + pr_info("vdin%d cma alloc ok!\n", devp->index); + } else { + devp->venc_pages = dma_alloc_from_contiguous( + &(devp->this_pdev->dev), + devp->cma_mem_size >> PAGE_SHIFT, 0); + if (devp->venc_pages) { + devp->mem_start = + page_to_phys(devp->venc_pages); + devp->mem_size = mem_size; + devp->cma_mem_alloc = 1; + pr_info("vdin%d mem_start = 0x%lx, mem_size = 0x%x\n", + devp->index, devp->mem_start, devp->mem_size); + pr_info("vdin%d cma alloc ok!\n", devp->index); + } else { + devp->cma_mem_alloc = 0; + pr_err("\nvdin%d cma mem undefined2.\n", + devp->index); + return 1; + } + } + return 0; +} + +/*this function used for codec cma release + * 1.call codec_mm_free_for_dma() or + * dma_release_from_contiguous() to relase cma; + * 2.reset mem_start & mem_size & cma_mem_alloc to 0; + */ +void vdin_cma_release(struct vdin_dev_s *devp) +{ + char vdin_name[6]; + unsigned int i; + + if ((devp->cma_config_en == 0) || + (devp->cma_mem_alloc == 0)) { + pr_err("\nvdin%d %s fail for (%d,%d)!!!\n", + devp->index, __func__, devp->cma_config_en, + devp->cma_mem_alloc); + return; + } + if (devp->index == 0) + strcpy(vdin_name, "vdin0"); + else if (devp->index == 1) + strcpy(vdin_name, "vdin1"); + + if (devp->cma_config_flag == 0x101) { + for (i = 0; i < devp->vfmem_max_cnt; i++) + codec_mm_free_for_dma(vdin_name, devp->vfmem_start[i]); + pr_info("vdin%d codec cma release ok!\n", devp->index); + } else if (devp->cma_config_flag == 0x1) { + codec_mm_free_for_dma(vdin_name, devp->mem_start); + pr_info("vdin%d codec cma release ok!\n", devp->index); + } else if (devp->cma_config_flag == 0x100) { + for (i = 0; i < devp->vfmem_max_cnt; i++) + dma_release_from_contiguous( + &(devp->this_pdev->dev), + devp->vfvenc_pages[i], + devp->vfmem_size >> PAGE_SHIFT); + pr_info("vdin%d cma release ok!\n", devp->index); + } else if (devp->venc_pages + && devp->cma_mem_size + && (devp->cma_config_flag == 0)) { + dma_release_from_contiguous( + &(devp->this_pdev->dev), + devp->venc_pages, + devp->cma_mem_size >> PAGE_SHIFT); + pr_info("vdin%d cma release ok!\n", devp->index); + } else { + pr_err("\nvdin%d %s fail for (%d,0x%x,0x%lx)!!!\n", + devp->index, __func__, devp->cma_mem_size, + devp->cma_config_flag, devp->mem_start); + } + devp->mem_start = 0; + devp->mem_size = 0; + devp->cma_mem_alloc = 0; +} +/*@20170823 new add for the case of csc change after signal stable*/ +void vdin_cma_malloc_mode(struct vdin_dev_s *devp) +{ + unsigned int h_size, v_size; + + h_size = devp->h_active; + v_size = devp->v_active; + if ((h_size <= VDIN_YUV444_MAX_CMA_WIDTH) && + (v_size <= VDIN_YUV444_MAX_CMA_HEIGH) && + (devp->cma_mem_mode == 1)) + devp->force_yuv444_malloc = 1; + else + devp->force_yuv444_malloc = 0; + +} +#endif + diff --git a/drivers/amlogic/media/vin/tvin/vdin/vdin_canvas.h b/drivers/amlogic/media/vin/tvin/vdin/vdin_canvas.h index 559162a9db0a..66aababd2c2e 100644 --- a/drivers/amlogic/media/vin/tvin/vdin/vdin_canvas.h +++ b/drivers/amlogic/media/vin/tvin/vdin/vdin_canvas.h @@ -19,22 +19,27 @@ #define __VDIN_CANVAS_H #include - -#include #include #define VDIN_CANVAS_MAX_WIDTH_UHD 4096 #define VDIN_CANVAS_MAX_WIDTH_HD 1920 - #define VDIN_CANVAS_MAX_HEIGH 2228 +#define VDIN_YUV422_8BIT_PER_PIXEL_BYTE 2 +#define VDIN_YUV422_10BIT_PER_PIXEL_BYTE 3 +#define VDIN_YUV444_10BIT_PER_PIXEL_BYTE 4 +#define VDIN_YUV444_8BIT_PER_PIXEL_BYTE 3 +#define VDIN_MIN_SOURCE_BITDEPTH 8 -#define VDIN_CANVAS_MAX_CNT 9 + +#define VDIN_YUV444_MAX_CMA_WIDTH 1920 +#define VDIN_YUV444_MAX_CMA_HEIGH 1080 extern const unsigned int vdin_canvas_ids[2][VDIN_CANVAS_MAX_CNT]; extern void vdin_canvas_init(struct vdin_dev_s *devp); extern void vdin_canvas_start_config(struct vdin_dev_s *devp); - extern void vdin_canvas_auto_config(struct vdin_dev_s *devp); - +extern unsigned int vdin_cma_alloc(struct vdin_dev_s *devp); +extern void vdin_cma_release(struct vdin_dev_s *devp); +extern void vdin_cma_malloc_mode(struct vdin_dev_s *devp); #endif /* __VDIN_CANVAS_H */ diff --git a/drivers/amlogic/media/vin/tvin/vdin/vdin_ctl.c b/drivers/amlogic/media/vin/tvin/vdin/vdin_ctl.c index c4be691b9e58..74ac19a1fe35 100644 --- a/drivers/amlogic/media/vin/tvin/vdin/vdin_ctl.c +++ b/drivers/amlogic/media/vin/tvin/vdin/vdin_ctl.c @@ -16,13 +16,12 @@ */ #include -/* #include */ -/* #include */ -/* #include */ -/* #include */ +#include #include -/* #include */ +#include #include +#include +#include #include "../tvin_global.h" #include "../tvin_format_table.h" #include "vdin_ctl.h" @@ -30,89 +29,64 @@ #include "vdin_drv.h" #include "vdin_vf.h" #include "vdin_canvas.h" -/* #include "../../../../common/drivers/amlogic/amports/ve_regs.h" */ - -/* #define VDIN_MEAS_24M_1MS 24000 */ -/* #define VDIN_MEAS_51M_1MS 50000 */ +#define VDIN_VSHRINK_HLIMIT 1280 #define TVIN_MAX_PIXCLK 20000 - -static short max_hactive = 4096; -module_param(max_hactive, short, 0664); -MODULE_PARM_DESC(max_hactive, "the max hactive of vdin"); - -/* - * protection for vga vertical de adjustment,if vertical blanking too short - * mybe too short to process one field data +#define META_RETRY_MAX 10 +#define VDIN_MAX_HACTIVE 4096 /*the max hactive of vdin*/ +/*0: 1 word in 1burst, 1: 2 words in 1burst; + *2: 4 words in 1burst; */ -static short vbp_offset = 15; -module_param(vbp_offset, short, 0664); -MODULE_PARM_DESC(vbp_offset, "the mix lines after vsync"); +#define VDIN_WR_BURST_MODE 2 -/* black bar det enable/disable test */ -static bool black_bar_enable; -module_param(black_bar_enable, bool, 0664); -MODULE_PARM_DESC(black_bar_enable, "black bar enable/disable"); - -static bool hist_bar_enable; -module_param(hist_bar_enable, bool, 0664); -MODULE_PARM_DESC(hist_bar_enable, "hist bar enable/disable"); - -static int color_convert; -module_param(color_convert, int, 0664); -MODULE_PARM_DESC(color_convert, "color_convert"); - -static unsigned int max_undone_cnt = 60; -module_param(max_undone_cnt, uint, 0644); -MODULE_PARM_DESC(max_undone_cnt, "the max vdin undone cnt to reset vpp"); - -static unsigned int use_frame_rate; -module_param(use_frame_rate, uint, 0644); -MODULE_PARM_DESC(use_frame_rate, "use frame rate to cal duraton"); +#define DV_META_PACKET_SIZE 128 +#define DV_META_HEADER_LEN 2 +#define DV_META_TAIL_CRC_SIZE 4 +#define DV_META_PACKET_TYPE_SIZE 3 static bool cm_enable = 1; module_param(cm_enable, bool, 0644); MODULE_PARM_DESC(cm_enable, "cm_enable"); static bool rgb_info_enable; +static unsigned int rgb_info_x; +static unsigned int rgb_info_y; +static unsigned int rgb_info_r; +static unsigned int rgb_info_g; +static unsigned int rgb_info_b; +static int vdin_det_idle_wait = 100; +static unsigned int delay_line_num; +static bool invert_top_bot; + +#ifdef DEBUG_SUPPORT module_param(rgb_info_enable, bool, 0644); MODULE_PARM_DESC(rgb_info_enable, "rgb_info_enable"); -static unsigned int rgb_info_x; module_param(rgb_info_x, uint, 0644); MODULE_PARM_DESC(rgb_info_x, "rgb_info_x"); -static unsigned int rgb_info_y; module_param(rgb_info_y, uint, 0644); MODULE_PARM_DESC(rgb_info_y, "rgb_info_y"); -static unsigned int rgb_info_r; module_param(rgb_info_r, uint, 0644); MODULE_PARM_DESC(rgb_info_r, "rgb_info_r"); -static unsigned int rgb_info_g; module_param(rgb_info_g, uint, 0644); MODULE_PARM_DESC(rgb_info_g, "rgb_info_g"); -static unsigned int rgb_info_b; module_param(rgb_info_b, uint, 0644); MODULE_PARM_DESC(rgb_info_b, "rgb_info_b"); -static unsigned int vdin_ldim_max_en = 1; -module_param(vdin_ldim_max_en, uint, 0644); -MODULE_PARM_DESC(vdin_ldim_max_en, "vdin_ldim_max_en"); +module_param(vdin_det_idle_wait, int, 0664); +MODULE_PARM_DESC(vdin_det_idle_wait, "vdin_det_idle_wait"); -/*0: 1 word in 1burst, 1: 2 words in 1burst; - * 2: 4 words in 1burst; - */ -static unsigned int vdin_wr_burst_mode = 2; -module_param(vdin_wr_burst_mode, uint, 0644); -MODULE_PARM_DESC(vdin_wr_burst_mode, "vdin_wr_burst_mode"); - -static unsigned int delay_line_num; module_param(delay_line_num, uint, 0644); MODULE_PARM_DESC(delay_line_num, "delay_line_num"); +module_param(invert_top_bot, bool, 0644); +MODULE_PARM_DESC(invert_top_bot, "invert field type top or bottom"); +#endif + bool enable_reset; module_param(enable_reset, bool, 0664); MODULE_PARM_DESC(enable_reset, "enable_reset"); @@ -120,17 +94,19 @@ static int vsync_reset_mask; module_param(vsync_reset_mask, int, 0664); MODULE_PARM_DESC(vsync_reset_mask, "vsync_reset_mask"); -static int vdin_det_idle_wait = 100; -module_param(vdin_det_idle_wait, int, 0664); -MODULE_PARM_DESC(vdin_det_idle_wait, "vdin_det_idle_wait"); +static unsigned int dv_dbg_log; +module_param(dv_dbg_log, uint, 0664); +MODULE_PARM_DESC(dv_dbg_log, "enable/disable dv_dbg_log"); -int try_count; -int try_count_max = 3; -module_param(try_count_max, int, 0664); -MODULE_PARM_DESC(try_count_max, "try_count_max"); +unsigned int dv_dbg_mask = (DV_BUF_START_RESET | DV_CRC_CHECK); +module_param(dv_dbg_mask, uint, 0664); +MODULE_PARM_DESC(dv_dbg_mask, "enable/disable dv_dbg_mask"); +static int vdin_ctl_dbg; +module_param(vdin_ctl_dbg, int, 0664); +MODULE_PARM_DESC(vdin_ctl_dbg, "vdin_ctl_dbg"); -unsigned int vpu_reg_27af = 0x3; +static unsigned int vpu_reg_27af = 0x3; /***************************Local defines**********************************/ #define BBAR_BLOCK_THR_FACTOR 3 @@ -162,9 +138,14 @@ unsigned int vpu_reg_27af = 0x3; #define MEAS_MUX_DTV 6 #define MEAS_MUX_ISP 8 #define MEAS_MUX_656_B 9 - #define MEAS_MUX_VIU 6 +#define HDMI_DE_REPEAT_DONE_FLAG 0xF0 +#define DECIMATION_REAL_RANGE 0x0F +#define VDIN_PIXELCLK_4K_30HZ 248832000 +#define VDIN_PIXELCLK_4K_60HZ 497664000 + + /* check hcnt/vcnt after N*vs. */ #define VDIN_WAIT_VALID_VS 2 /* ignore n*vs which have wrong data. */ @@ -174,44 +155,50 @@ unsigned int vpu_reg_27af = 0x3; /* the diff value between normal/bad data */ #define VDIN_MEAS_VSCNT_DIFF 0x50 -#ifndef VDIN_DEBUG +#if 0/*ndef VDIN_DEBUG*/ #undef pr_info #define pr_info(fmt, ...) #endif +/*reset reg mif value of vdin0: + * VDIN_WR_CTRL \VDIN_COM_CTRL0\ VDIN_MISC_CTRL + */ static void vdin0_wr_mif_reset(void) { if (vsync_reset_mask & 0x08) { W_VCBUS_BIT(VDIN_WR_CTRL, 1, FRAME_SOFT_RST_EN_BIT, 1); - W_VCBUS_BIT(VDIN_COM_CTRL0, 1, 28, 1); + W_VCBUS_BIT(VDIN_COM_CTRL0, 1, VDIN_FORCEGOLINE_EN_BIT, 1); udelay(1); W_VCBUS_BIT(VDIN_WR_CTRL, 0, FRAME_SOFT_RST_EN_BIT, 1); } else { - W_VCBUS_BIT(VDIN_WR_CTRL, 0, 10, 1); + W_VCBUS_BIT(VDIN_WR_CTRL, 0, VDIN_WRCTRLREG_PAUSE_BIT, 1); W_VCBUS_BIT(VDIN_MISC_CTRL, 1, 2, 1); W_VCBUS_BIT(VDIN_MISC_CTRL, 1, VDIN0_MIF_RST_BIT, 1); udelay(1); W_VCBUS_BIT(VDIN_MISC_CTRL, 0, VDIN0_MIF_RST_BIT, 1); W_VCBUS_BIT(VDIN_MISC_CTRL, 0, 2, 1); - W_VCBUS_BIT(VDIN_WR_CTRL, 1, 8, 1); - W_VCBUS_BIT(VDIN_WR_CTRL, 1, 10, 1); + W_VCBUS_BIT(VDIN_WR_CTRL, 1, VDIN_WRREQUEST_EN_BT, 1); + W_VCBUS_BIT(VDIN_WR_CTRL, 1, VDIN_WRCTRLREG_PAUSE_BIT, 1); } }; +/*reset reg mif value of vdin1: + * VDIN_WR_CTRL \VDIN_COM_CTRL1\ VDIN_MISC_CTRL + */ static void vdin1_wr_mif_reset(void) { if (vsync_reset_mask & 0x08) { W_VCBUS_BIT(VDIN1_WR_CTRL, 1, FRAME_SOFT_RST_EN_BIT, 1); - W_VCBUS_BIT(VDIN_COM_CTRL1, 1, 28, 1); + W_VCBUS_BIT(VDIN_COM_CTRL1, 1, VDIN_FORCEGOLINE_EN_BIT, 1); udelay(1); W_VCBUS_BIT(VDIN1_WR_CTRL, 0, FRAME_SOFT_RST_EN_BIT, 1); } else { - W_VCBUS_BIT(VDIN1_WR_CTRL, 0, 10, 1); + W_VCBUS_BIT(VDIN1_WR_CTRL, 0, VDIN_WRCTRLREG_PAUSE_BIT, 1); W_VCBUS_BIT(VDIN_MISC_CTRL, 1, VDIN1_MIF_RST_BIT, 1); udelay(1); W_VCBUS_BIT(VDIN_MISC_CTRL, 0, VDIN1_MIF_RST_BIT, 1); - W_VCBUS_BIT(VDIN1_WR_CTRL, 1, 8, 1); - W_VCBUS_BIT(VDIN1_WR_CTRL, 1, 10, 1); + W_VCBUS_BIT(VDIN1_WR_CTRL, 1, VDIN_WRREQUEST_EN_BT, 1); + W_VCBUS_BIT(VDIN1_WR_CTRL, 1, VDIN_WRCTRLREG_PAUSE_BIT, 1); } } @@ -438,7 +425,11 @@ static struct vdin_matrix_lup_s vdin_matrix_lup[] = { }; /***************************Local function**********************************/ - +/*set format_convert + *base on parameters: + * a.color_format + * b.dest_cfmt + */ void vdin_get_format_convert(struct vdin_dev_s *devp) { enum vdin_format_convert_e format_convert; @@ -492,9 +483,16 @@ void vdin_get_format_convert(struct vdin_dev_s *devp) break; } } + if ((devp->dv.dolby_input & (1 << devp->index)) || + (devp->dv.dv_flag && is_dolby_vision_enable())) + format_convert = VDIN_FORMAT_CONVERT_YUV_YUV444; devp->format_convert = format_convert; } +/*functiong: + * format_convert + * based on dest_cfmt + */ enum vdin_format_convert_e vdin_get_format_convert_matrix0( struct vdin_dev_s *devp) { @@ -513,6 +511,10 @@ enum vdin_format_convert_e vdin_get_format_convert_matrix0( return format_convert; } +/*functiong: + * format_convert + * based on color_cfmt + */ enum vdin_format_convert_e vdin_get_format_convert_matrix1( struct vdin_dev_s *devp) { @@ -537,17 +539,36 @@ enum vdin_format_convert_e vdin_get_format_convert_matrix1( return format_convert; } +/*get prob of r/g/b + * r 9:0 + * g 19:10 + * b 29:20 + */ void vdin_get_prob_rgb(unsigned int offset, unsigned int *r, unsigned int *g, unsigned int *b) { - *b = rgb_info_b = ((rd_bits(offset, VDIN_MATRIX_PROBE_COLOR, 0, 10) - << 8) >> 10); - *g = rgb_info_g = ((rd_bits(offset, VDIN_MATRIX_PROBE_COLOR, 10, 10) - << 8) >> 10); - *r = rgb_info_r = ((rd_bits(offset, VDIN_MATRIX_PROBE_COLOR, 20, 10) - << 8) >> 10); + *b = rgb_info_b = rd_bits(offset, VDIN_MATRIX_PROBE_COLOR, + COMPONENT0_PROBE_COLOR_BIT, COMPONENT0_PROBE_COLOR_WID); + *g = rgb_info_g = rd_bits(offset, VDIN_MATRIX_PROBE_COLOR, + COMPONENT1_PROBE_COLOR_BIT, COMPONENT1_PROBE_COLOR_WID); + *r = rgb_info_r = rd_bits(offset, VDIN_MATRIX_PROBE_COLOR, + COMPONENT0_PROBE_COLOR_BIT, COMPONENT0_PROBE_COLOR_WID); } +/*function: + * 1.set meas mux based on port_: + * 0x01: /mpeg/ 0x10: /CVBS/ + * 0x02: /bt656/ 0x20: /SVIDEO/ + * 0x04: /VGA/ 0x40: /hdmi/ + * 0x08: /COMPONENT/ 0x80: /dvin/ + * 0xc0:/viu/ 0x100:/dtv mipi/ + * 0x200:/isp/ + * 2.set VDIN_MEAS in accumulation mode + * 3.set VPP_VDO_MEAS in accumulation mode + * 4.set VPP_MEAS in latch-on-falling-edge mode + * 5.set VDIN_MEAS mux + * 6.manual reset VDIN_MEAS & VPP_VDO_MEAS at the same time + */ static void vdin_set_meas_mux(unsigned int offset, enum tvin_port_e port_, enum bt_path_e bt_path) { @@ -558,11 +579,15 @@ static void vdin_set_meas_mux(unsigned int offset, enum tvin_port_e port_, case 0x01: /* mpeg */ meas_mux = MEAS_MUX_NULL; break; - case 0x02: /* 656 */ - if (is_meson_gxbb_cpu() && (bt_path == BT_PATH_GPIO_B)) - meas_mux = MEAS_MUX_656_B; - else + case 0x02: /* bt656 , txl and txlx do not support bt656 */ + if ((is_meson_gxbb_cpu() || is_meson_gxtvbb_cpu()) && + (bt_path == BT_PATH_GPIO_B)) + meas_mux = MEAS_MUX_656_B; + else if ((is_meson_gxl_cpu() || is_meson_gxm_cpu()) && + (bt_path == BT_PATH_GPIO)) meas_mux = MEAS_MUX_656; + else + pr_info("cpu not define or do not support bt656"); break; case 0x04: /* VGA */ meas_mux = MEAS_MUX_TVFE; @@ -614,8 +639,32 @@ static void vdin_set_meas_mux(unsigned int offset, enum tvin_port_e port_, W_VCBUS_BIT(VPP_VDO_MEAS_CTRL, 0, 10, 1); } +/*function:set VDIN_COM_CTRL0 + *Bit 3:0 vdin selection, + * 1: mpeg_in from dram, 2: bt656 input,3: component input + * 4: tvdecoder input, 5: hdmi rx input,6: digtial video input, + * 7: loopback from Viu1, 8: MIPI. + */ +/* Bit 7:6, component0 output switch, + * 00: select component0 in,01: select component1 in, + * 10: select component2 in + */ +/* Bit 9:8, component1 output switch, + * 00: select component0 in, + * 01: select component1 in, 10: select component2 in + */ +/* Bit 11:10, component2 output switch, + * 00: select component0 in, 01: select component1 in, + * 10: select component2 in + */ -static inline void vdin_set_top(unsigned int offset, +/*attention:new add for bt656 + *0x02: /bt656/ + a.BT_PATH_GPIO: gxl & gxm + b.BT_PATH_GPIO_B:gxtvbb & gxbb + c.txl and txlx don't support bt656 +*/ +void vdin_set_top(unsigned int offset, enum tvin_port_e port, enum tvin_color_fmt_e input_cfmt, unsigned int h, enum bt_path_e bt_path) @@ -635,16 +684,19 @@ static inline void vdin_set_top(unsigned int offset, wr_bits(offset, VDIN_ASFIFO_CTRL0, 0xe0, VDI1_ASFIFO_CTRL_BIT, VDI1_ASFIFO_CTRL_WID); break; - case 0x02: /* bt656 */ - if (is_meson_gxbb_cpu() && (bt_path == BT_PATH_GPIO_B)) { - vdin_mux = VDIN_MUX_656_B; - wr_bits(offset, VDIN_ASFIFO_CTRL3, 0xe4, + case 0x02: /* bt656 ,txl and txlx do not support bt656 */ + if ((is_meson_gxbb_cpu() || is_meson_gxtvbb_cpu()) && + (bt_path == BT_PATH_GPIO_B)) { + vdin_mux = VDIN_MUX_656_B; + wr_bits(offset, VDIN_ASFIFO_CTRL3, 0xe4, VDI9_ASFIFO_CTRL_BIT, VDI9_ASFIFO_CTRL_WID); - } else { - vdin_mux = VDIN_MUX_656; - wr_bits(offset, VDIN_ASFIFO_CTRL0, 0xe4, + } else if ((is_meson_gxm_cpu() || is_meson_gxl_cpu()) && + (bt_path == BT_PATH_GPIO)) { + vdin_mux = VDIN_MUX_656; + wr_bits(offset, VDIN_ASFIFO_CTRL0, 0xe4, VDI1_ASFIFO_CTRL_BIT, VDI1_ASFIFO_CTRL_WID); - } + } else + pr_info("cpu not define or do not support bt656"); break; case 0x04: /* VGA */ vdin_mux = VDIN_MUX_TVFE; @@ -733,13 +785,11 @@ static inline void vdin_set_top(unsigned int offset, COMP2_OUT_SWT_BIT, COMP2_OUT_SWT_WID); } -/* - * this function will set the bellow parameters of devp: - * 1.h_active - * 2.v_active +/*this function will set the bellow parameters of devp: + *1.h_active + *2.v_active */ -#define HDMI_DE_REPEAT_DONE_FLAG 0xF0 -#define DECIMATION_REAL_RANGE 0x0F + void vdin_set_decimation(struct vdin_dev_s *devp) { unsigned int offset = devp->addr_offset; @@ -748,15 +798,17 @@ void vdin_set_decimation(struct vdin_dev_s *devp) if (devp->prop.decimation_ratio & HDMI_DE_REPEAT_DONE_FLAG) { decimation_in_frontend = true; - pr_info("decimation_in_frontend\n"); + if (vdin_ctl_dbg) + pr_info("decimation_in_frontend\n"); } devp->prop.decimation_ratio = devp->prop.decimation_ratio & DECIMATION_REAL_RANGE; new_clk = devp->fmt_info_p->pixel_clk / (devp->prop.decimation_ratio + 1); - pr_info("%s decimation_ratio=%u,new_clk=%u.\n", - __func__, devp->prop.decimation_ratio, new_clk); + if (vdin_ctl_dbg) + pr_info("%s decimation_ratio=%u,new_clk=%u.\n", + __func__, devp->prop.decimation_ratio, new_clk); devp->h_active = devp->fmt_info_p->h_active / (devp->prop.decimation_ratio + 1); @@ -783,19 +835,26 @@ void vdin_set_decimation(struct vdin_dev_s *devp) /* output_width_m1 */ wr_bits(offset, VDIN_INTF_WIDTHM1, (devp->h_active - 1), VDIN_INTF_WIDTHM1_BIT, VDIN_INTF_WIDTHM1_WID); + return; } + void vdin_fix_nonstd_vsync(struct vdin_dev_s *devp) { unsigned int offset = devp->addr_offset; - - wr_bits(offset, VDIN_INTF_WIDTHM1, 3, 24, 2); + wr_bits(offset, VDIN_INTF_WIDTHM1, 3, + VDIN_FIX_NONSTDVSYNC_BIT, VDIN_FIX_NONSTDVSYNC_WID); } -/* - * this function will set the bellow parameters of devp: - * 1.h_active - * 2.v_active +/*this function will set the bellow parameters of devp: + * 1.h_active + * 2.v_active + * set VDIN_WIN_H_START_END + * Bit 28:16 input window H start + * Bit 12:0 input window H end + * set VDIN_WIN_V_START_END + * Bit 28:16 input window V start + * Bit 12:0 input window V start */ void vdin_set_cutwin(struct vdin_dev_s *devp) { @@ -820,13 +879,19 @@ void vdin_set_cutwin(struct vdin_dev_s *devp) (ve << INPUT_WIN_V_END_BIT)); wr_bits(offset, VDIN_COM_CTRL0, 1, INPUT_WIN_SEL_EN_BIT, INPUT_WIN_SEL_EN_WID); - pr_info("%s enable cutwin hs=%d, he=%d, vs=%d, ve=%d\n", - __func__, + if (vdin_ctl_dbg) + pr_info("%s enable cutwin hs=%d, he=%d, vs=%d, ve=%d\n", + __func__, devp->prop.hs, devp->prop.he, devp->prop.vs, devp->prop.ve); } else { - pr_info("%s disable cutwin!!! hs=%d, he=%d, vs=%d, ve=%d\n", - __func__, + wr(offset, VDIN_WIN_H_START_END, 0); + wr(offset, VDIN_WIN_V_START_END, 0); + wr_bits(offset, VDIN_COM_CTRL0, 0, + INPUT_WIN_SEL_EN_BIT, INPUT_WIN_SEL_EN_WID); + if (vdin_ctl_dbg) + pr_info("%s disable cutwin!!! hs=%d, he=%d, vs=%d, ve=%d\n", + __func__, devp->prop.hs, devp->prop.he, devp->prop.vs, devp->prop.ve); } @@ -837,18 +902,27 @@ void vdin_set_config(struct vdin_dev_s *devp) { if (is_meson_gxbb_cpu() || is_meson_gxm_cpu() || is_meson_gxl_cpu()) /* max pixel clk of vdin for gxbb/gxm/gxl */ - devp->vdin_max_pixelclk = 248832000; /* 2160p30hz*/ + devp->vdin_max_pixelclk = + VDIN_PIXELCLK_4K_30HZ; /* 2160p30hz*/ else - devp->vdin_max_pixelclk = 497664000; /* 2160p60hz*/ + devp->vdin_max_pixelclk = + VDIN_PIXELCLK_4K_60HZ; /* 2160p60hz*/ } - +/*set matrix_csc + * based on parameters: + * a.format_convert + * b.port + * c.color_range_mode + * d.vdin_hdr_flag + */ static inline void vdin_set_color_matrix1(unsigned int offset, struct tvin_format_s *tvin_fmt_p, enum vdin_format_convert_e format_convert, enum tvin_port_e port, enum tvin_color_fmt_range_e color_fmt_range, - unsigned int vdin_hdr_flag) + unsigned int vdin_hdr_flag, + unsigned int color_range_mode) { /* unsigned int offset = devp->addr_offset; */ enum vdin_matrix_csc_e matrix_csc = VDIN_MATRIX_NULL; @@ -864,17 +938,30 @@ static inline void vdin_set_color_matrix1(unsigned int offset, case VDIN_FORMAT_CONVERT_RGB_NV21: if ((port >= TVIN_PORT_HDMI0) && (port <= TVIN_PORT_HDMI7)) { - if (color_fmt_range == TVIN_RGB_FULL) { - matrix_csc = VDIN_MATRIX_RGB_YUV709F; - if (vdin_hdr_flag == 1) - matrix_csc = VDIN_MATRIX_RGB_YUV709; + if (color_range_mode == 1) { + if (color_fmt_range == TVIN_RGB_FULL) { + matrix_csc = VDIN_MATRIX_RGB_YUV709F; + if (vdin_hdr_flag == 1) + matrix_csc = + VDIN_MATRIX_RGB_YUV709; + } else { + matrix_csc = VDIN_MATRIX_RGBS_YUV709F; + if (vdin_hdr_flag == 1) + matrix_csc = + VDIN_MATRIX_RGBS_YUV709; + } } else { - matrix_csc = VDIN_MATRIX_RGBS_YUV709F; - if (vdin_hdr_flag == 1) + if (color_fmt_range == TVIN_RGB_FULL) + matrix_csc = VDIN_MATRIX_RGB_YUV709; + else matrix_csc = VDIN_MATRIX_RGBS_YUV709; } - } else - matrix_csc = VDIN_MATRIX_RGB_YUV709F; + } else { + if (color_range_mode == 1) + matrix_csc = VDIN_MATRIX_RGB_YUV709F; + else + matrix_csc = VDIN_MATRIX_RGB_YUV709; + } break; case VDIN_FORMAT_CONVERT_BRG_YUV422: matrix_csc = VDIN_MATRIX_BRG_YUV601; @@ -884,18 +971,31 @@ static inline void vdin_set_color_matrix1(unsigned int offset, break; case VDIN_FORMAT_CONVERT_RGB_YUV444: if ((port >= TVIN_PORT_HDMI0) && - (port <= TVIN_PORT_HDMI7)) { - if (color_fmt_range == TVIN_RGB_FULL) { - matrix_csc = VDIN_MATRIX_RGB_YUV709F; - if (vdin_hdr_flag == 1) - matrix_csc = VDIN_MATRIX_RGB_YUV709; + (port <= TVIN_PORT_HDMI7)) { + if (color_range_mode == 1) { + if (color_fmt_range == TVIN_RGB_FULL) { + matrix_csc = VDIN_MATRIX_RGB_YUV709F; + if (vdin_hdr_flag == 1) + matrix_csc = + VDIN_MATRIX_RGB_YUV709; + } else { + matrix_csc = VDIN_MATRIX_RGBS_YUV709F; + if (vdin_hdr_flag == 1) + matrix_csc = + VDIN_MATRIX_RGBS_YUV709; + } } else { - matrix_csc = VDIN_MATRIX_RGBS_YUV709F; - if (vdin_hdr_flag == 1) + if (color_fmt_range == TVIN_RGB_FULL) + matrix_csc = VDIN_MATRIX_RGB_YUV709; + else matrix_csc = VDIN_MATRIX_RGBS_YUV709; } - } else - matrix_csc = VDIN_MATRIX_RGB_YUV709F; + } else { + if (color_range_mode == 1) + matrix_csc = VDIN_MATRIX_RGB_YUV709F; + else + matrix_csc = VDIN_MATRIX_RGB_YUV709; + } break; case VDIN_FORMAT_CONVERT_YUV_RGB: if (((fmt_info->scan_mode == TVIN_SCAN_MODE_PROGRESSIVE) && @@ -936,17 +1036,28 @@ static inline void vdin_set_color_matrix1(unsigned int offset, ((fmt_info->scan_mode == TVIN_SCAN_MODE_INTERLACED) && (fmt_info->v_active >= 540)) /* 1080i & above */ ) { - if (color_fmt_range != TVIN_YUV_FULL) + if ((color_range_mode == 1) && + (color_fmt_range != TVIN_YUV_FULL)) matrix_csc = VDIN_MATRIX_YUV709_YUV709F; + else if ((color_range_mode == 0) && + (color_fmt_range == TVIN_YUV_FULL)) + matrix_csc = VDIN_MATRIX_YUV709F_YUV709; } else { - if (color_fmt_range == TVIN_YUV_FULL) - matrix_csc = VDIN_MATRIX_YUV601F_YUV709F; - else - matrix_csc = VDIN_MATRIX_YUV601_YUV709F; + if (color_range_mode == 1) { + if (color_fmt_range == TVIN_YUV_FULL) + matrix_csc = + VDIN_MATRIX_YUV601F_YUV709F; + else + matrix_csc = VDIN_MATRIX_YUV601_YUV709F; + } else { + if (color_fmt_range == TVIN_YUV_FULL) + matrix_csc = VDIN_MATRIX_YUV601F_YUV709; + else + matrix_csc = VDIN_MATRIX_YUV601_YUV709; + } } if (vdin_hdr_flag == 1) matrix_csc = VDIN_MATRIX_NULL; - break; default: matrix_csc = VDIN_MATRIX_NULL; @@ -989,7 +1100,8 @@ static inline void vdin_set_color_matrix0(unsigned int offset, enum vdin_format_convert_e format_convert, enum tvin_port_e port, enum tvin_color_fmt_range_e color_fmt_range, - unsigned int vdin_hdr_flag) + unsigned int vdin_hdr_flag, + unsigned int color_range_mode) { enum vdin_matrix_csc_e matrix_csc = VDIN_MATRIX_NULL; struct vdin_matrix_lup_s *matrix_tbl; @@ -1004,17 +1116,31 @@ static inline void vdin_set_color_matrix0(unsigned int offset, case VDIN_FORMAT_CONVERT_RGB_NV21: if ((port >= TVIN_PORT_HDMI0) && (port <= TVIN_PORT_HDMI7)) { - if (color_fmt_range == TVIN_RGB_FULL) { - matrix_csc = VDIN_MATRIX_RGB_YUV709F; - if (vdin_hdr_flag == 1) - matrix_csc = VDIN_MATRIX_RGB_YUV709; + if (color_range_mode == 1) { + if (color_fmt_range == TVIN_RGB_FULL) { + matrix_csc = VDIN_MATRIX_RGB_YUV709F; + if (vdin_hdr_flag == 1) + matrix_csc = + VDIN_MATRIX_RGB_YUV709; + } else { + matrix_csc = + VDIN_MATRIX_RGBS_YUV709F; + if (vdin_hdr_flag == 1) + matrix_csc = + VDIN_MATRIX_RGBS_YUV709; + } } else { - matrix_csc = VDIN_MATRIX_RGBS_YUV709F; - if (vdin_hdr_flag == 1) + if (color_fmt_range == TVIN_RGB_FULL) + matrix_csc = VDIN_MATRIX_RGB_YUV709; + else matrix_csc = VDIN_MATRIX_RGBS_YUV709; } - } else - matrix_csc = VDIN_MATRIX_RGB_YUV709F; + } else { + if (color_range_mode == 1) + matrix_csc = VDIN_MATRIX_RGB_YUV709F; + else + matrix_csc = VDIN_MATRIX_RGB_YUV709; + } break; case VDIN_FORMAT_CONVERT_GBR_YUV422: matrix_csc = VDIN_MATRIX_GBR_YUV601; @@ -1025,17 +1151,30 @@ static inline void vdin_set_color_matrix0(unsigned int offset, case VDIN_FORMAT_CONVERT_RGB_YUV444: if ((port >= TVIN_PORT_HDMI0) && (port <= TVIN_PORT_HDMI7)) { - if (color_fmt_range == TVIN_RGB_FULL) { - matrix_csc = VDIN_MATRIX_RGB_YUV709F; - if (vdin_hdr_flag == 1) - matrix_csc = VDIN_MATRIX_RGB_YUV709; + if (color_range_mode == 1) { + if (color_fmt_range == TVIN_RGB_FULL) { + matrix_csc = VDIN_MATRIX_RGB_YUV709F; + if (vdin_hdr_flag == 1) + matrix_csc = + VDIN_MATRIX_RGB_YUV709; + } else { + matrix_csc = VDIN_MATRIX_RGBS_YUV709F; + if (vdin_hdr_flag == 1) + matrix_csc = + VDIN_MATRIX_RGBS_YUV709; + } } else { - matrix_csc = VDIN_MATRIX_RGBS_YUV709F; - if (vdin_hdr_flag == 1) + if (color_fmt_range == TVIN_RGB_FULL) + matrix_csc = VDIN_MATRIX_RGB_YUV709; + else matrix_csc = VDIN_MATRIX_RGBS_YUV709; } - } else - matrix_csc = VDIN_MATRIX_RGB_YUV709F; + } else { + if (color_range_mode == 1) + matrix_csc = VDIN_MATRIX_RGB_YUV709F; + else + matrix_csc = VDIN_MATRIX_RGB_YUV709; + } break; case VDIN_FORMAT_CONVERT_YUV_RGB: if (((fmt_info->scan_mode == TVIN_SCAN_MODE_PROGRESSIVE) && @@ -1076,17 +1215,28 @@ static inline void vdin_set_color_matrix0(unsigned int offset, ((fmt_info->scan_mode == TVIN_SCAN_MODE_INTERLACED) && (fmt_info->v_active >= 540)) /* 1080i & above */ ) { - if (color_fmt_range != TVIN_YUV_FULL) + if ((color_range_mode == 1) && + (color_fmt_range != TVIN_YUV_FULL)) matrix_csc = VDIN_MATRIX_YUV709_YUV709F; + else if ((color_range_mode == 0) && + (color_fmt_range == TVIN_YUV_FULL)) + matrix_csc = VDIN_MATRIX_YUV709F_YUV709; } else { - if (color_fmt_range == TVIN_YUV_FULL) - matrix_csc = VDIN_MATRIX_YUV601F_YUV709F; - else - matrix_csc = VDIN_MATRIX_YUV601_YUV709F; + if (color_range_mode == 1) { + if (color_fmt_range == TVIN_YUV_FULL) + matrix_csc = + VDIN_MATRIX_YUV601F_YUV709F; + else + matrix_csc = VDIN_MATRIX_YUV601_YUV709F; + } else { + if (color_fmt_range == TVIN_YUV_FULL) + matrix_csc = VDIN_MATRIX_YUV601F_YUV709; + else + matrix_csc = VDIN_MATRIX_YUV601_YUV709; + } } if (vdin_hdr_flag == 1) matrix_csc = VDIN_MATRIX_NULL; - break; default: matrix_csc = VDIN_MATRIX_NULL; @@ -1120,6 +1270,11 @@ static inline void vdin_set_color_matrix0(unsigned int offset, VDIN_MATRIX_EN_BIT, VDIN_MATRIX_EN_WID); } } + +/*set matrix based on rgb_info_enable: + * 0:set matrix0, disable matrix1 + * 1:set matrix1, set matrix0 + */ void vdin_set_matrix(struct vdin_dev_s *devp) { enum vdin_format_convert_e format_convert_matrix0; @@ -1137,7 +1292,12 @@ void vdin_set_matrix(struct vdin_dev_s *devp) devp->format_convert, devp->parm.port, devp->prop.color_fmt_range, - devp->prop.vdin_hdr_Flag); + devp->prop.vdin_hdr_Flag, + devp->color_range_mode); + if ((devp->dv.dolby_input & (1 << devp->index)) || + (devp->dv.dv_flag && is_dolby_vision_enable())) + wr_bits(offset, VDIN_MATRIX_CTRL, 0, + VDIN_MATRIX_EN_BIT, VDIN_MATRIX_EN_WID); } else { format_convert_matrix0 = vdin_get_format_convert_matrix0(devp); format_convert_matrix1 = vdin_get_format_convert_matrix1(devp); @@ -1145,19 +1305,25 @@ void vdin_set_matrix(struct vdin_dev_s *devp) format_convert_matrix1, devp->parm.port, devp->prop.color_fmt_range, - devp->prop.vdin_hdr_Flag); + devp->prop.vdin_hdr_Flag, + devp->color_range_mode); vdin_set_color_matrix0(devp->addr_offset, devp->fmt_info_p, - devp->format_convert, + format_convert_matrix0, devp->parm.port, devp->prop.color_fmt_range, - devp->prop.vdin_hdr_Flag); + devp->prop.vdin_hdr_Flag, + devp->color_range_mode); /* set xy */ - wr_bits(offset, VDIN_MATRIX_PROBE_POS, rgb_info_y, 0, 13); - wr_bits(offset, VDIN_MATRIX_PROBE_POS, rgb_info_x, 16, 13); + wr_bits(offset, VDIN_MATRIX_PROBE_POS, rgb_info_y, + PROBE_POX_Y_BIT, PROBE_POX_Y_WID); + wr_bits(offset, VDIN_MATRIX_PROBE_POS, rgb_info_x, + PROBE_POS_X_BIT, PROBE_POS_X_WID); /* 1:probe pixel data after matrix */ - wr_bits(offset, VDIN_MATRIX_CTRL, 1, 6, 1); + wr_bits(offset, VDIN_MATRIX_CTRL, 1, + VDIN_PROBE_POST_BIT, VDIN_PROBE_POST_WID); /* 1:select matrix 1 */ - wr_bits(offset, VDIN_MATRIX_CTRL, 1, 4, 2); + wr_bits(offset, VDIN_MATRIX_CTRL, 1, + VDIN_PROBE_SEL_BIT, VDIN_PROBE_SEL_WID); } } @@ -1170,20 +1336,27 @@ void vdin_set_matrixs(struct vdin_dev_s *devp, unsigned char id, devp->fmt_info_p, csc, devp->parm.port, devp->prop.color_fmt_range, - devp->prop.vdin_hdr_Flag); + devp->prop.vdin_hdr_Flag, + devp->color_range_mode); break; case 1: vdin_set_color_matrix1(devp->addr_offset, devp->fmt_info_p, csc, devp->parm.port, devp->prop.color_fmt_range, - devp->prop.vdin_hdr_Flag); + devp->prop.vdin_hdr_Flag, + devp->color_range_mode); break; default: break; } } +/* this function set flowing parameters: + *a.rgb_info_x b.rgb_info_y + *debug usage: + *echo rgb_xy x y > /sys/class/vdin/vdinx/attr + */ void vdin_set_prob_xy(unsigned int offset, unsigned int x, unsigned int y, struct vdin_dev_s *devp) { @@ -1198,12 +1371,14 @@ void vdin_set_prob_xy(unsigned int offset, format_convert_matrix1, devp->parm.port, devp->prop.color_fmt_range, - devp->prop.vdin_hdr_Flag); + devp->prop.vdin_hdr_Flag, + devp->color_range_mode); vdin_set_color_matrix0(devp->addr_offset, devp->fmt_info_p, format_convert_matrix0, devp->parm.port, devp->prop.color_fmt_range, - devp->prop.vdin_hdr_Flag); + devp->prop.vdin_hdr_Flag, + devp->color_range_mode); /* set position */ rgb_info_x = x; if (devp->fmt_info_p->scan_mode == TVIN_SCAN_MODE_INTERLACED) @@ -1211,24 +1386,23 @@ void vdin_set_prob_xy(unsigned int offset, else rgb_info_y = y; /* #if defined(VDIN_V1) */ - wr_bits(offset, VDIN_MATRIX_PROBE_POS, rgb_info_y, 0, 13); - wr_bits(offset, VDIN_MATRIX_PROBE_POS, rgb_info_x, 16, 13); + wr_bits(offset, VDIN_MATRIX_PROBE_POS, rgb_info_y, + PROBE_POX_Y_BIT, PROBE_POX_Y_WID); + wr_bits(offset, VDIN_MATRIX_PROBE_POS, rgb_info_x, + PROBE_POS_X_BIT, PROBE_POS_X_WID); /* 1:probe pixel data after matrix */ - wr_bits(offset, VDIN_MATRIX_CTRL, 1, 6, 1); + wr_bits(offset, VDIN_MATRIX_CTRL, 1, + VDIN_PROBE_POST_BIT, VDIN_PROBE_POST_WID); /* 1:select matrix 1 */ - wr_bits(offset, VDIN_MATRIX_CTRL, 1, 4, 2); + wr_bits(offset, VDIN_MATRIX_CTRL, 1, + VDIN_PROBE_SEL_BIT, VDIN_PROBE_SEL_WID); /* #endif */ } -void vdin_set_matrix_blank(struct vdin_dev_s *devp) -{ - vdin_set_color_matrix0(devp->addr_offset, - devp->fmt_info_p, - VDIN_MATRIX_XXX_YUV_BLACK, - devp->parm.port, - devp->prop.color_fmt_range, - devp->prop.vdin_hdr_Flag); -} +/*set block bar + *base on flowing parameters: + *a.h_active b.v_active + */ static inline void vdin_set_bbar(unsigned int offset, unsigned int v, unsigned int h) { @@ -1271,6 +1445,10 @@ static inline void vdin_set_bbar(unsigned int offset, unsigned int v, BLKBAR_DET_SOFT_RST_N_BIT, BLKBAR_DET_SOFT_RST_N_WID); } + +/*set histogram window + * pow\h_start\h_end\v_start\v_end + */ static inline void vdin_set_histogram(unsigned int offset, unsigned int hs, unsigned int he, unsigned int vs, unsigned int ve) { @@ -1302,6 +1480,12 @@ static inline void vdin_set_histogram(unsigned int offset, unsigned int hs, } } +/*set hist mux + *VDIN_HIST_CTRL + * Bit 3:2 hist_din_sel the source used for hist statistics. + * 00: from matrix0 dout, 01: from vsc_dout, + * 10: from matrix1 dout, 11: form matrix1 din + */ static inline void vdin_set_hist_mux(struct vdin_dev_s *devp) { enum tvin_port_e port = TVIN_PORT_NULL; @@ -1314,14 +1498,54 @@ static inline void vdin_set_hist_mux(struct vdin_dev_s *devp) wr_bits(devp->addr_offset, VDIN_HIST_CTRL, 3, HIST_HIST_DIN_SEL_BIT, HIST_HIST_DIN_SEL_WID); } - -static inline void vdin_set_wr_ctrl(unsigned int offset, unsigned int v, - unsigned int h, enum vdin_format_convert_e format_convert, - unsigned int color_depth_mode, unsigned int source_bitdeth) +/* urgent ctr config */ +/*if vdin fifo over up_th,will trigger increase + * urgent responds to vdin write, + *if vdin fifo lower dn_th,will trigger decrease + * urgent responds to vdin write + */ +static void vdin_urgent_patch(unsigned int offset, unsigned int v, + unsigned int h) +{ + if ((h >= 1920) && (v >= 1080)) { + wr_bits(offset, VDIN_LFIFO_URG_CTRL, 1, + VDIN_LFIFO_URG_CTRL_EN_BIT, VDIN_LFIFO_URG_CTRL_EN_WID); + wr_bits(offset, VDIN_LFIFO_URG_CTRL, 1, + VDIN_LFIFO_URG_WR_EN_BIT, VDIN_LFIFO_URG_WR_EN_WID); + wr_bits(offset, VDIN_LFIFO_URG_CTRL, 20, + VDIN_LFIFO_URG_UP_TH_BIT, VDIN_LFIFO_URG_UP_TH_WID); + wr_bits(offset, VDIN_LFIFO_URG_CTRL, 8, + VDIN_LFIFO_URG_DN_TH_BIT, VDIN_LFIFO_URG_DN_TH_WID); + /*vlsi guys suggest setting:*/ + W_VCBUS_BIT(VPU_ARB_URG_CTRL, 1, + VDIN_LFF_URG_CTRL_BIT, VDIN_LFF_URG_CTRL_WID); + W_VCBUS_BIT(VPU_ARB_URG_CTRL, 1, + VPP_OFF_URG_CTRL_BIT, VPP_OFF_URG_CTRL_WID); + } else { + wr(offset, VDIN_LFIFO_URG_CTRL, 0); + aml_write_vcbus(VPU_ARB_URG_CTRL, 0); + } +} +void vdin_urgent_patch_resume(unsigned int offset) +{ + /* urgent ctr config */ + wr(offset, VDIN_LFIFO_URG_CTRL, 0); + aml_write_vcbus(VPU_ARB_URG_CTRL, 0); +} +/*set write ctrl regs: + *VDIN_WR_H_START_END + *VDIN_WR_V_START_END + *VDIN_WR_CTRL + *VDIN_LFIFO_URG_CTRL + */ +static inline void vdin_set_wr_ctrl(struct vdin_dev_s *devp, + unsigned int offset, unsigned int v, + unsigned int h, enum vdin_format_convert_e format_convert, + unsigned int color_depth_mode, unsigned int source_bitdeth) { unsigned int write_format444 = 0, swap_cbcr = 0; /* unsigned int def_canvas_id = offset? - * vdin_canvas_ids[1][0]:vdin_canvas_ids[0][0]; + * vdin_canvas_ids[1][0]:vdin_canvas_ids[0][0]; */ switch (format_convert) { @@ -1343,7 +1567,7 @@ static inline void vdin_set_wr_ctrl(unsigned int offset, unsigned int v, write_format444 = 1; break; } - /* yuv422 full pack mode for 10bit */ + /*yuv422 full pack mode for 10bit*/ if (((format_convert == VDIN_FORMAT_CONVERT_YUV_YUV422) || (format_convert == VDIN_FORMAT_CONVERT_RGB_YUV422) || (format_convert == VDIN_FORMAT_CONVERT_GBR_YUV422) || @@ -1352,6 +1576,13 @@ static inline void vdin_set_wr_ctrl(unsigned int offset, unsigned int v, write_format444 = 3; /* win_he */ + if ((h%2) && (devp->source_bitdepth > 8) && + (devp->color_depth_mode == 1) && + ((devp->format_convert == VDIN_FORMAT_CONVERT_YUV_YUV422) || + (devp->format_convert == VDIN_FORMAT_CONVERT_RGB_YUV422) || + (devp->format_convert == VDIN_FORMAT_CONVERT_GBR_YUV422) || + (devp->format_convert == VDIN_FORMAT_CONVERT_BRG_YUV422))) + h += 1; wr_bits(offset, VDIN_WR_H_START_END, (h - 1), WR_HEND_BIT, WR_HEND_WID); /* win_ve */ wr_bits(offset, VDIN_WR_V_START_END, (v - 1), WR_VEND_BIT, WR_VEND_WID); @@ -1388,77 +1619,135 @@ static inline void vdin_set_wr_ctrl(unsigned int offset, unsigned int v, } /* format444 */ wr_bits(offset, VDIN_WR_CTRL, write_format444, WR_FMT_BIT, WR_FMT_WID); -/* - * canvas_id - * wr_bits(offset, VDIN_WR_CTRL, - * def_canvas_id, WR_CANVAS_BIT, WR_CANVAS_WID); +/* canvas_id + * wr_bits(offset, VDIN_WR_CTRL, + * def_canvas_id, WR_CANVAS_BIT, WR_CANVAS_WID); */ /* req_urgent */ wr_bits(offset, VDIN_WR_CTRL, 1, WR_REQ_URGENT_BIT, WR_REQ_URGENT_WID); /* req_en */ wr_bits(offset, VDIN_WR_CTRL, 1, WR_REQ_EN_BIT, WR_REQ_EN_WID); + /*only for vdin0*/ + if (devp->urgent_en && (devp->index == 0)) + vdin_urgent_patch(offset, v, h); /* dis ctrl reg wpulse */ - /* if (is_meson_g9tv_cpu() || is_meson_m8_cpu() || + /*if (is_meson_g9tv_cpu() || is_meson_m8_cpu() || * is_meson_m8m2_cpu() || is_meson_gxbb_cpu() || * is_meson_m8b_cpu()) */ - wr_bits(offset, VDIN_WR_CTRL, 1, 10, 1); + wr_bits(offset, VDIN_WR_CTRL, 1, + VDIN_WRCTRLREG_PAUSE_BIT, 1); /* swap the 2 64bits word in 128 words */ /*if (is_meson_gxbb_cpu())*/ wr_bits(offset, VDIN_WR_CTRL, 1, 19, 1); } -#if 0 -void set_wr_ctrl(int h_pos, int v_pos, struct vdin_dev_s *devp) +void vdin_set_wr_ctrl_vsync(struct vdin_dev_s *devp, + unsigned int offset, enum vdin_format_convert_e format_convert, + unsigned int color_depth_mode, unsigned int source_bitdeth, + unsigned int rdma_enable) { - enum tvin_sig_fmt_e fmt = devp->parm.info.fmt; - unsigned int offset = devp->addr_offset; - unsigned int ve = 0; - const struct tvin_format_s *fmt_info = tvin_get_fmt_info(fmt); + unsigned int write_format444 = 0, swap_cbcr = 0; + unsigned int hconv_mode, vconv_mode; - if (!fmt_info) { - pr_err("[tvafe..] %s: error,fmt is null!!!\n", __func__); - return; + switch (format_convert) { + case VDIN_FORMAT_CONVERT_YUV_YUV422: + case VDIN_FORMAT_CONVERT_RGB_YUV422: + write_format444 = 0; + break; + case VDIN_FORMAT_CONVERT_YUV_NV12: + case VDIN_FORMAT_CONVERT_RGB_NV12: + write_format444 = 2; + swap_cbcr = 1; + break; + case VDIN_FORMAT_CONVERT_YUV_NV21: + case VDIN_FORMAT_CONVERT_RGB_NV21: + write_format444 = 2; + swap_cbcr = 0; + break; + default: + write_format444 = 1; + break; } + /*yuv422 full pack mode for 10bit*/ + if (((format_convert == VDIN_FORMAT_CONVERT_YUV_YUV422) || + (format_convert == VDIN_FORMAT_CONVERT_RGB_YUV422) || + (format_convert == VDIN_FORMAT_CONVERT_GBR_YUV422) || + (format_convert == VDIN_FORMAT_CONVERT_BRG_YUV422)) && + color_depth_mode && (source_bitdeth > 8)) + write_format444 = 3; -/* disable cut window */ - ve = fmt_info->v_active; - wr_bits(offset, VDIN_COM_CTRL0, 0, - INPUT_WIN_SEL_EN_BIT, INPUT_WIN_SEL_EN_WID); - if (h_pos + fmt_info->hs_bp < 0) { - unsigned int w_s = abs(h_pos + fmt_info->hs_bp); - - w_s = (1 + (w_s>>3))<<3; - wr_bits(offset, VDIN_WR_H_START_END, w_s, - WR_HSTART_BIT, WR_HSTART_WID); + /* hconv_mode */ + hconv_mode = 0; + /* vconv_mode */ + vconv_mode = 0; + if (write_format444 == 2) { + hconv_mode = 2; + vconv_mode = 0; + } else if (write_format444 == 1) { + vconv_mode = 3; } else { - wr_bits(offset, VDIN_WR_H_START_END, 0, - WR_HSTART_BIT, WR_HSTART_WID); + swap_cbcr = 0; } - if (v_pos + fmt_info->vs_bp - vbp_offset < 0) { - wr_bits(offset, VDIN_WR_V_START_END, - abs(v_pos + fmt_info->vs_bp - vbp_offset), - WR_VSTART_BIT, WR_VSTART_WID); - } else if (v_pos > fmt_info->vs_front) { - /* config write window and cut window - * when v pos > v front porch - */ - wr(offset, VDIN_WIN_V_START_END, - ((v_pos - fmt_info->vs_front)<h_active - 1) << INPUT_WIN_H_END_BIT)); - wr_bits(offset, VDIN_COM_CTRL0, 1, - INPUT_WIN_SEL_EN_BIT, INPUT_WIN_SEL_EN_WID); - ve -= v_pos - fmt_info->vs_front; - } else { - wr_bits(offset, VDIN_WR_V_START_END, 0, - WR_VSTART_BIT, WR_VSTART_WID); - } - vdin_set_wr_ctrl(devp->addr_offset, ve, devp->h_active, - devp->format_convert); -} +#ifdef CONFIG_AML_RDMA + if (rdma_enable) { + rdma_write_reg_bits(devp->rdma_handle, + VDIN_WR_CTRL+devp->addr_offset, + hconv_mode, HCONV_MODE_BIT, HCONV_MODE_WID); + rdma_write_reg_bits(devp->rdma_handle, + VDIN_WR_CTRL+devp->addr_offset, + vconv_mode, VCONV_MODE_BIT, VCONV_MODE_WID); + rdma_write_reg_bits(devp->rdma_handle, + VDIN_WR_CTRL+devp->addr_offset, + swap_cbcr, SWAP_CBCR_BIT, SWAP_CBCR_WID); + rdma_write_reg_bits(devp->rdma_handle, + VDIN_WR_CTRL+devp->addr_offset, + write_format444, WR_FMT_BIT, WR_FMT_WID); + } else #endif + { + wr_bits(offset, VDIN_WR_CTRL, hconv_mode, + HCONV_MODE_BIT, HCONV_MODE_WID); + wr_bits(offset, VDIN_WR_CTRL, vconv_mode, + VCONV_MODE_BIT, VCONV_MODE_WID); + wr_bits(offset, VDIN_WR_CTRL, swap_cbcr, + SWAP_CBCR_BIT, SWAP_CBCR_WID); + wr_bits(offset, VDIN_WR_CTRL, write_format444, + WR_FMT_BIT, WR_FMT_WID); + } +} + +/* set vdin_wr_mif for video only */ +void vdin_set_wr_mif(struct vdin_dev_s *devp) +{ + int height, width; + static unsigned int temp_height; + static unsigned int temp_width; + + height = ((rd(0, VPP_POSTBLEND_VD1_V_START_END) & 0xfff) - + ((rd(0, VPP_POSTBLEND_VD1_V_START_END) >> 16) & + 0xfff) + 1); + width = ((rd(0, VPP_POSTBLEND_VD1_H_START_END) & 0xfff) - + ((rd(0, VPP_POSTBLEND_VD1_H_START_END) >> 16) & + 0xfff) + 1); + if ((devp->parm.port == TVIN_PORT_VIDEO) && (devp->index == 1) && + ((height != temp_height) && (width != temp_width))) { + if ((width%2) && (devp->source_bitdepth > + VDIN_MIN_SOURCE_BITDEPTH) && + (devp->color_depth_mode == 1) && + ((devp->format_convert == VDIN_FORMAT_CONVERT_YUV_YUV422) || + (devp->format_convert == VDIN_FORMAT_CONVERT_RGB_YUV422) || + (devp->format_convert == VDIN_FORMAT_CONVERT_GBR_YUV422) || + (devp->format_convert == VDIN_FORMAT_CONVERT_BRG_YUV422))) + width += 1; + wr_bits(devp->addr_offset, VDIN_WR_H_START_END, + (width - 1), WR_HEND_BIT, WR_HEND_WID); + wr_bits(devp->addr_offset, VDIN_WR_V_START_END, + (height - 1), WR_VEND_BIT, WR_VEND_WID); + temp_height = height; + temp_width = width; + } +} + /***************************global function**********************************/ @@ -1534,7 +1823,6 @@ void vdin_set_def_wr_canvas(struct vdin_dev_s *devp) { unsigned int offset = devp->addr_offset; unsigned int def_canvas; - def_canvas = vdin_canvas_ids[devp->index][0]; /* [31:24] write.out_ctrl = 0x0b */ @@ -1553,17 +1841,23 @@ void vdin_set_def_wr_canvas(struct vdin_dev_s *devp) wr(offset, VDIN_WR_CTRL, (0x0bc01000 | def_canvas)); } -#ifdef CONFIG_AMLOGIC_LOCAL_DIMMING -void vdin_set_ldim_max_init(unsigned int offset, +/*set local dimming*/ +#ifdef CONFIG_AML_LOCAL_DIMMING + +#define VDIN_LDIM_PIC_ROWMAX 1080 +#define VDIN_LDIM_PIC_COLMAX 1920 +#define VDIN_LDIMMAX_HIDX 4095 +#define VDIN_LDIM_BLK_VNUM 2 +#define VDIN_LDIM_BLK_HNUM 8 +static void vdin_set_ldim_max_init(unsigned int offset, int pic_h, int pic_v, int blk_vnum, int blk_hnum) { int k; struct ldim_max_s ldimmax; - int ldim_pic_rowmax = 1080; - int ldim_pic_colmax = 1920; - int ldim_blk_vnum = 2; - int ldim_blk_hnum = 8; - + int ldim_pic_rowmax = VDIN_LDIM_PIC_ROWMAX; + int ldim_pic_colmax = VDIN_LDIM_PIC_COLMAX; + int ldim_blk_vnum = VDIN_LDIM_BLK_VNUM; + int ldim_blk_hnum = VDIN_LDIM_BLK_HNUM; ldim_pic_rowmax = pic_v; ldim_pic_colmax = pic_h; ldim_blk_vnum = blk_vnum; /* 8; */ @@ -1573,31 +1867,38 @@ void vdin_set_ldim_max_init(unsigned int offset, /* check ic type */ if (!is_meson_gxtvbb_cpu()) return; - - pr_info("\n****************vdin_set_ldim_max_init:hidx start********\n"); + if (vdin_ctl_dbg) + pr_info("\n****************vdin_set_ldim_max_init:hidx start********\n"); for (k = 1; k < 11; k++) { ldimmax.ld_stamax_hidx[k] = ((ldim_pic_colmax + ldim_blk_hnum - 1)/ldim_blk_hnum)*k; - if (ldimmax.ld_stamax_hidx[k] > 4095) - ldimmax.ld_stamax_hidx[k] = 4095; /* clip U12 */ + if (ldimmax.ld_stamax_hidx[k] > VDIN_LDIMMAX_HIDX) + /* clip U12 */ + ldimmax.ld_stamax_hidx[k] = VDIN_LDIMMAX_HIDX; if (ldimmax.ld_stamax_hidx[k] == ldim_pic_colmax) ldimmax.ld_stamax_hidx[k] = ldim_pic_colmax - 1; - pr_info("%d\t", ldimmax.ld_stamax_hidx[k]); + if (vdin_ctl_dbg) + pr_info("%d\t", ldimmax.ld_stamax_hidx[k]); } - pr_info("\n****************vdin_set_ldim_max_init:hidx end*********\n"); + if (vdin_ctl_dbg) + pr_info("\n****************vdin_set_ldim_max_init:hidx end*********\n"); ldimmax.ld_stamax_vidx[0] = 0; - pr_info("\n***********vdin_set_ldim_max_init:vidx start************\n"); + if (vdin_ctl_dbg) + pr_info("\n***********vdin_set_ldim_max_init:vidx start************\n"); for (k = 1; k < 11; k++) { ldimmax.ld_stamax_vidx[k] = ((ldim_pic_rowmax + ldim_blk_vnum - 1)/ldim_blk_vnum)*k; - if (ldimmax.ld_stamax_vidx[k] > 4095) - ldimmax.ld_stamax_vidx[k] = 4095; /* clip to U12 */ + if (ldimmax.ld_stamax_vidx[k] > VDIN_LDIMMAX_HIDX) + /* clip to U12 */ + ldimmax.ld_stamax_vidx[k] = VDIN_LDIMMAX_HIDX; if (ldimmax.ld_stamax_vidx[k] == ldim_pic_rowmax) ldimmax.ld_stamax_vidx[k] = ldim_pic_rowmax - 1; - pr_info("%d\t", ldimmax.ld_stamax_vidx[k]); + if (vdin_ctl_dbg) + pr_info("%d\t", ldimmax.ld_stamax_vidx[k]); } - pr_info("\n*******vdin_set_ldim_max_init:vidx end*******\n"); + if (vdin_ctl_dbg) + pr_info("\n*******vdin_set_ldim_max_init:vidx end*******\n"); wr(offset, VDIN_LDIM_STTS_HIST_REGION_IDX, (1 << LOCAL_DIM_STATISTIC_EN_BIT) | (0 << EOL_EN_BIT) | @@ -1660,7 +1961,7 @@ void vdin_set_vframe_prop_info(struct vframe_s *vf, { unsigned int offset = devp->addr_offset; struct vframe_bbar_s bbar = {0}; -#ifdef CONFIG_AMLOGIC_LOCAL_DIMMING +#ifdef CONFIG_AML_LOCAL_DIMMING /*int i;*/ #endif /* fetch hist info */ @@ -1836,13 +2137,13 @@ void vdin_set_vframe_prop_info(struct vframe_s *vf, } /* Update Histgram windown with detected BlackBar window */ - if (hist_bar_enable) + if (devp->hist_bar_enable) vdin_set_histogram(offset, 0, vf->width - 1, 0, vf->height - 1); else vdin_set_histogram(offset, bbar.left, bbar.right, bbar.top, bbar.bottom); - if (black_bar_enable) { + if (devp->black_bar_enable) { vf->prop.bbar.top = bbar.top; vf->prop.bbar.bottom = bbar.bottom; vf->prop.bbar.left = bbar.left; @@ -1854,7 +2155,7 @@ void vdin_set_vframe_prop_info(struct vframe_s *vf, vf->prop.meas.vs_stamp = devp->stamp; vf->prop.meas.vs_cycle = devp->cycle; #if 0 -/*#ifdef CONFIG_AMLOGIC_LOCAL_DIMMING*/ +/*#ifdef CONFIG_AML_LOCAL_DIMMING*/ /* get ldim max */ if (vdin_ldim_max_en && is_meson_gxtvbb_cpu()) { wr_bits(offset, VDIN_LDIM_STTS_HIST_REGION_IDX, 0, @@ -1874,8 +2175,6 @@ static inline ulong vdin_reg_limit(ulong val, ulong wid) return (1<addr_offset, devp->v_active, devp->h_active); -#ifdef CONFIG_AMLOGIC_LOCAL_DIMMING +#ifdef CONFIG_AML_LOCAL_DIMMING /* ldim sub-module */ /* vdin_set_ldim_max_init(devp->addr_offset, 1920, 1080, 8, 2); */ vdin_set_ldim_max_init(devp->addr_offset, devp->h_active, - devp->v_active, 8, 2); + devp->v_active, + VDIN_LDIM_BLK_HNUM, VDIN_LDIM_BLK_VNUM); #endif /* hist sub-module */ vdin_set_histogram(devp->addr_offset, 0, @@ -1896,18 +2196,23 @@ void vdin_set_all_regs(struct vdin_dev_s *devp) /* hist mux selecttion */ vdin_set_hist_mux(devp); /* write sub-module */ - vdin_set_wr_ctrl(devp->addr_offset, devp->v_active, + vdin_set_wr_ctrl(devp, devp->addr_offset, devp->v_active, devp->h_active, devp->format_convert, devp->color_depth_mode, devp->source_bitdepth); + /* top sub-module */ vdin_set_top(devp->addr_offset, devp->parm.port, devp->prop.color_format, devp->h_active, devp->bt_path); + + /* */ + vdin_set_meas_mux(devp->addr_offset, devp->parm.port, devp->bt_path); + } -void vdin_delay_line(unsigned short num, unsigned int offset) +static void vdin_delay_line(unsigned short num, unsigned int offset) { wr_bits(offset, VDIN_COM_CTRL0, num, DLY_GO_FLD_LN_NUM_BIT, DLY_GO_FLD_LN_NUM_WID); @@ -2044,7 +2349,9 @@ void vdin_set_default_regmap(unsigned int offset) /* [10: 0] matrix.pre_ofsset2 = 0 */ wr(offset, VDIN_MATRIX_PRE_OFFSET2, 0x00000000); /* [11: 0] write.lfifo_buf_size = 0x100 */ - if (is_meson_gxtvbb_cpu() || is_meson_txl_cpu()) + if (is_meson_m8b_cpu() || + is_meson_gxtvbb_cpu() || is_meson_txl_cpu() || + is_meson_txlx_cpu()) wr(offset, VDIN_LFIFO_CTRL, 0x00000f00); else wr(offset, VDIN_LFIFO_CTRL, 0x00000780); @@ -2087,7 +2394,7 @@ void vdin_set_default_regmap(unsigned int offset) WRITE_CHROMA_CANVAS_ADDR_WID); wr_bits(offset, VDIN_WR_CTRL2, 0, DISCARD_BEF_LINE_FIFO_BIT, DISCARD_BEF_LINE_FIFO_WID); - wr_bits(offset, VDIN_WR_CTRL2, vdin_wr_burst_mode, + wr_bits(offset, VDIN_WR_CTRL2, VDIN_WR_BURST_MODE, VDIN_WR_BURST_MODE_BIT, VDIN_WR_BURST_MODE_WID); if (get_cpu_type() >= MESON_CPU_MAJOR_ID_GXL) wr_bits(offset, VDIN_WR_CTRL2, 1, @@ -2111,7 +2418,10 @@ void vdin_set_default_regmap(unsigned int offset) /* Bit 15:0 vscaler ini_phase */ wr(offset, VDIN_VSC_INI_CTRL, 0x000000); /* Bit 12:0, scaler input height minus 1 */ - wr(offset, VDIN_SCIN_HEIGHTM1, 0x00000); + /*wr(offset, VDIN_SCIN_HEIGHTM1,0x000000);*/ + wr_bits(offset, VDIN_SCIN_HEIGHTM1, 0, SCALER_INPUT_HEIGHT_BIT, + SCALER_INPUT_HEIGHT_WID); + /* Bit 23:16, dummy component 0 */ /* Bit 15:8, dummy component 1 */ /* Bit 7:0, dummy component 2 */ @@ -2212,18 +2522,18 @@ void vdin_set_default_regmap(unsigned int offset) /* [28:16] input_win.vs = 0 */ /* [12: 0] input_win.ve = 0 */ wr(offset, VDIN_WIN_V_START_END, 0x00000000); - } void vdin_hw_enable(unsigned int offset) { /* enable video data input */ /* [ 4] top.datapath_en = 1 */ - wr_bits(offset, VDIN_COM_CTRL0, 1, 4, 1); + wr_bits(offset, VDIN_COM_CTRL0, 1, + VDIN_COMMONINPUT_EN_BIT, VDIN_COMMONINPUT_EN_WID); /* mux input */ /* [ 3: 0] top.mux = 0/(null, mpeg, 656, tvfe, cvd2, hdmi, dvin) */ - wr_bits(offset, VDIN_COM_CTRL0, 0, 0, 4); + wr_bits(offset, VDIN_COM_CTRL0, 0, VDIN_SEL_BIT, VDIN_SEL_WID); /* enable clock of blackbar, histogram, histogram, line fifo1, matrix, * hscaler, pre hscaler, clock0 @@ -2236,21 +2546,23 @@ void vdin_hw_enable(unsigned int offset) /* [ 5: 4] Enable pre hscaler clock = 00/(auto, off, on, on) */ /* [ 3: 2] Enable clock0 = 00/(auto, off, on, on) */ /* [ 0] Enable register clock = 00/(auto, off!!!!!!!!) */ - wr(offset, VDIN_COM_GCLK_CTRL, 0x0); + switch_vpu_clk_gate_vmod(offset == 0 ? VPU_VIU_VDIN0 : VPU_VIU_VDIN1, + VPU_CLK_GATE_ON); + /* wr(offset, VDIN_COM_GCLK_CTRL, 0x0); */ } - void vdin_hw_disable(unsigned int offset) { /* disable cm2 */ wr_bits(offset, VDIN_CM_BRI_CON_CTRL, 0, CM_TOP_EN_BIT, CM_TOP_EN_WID); /* disable video data input */ /* [ 4] top.datapath_en = 0 */ - wr_bits(offset, VDIN_COM_CTRL0, 0, 4, 1); + wr_bits(offset, VDIN_COM_CTRL0, 0, + VDIN_COMMONINPUT_EN_BIT, VDIN_COMMONINPUT_EN_WID); /* mux null input */ /* [ 3: 0] top.mux = 0/(null, mpeg, 656, tvfe, cvd2, hdmi, dvin) */ - wr_bits(offset, VDIN_COM_CTRL0, 0, 0, 4); + wr_bits(offset, VDIN_COM_CTRL0, 0, VDIN_SEL_BIT, VDIN_SEL_WID); wr(offset, VDIN_COM_CTRL0, 0x00000910); vdin_delay_line(delay_line_num, offset); if (enable_reset) @@ -2269,7 +2581,9 @@ void vdin_hw_disable(unsigned int offset) /* [ 5: 4] Disable pre hscaler clock = 01/(auto, off, on, on) */ /* [ 3: 2] Disable clock0 = 01/(auto, off, on, on) */ /* [ 0] Enable register clock = 00/(auto, off!!!!!!!!) */ - wr(offset, VDIN_COM_GCLK_CTRL, 0x5554); + switch_vpu_clk_gate_vmod(offset == 0 ? VPU_VIU_VDIN0:VPU_VIU_VDIN1, + VPU_CLK_GATE_OFF); + /* wr(offset, VDIN_COM_GCLK_CTRL, 0x5554); */ } /* get current vsync field type 0:top 1 bottom */ @@ -2287,8 +2601,10 @@ int vdin_vsync_reset_mif(int index) if (!enable_reset) return 0; if (index == 0) { - W_VCBUS_BIT(VDIN_WR_CTRL, 0, 25, 1); /* vdin->vdin mif wr en */ - W_VCBUS_BIT(VDIN_WR_CTRL, 1, 29, 1); /* clock gate */ + W_VCBUS_BIT(VDIN_WR_CTRL, 0, VDIN0_VCP_WR_EN_BIT, + VDIN0_VCP_WR_EN_WID); /* vdin->vdin mif wr en */ + W_VCBUS_BIT(VDIN_WR_CTRL, 1, VDIN0_DISABLE_CLOCKGATE_BIT, + VDIN0_DISABLE_CLOCKGATE_WID); /* clock gate */ /* wr req en */ W_VCBUS_BIT(VDIN_WR_CTRL, 0, WR_REQ_EN_BIT, WR_REQ_EN_WID); aml_write_vcbus(VPU_WRARB_REQEN_SLV_L1C2, vpu_reg_27af & @@ -2306,7 +2622,7 @@ int vdin_vsync_reset_mif(int index) break; } } - if (i >= vdin_det_idle_wait) + if ((i >= vdin_det_idle_wait) && vdin_ctl_dbg) pr_info("============== !!! idle wait timeout\n"); } @@ -2314,13 +2630,17 @@ int vdin_vsync_reset_mif(int index) vpu_reg_27af | (1 << VDIN0_REQ_EN_BIT)); W_VCBUS_BIT(VDIN_WR_CTRL, 1, WR_REQ_EN_BIT, WR_REQ_EN_WID); - W_VCBUS_BIT(VDIN_WR_CTRL, 0, 29, 1); - W_VCBUS_BIT(VDIN_WR_CTRL, 1, 25, 1); + W_VCBUS_BIT(VDIN_WR_CTRL, 0, VDIN0_DISABLE_CLOCKGATE_BIT, + VDIN0_DISABLE_CLOCKGATE_WID); + W_VCBUS_BIT(VDIN_WR_CTRL, 1, + VDIN0_VCP_WR_EN_BIT, VDIN0_VCP_WR_EN_WID); vpu_reg_27af |= VDIN0_REQ_EN_BIT; } else if (index == 1) { - W_VCBUS_BIT(VDIN1_WR_CTRL2, 1, 8, 1); /* vdin->vdin mif wr en */ - W_VCBUS_BIT(VDIN1_WR_CTRL, 1, 29, 1); /* clock gate */ + W_VCBUS_BIT(VDIN1_WR_CTRL2, 1, VDIN1_VCP_WR_EN_BIT, + VDIN1_VCP_WR_EN_WID); /* vdin->vdin mif wr en */ + W_VCBUS_BIT(VDIN1_WR_CTRL, 1, VDIN1_DISABLE_CLOCKGATE_BIT, + VDIN1_DISABLE_CLOCKGATE_WID); /* clock gate */ /* wr req en */ W_VCBUS_BIT(VDIN1_WR_CTRL, 0, WR_REQ_EN_BIT, WR_REQ_EN_WID); aml_write_vcbus(VPU_WRARB_REQEN_SLV_L1C2, @@ -2343,8 +2663,10 @@ int vdin_vsync_reset_mif(int index) vpu_reg_27af | (1 << VDIN1_REQ_EN_BIT)); vpu_reg_27af |= (1 << VDIN1_REQ_EN_BIT); W_VCBUS_BIT(VDIN1_WR_CTRL, 1, WR_REQ_EN_BIT, WR_REQ_EN_WID); - W_VCBUS_BIT(VDIN1_WR_CTRL, 0, 29, 1); - W_VCBUS_BIT(VDIN1_WR_CTRL2, 0, 8, 1); + W_VCBUS_BIT(VDIN1_WR_CTRL, 0, VDIN1_DISABLE_CLOCKGATE_BIT, + VDIN1_DISABLE_CLOCKGATE_WID); + W_VCBUS_BIT(VDIN1_WR_CTRL2, 0, + VDIN1_VCP_WR_EN_BIT, VDIN1_VCP_WR_EN_WID); } #if 0 /* TODO: if start or end line > 0, should drop this frame! */ if ((aml_read_vcbus(VDIN_LCNT_STATUS) & 0xfff) > 0) { @@ -2460,15 +2782,15 @@ bool vdin_check_vs(struct vdin_dev_s *devp) return ret; } /* - * cycle = delta_stamp = ((1/fps)/(1/msr_clk))*(vsync_span+1) - * msr_clk/fps unit is HZ - * vsync_span(0x125a[11:4]) usually should be 0; - */ +cycle = delta_stamp = ((1/fps)/(1/msr_clk))*(vsync_span+1) +msr_clk/fps unit is HZ +vsync_span(0x125a[11:4]) usually should be 0; +*/ bool vdin_check_cycle(struct vdin_dev_s *devp) { unsigned int stamp, cycle; - stamp = vdin_get_meas_vstamp(devp->addr_offset); + if (stamp < devp->stamp) cycle = 0xffffffff - devp->stamp + stamp + 1; else @@ -2476,10 +2798,17 @@ bool vdin_check_cycle(struct vdin_dev_s *devp) if (cycle <= (devp->msr_clk_val/1000)) return true; - devp->stamp = stamp; - devp->cycle = cycle; - return false; + else { + devp->stamp = stamp; + devp->cycle = cycle; + return false; + } } + +/*function:calculate curr_wr_vf->duration + * based on parm.port\ msr_clk_val\ parm.flag and + * curr_field_type + */ void vdin_calculate_duration(struct vdin_dev_s *devp) { unsigned int last_field_type, cycle_phase; @@ -2496,20 +2825,19 @@ void vdin_calculate_duration(struct vdin_dev_s *devp) cycle_phase = devp->msr_clk_val/96000; if (cycle_phase == 0) { cycle_phase = 250; - pr_info("%s:cycle_phase is 0!!!!", __func__); + if (vdin_ctl_dbg) + pr_info("%s:cycle_phase is 0!!!!", __func__); } #ifdef VDIN_DYNAMIC_DURATION devp->curr_wr_vf->duration = (devp->cycle + cycle_phase/2) / cycle_phase; #else - if ((use_frame_rate == 1) && + if ((devp->use_frame_rate == 1) && ((port >= TVIN_PORT_HDMI0) && (port <= TVIN_PORT_HDMI7))) { curr_wr_vf->duration = (devp->cycle + cycle_phase/2) / cycle_phase; } else { - if (!fmt_info->duration) - curr_wr_vf->duration = - (devp->cycle + cycle_phase/2) / cycle_phase; + curr_wr_vf->duration = devp->duration; } #endif /* for 2D->3D mode & interlaced format, double top field @@ -2530,23 +2858,12 @@ void vdin_calculate_duration(struct vdin_dev_s *devp) } #endif } -void vdin_output_ctl(unsigned int offset, unsigned int output_nr_flag) -{ - wr_bits(offset, VDIN_WR_CTRL, 1, VCP_IN_EN_BIT, VCP_IN_EN_WID); - if (output_nr_flag) { - wr_bits(offset, VDIN_WR_CTRL, 0, VCP_WR_EN_BIT, VCP_WR_EN_WID); - wr_bits(offset, VDIN_WR_CTRL, 1, VCP_NR_EN_BIT, VCP_NR_EN_WID); - } else { - wr_bits(offset, VDIN_WR_CTRL, 1, VCP_WR_EN_BIT, VCP_WR_EN_WID); - wr_bits(offset, VDIN_WR_CTRL, 0, VCP_NR_EN_BIT, VCP_NR_EN_WID); - } -} /* *just for horizontal down scale src_w is origin width, *just dst_w is width after scale down */ -void vdin_set_hscale(unsigned int offset, unsigned int src_w, +static void vdin_set_hscale(unsigned int offset, unsigned int src_w, unsigned int dst_w) { @@ -2560,34 +2877,32 @@ void vdin_set_hscale(unsigned int offset, unsigned int src_w, 0xf84d42f9, 0xf84a45f9, 0xf84848f8 }; /* - * unsigned int filt_coef1[] = {//2 point bilinear - * 0x00800000, 0x007e0200, 0x007c0400, 0x007a0600, 0x00780800, - * 0x00760a00, 0x00740c00, 0x00720e00, 0x00701000, 0x006e1200, - * 0x006c1400, 0x006a1600,0x00681800, 0x00661a00, 0x00641c00, - * 0x00621e00, 0x00602000, 0x005e2200,0x005c2400, 0x005a2600, - * 0x00582800, 0x00562a00, 0x00542c00, 0x00522e00,0x00503000, - * 0x004e3200, 0x004c3400, 0x004a3600, 0x00483800, 0x00463a00, - * 0x00443c00, 0x00423e00, 0x00404000 - * }; - * - * unsigned int filt_coef2[] = { //2 point bilinear, bank_length == 2 - * 0x80000000, 0x7e020000, 0x7c040000, 0x7a060000, 0x78080000, - * 0x760a0000, 0x740c0000, 0x720e0000, 0x70100000, 0x6e120000, - * 0x6c140000, 0x6a160000, 0x68180000, 0x661a0000, 0x641c0000, - * 0x621e0000, 0x60200000, 0x5e220000, 0x5c240000, 0x5a260000, - * 0x58280000, 0x562a0000, 0x542c0000, 0x522e0000,0x50300000, - * 0x4e320000, 0x4c340000, 0x4a360000, 0x48380000, 0x463a0000, - * 0x443c0000, 0x423e0000, 0x40400000 - * }; - */ - int horz_phase_step, i; + unsigned int filt_coef1[] = {//2 point bilinear + 0x00800000, 0x007e0200, 0x007c0400, 0x007a0600, 0x00780800, + 0x00760a00, 0x00740c00, 0x00720e00, 0x00701000, 0x006e1200, + 0x006c1400, 0x006a1600,0x00681800, 0x00661a00, 0x00641c00, + 0x00621e00, 0x00602000, 0x005e2200,0x005c2400, 0x005a2600, + 0x00582800, 0x00562a00, 0x00542c00, 0x00522e00,0x00503000, + 0x004e3200, 0x004c3400, 0x004a3600, 0x00483800, 0x00463a00, + 0x00443c00, 0x00423e00, 0x00404000 + }; + unsigned int filt_coef2[] = { //2 point bilinear, bank_length == 2 + 0x80000000, 0x7e020000, 0x7c040000, 0x7a060000, 0x78080000, + 0x760a0000, 0x740c0000, 0x720e0000, 0x70100000, 0x6e120000, + 0x6c140000, 0x6a160000, 0x68180000, 0x661a0000, 0x641c0000, + 0x621e0000, 0x60200000, 0x5e220000, 0x5c240000, 0x5a260000, + 0x58280000, 0x562a0000, 0x542c0000, 0x522e0000,0x50300000, + 0x4e320000, 0x4c340000, 0x4a360000, 0x48380000, 0x463a0000, + 0x443c0000, 0x423e0000, 0x40400000 + }; + */ + int horz_phase_step, i; if (!dst_w) { pr_err("[vdin..]%s parameter dst_w error.\n", __func__); return; } - /* disable hscale&pre hscale */ - wr_bits(offset, VDIN_SC_MISC_CTRL, 0, PRE_HSCL_EN_BIT, PRE_HSCL_EN_WID); + /* disable hscale */ wr_bits(offset, VDIN_SC_MISC_CTRL, 0, HSCL_EN_BIT, HSCL_EN_WID); /* write horz filter coefs */ wr(offset, VDIN_SCALE_COEF_IDX, 0x0100); @@ -2614,8 +2929,8 @@ void vdin_set_hscale(unsigned int offset, unsigned int src_w, ); wr(offset, VDIN_SC_MISC_CTRL, + rd(offset, VDIN_SC_MISC_CTRL) | (0 << INIT_PIX_IN_PTR_BIT) | - (0 << PRE_HSCL_EN_BIT) |/* pre_hscale_en */ (1 << HSCL_EN_BIT) |/* hsc_en */ (1 << SHORT_LN_OUT_EN_BIT) |/* short_lineo_en */ (1 << HSCL_NEAREST_EN_BIT) |/* nearest_en */ @@ -2628,11 +2943,10 @@ void vdin_set_hscale(unsigned int offset, unsigned int src_w, *just for veritical scale src_w is origin height, *just dst_h is the height after scale */ -void vdin_set_vscale(unsigned int offset, unsigned int src_h, +static void vdin_set_vscale(unsigned int offset, unsigned int src_h, unsigned int dst_h) { int veri_phase_step, tmp; - if (!dst_h) { pr_err("[vdin..]%s parameter dst_h error.\n", __func__); return; @@ -2665,38 +2979,102 @@ void vdin_set_vscale(unsigned int offset, unsigned int src_h, wr_bits(offset, VDIN_VSC_INI_CTRL, 0, INI_SKIP_LINE_NUM_BIT, INI_SKIP_LINE_NUM_WID); - wr(offset, VDIN_SCIN_HEIGHTM1, src_h - 1); + wr_bits(offset, VDIN_SCIN_HEIGHTM1, src_h - 1, + SCALER_INPUT_HEIGHT_BIT, SCALER_INPUT_HEIGHT_WID); wr(offset, VDIN_DUMMY_DATA, 0x008080); /* enable vscale */ wr_bits(offset, VDIN_VSC_INI_CTRL, 1, VSC_EN_BIT, VSC_EN_WID); } +/* new add pre_hscale module + *do hscaler down when scaling4w is smaller than half of h_avtive + *which is closed by default + */ +static void vdin_set_prehscale(unsigned int offset) +{ + wr_bits(offset, VDIN_SC_MISC_CTRL, 0, PRE_HSCL_MODE_BIT, + PRE_HSCL_MODE_WID); + wr_bits(offset, VDIN_SC_MISC_CTRL, 1, PRE_HSCL_EN_BIT, PRE_HSCL_EN_WID); + pr_info("set_prehsc done!\n"); +} +/*new add vshrink module + *do vscaler down,when scaling4h is smaller than half of v_avtive + *which is closed by default + *vshrk_mode:0-->1:2; 1-->1:4; 2-->1:8 + *attention:only vdin1 have this module!! + */ +static void vdin_set_vshrink(unsigned int offset, unsigned int src_h, + unsigned int vshrk_mode) +{ + wr_bits(offset, VDIN_SCIN_HEIGHTM1, src_h - 1, + VSHRK_INPUT_HEIGHT_BIT, VSHRK_INPUT_HEIGHT_WID); + wr_bits(offset, VDIN_VSHRK_CTRL, 1, + VDIN_VSHRK_LPF_MODE_BIT, VDIN_VSHRK_LPF_MODE_WID); + wr_bits(offset, VDIN_VSHRK_CTRL, vshrk_mode, + VDIN_VSHRK_MODE_BIT, VDIN_VSHRK_MODE_WID); + wr_bits(offset, VDIN_VSHRK_CTRL, 1, + VDIN_VSHRK_EN_BIT, VDIN_VSHRK_EN_WID); + pr_info("set_vshrink done!\n"); +} + +/*function:set horizontal and veritical scale + *vdin scaler path: + * vdin0:prehsc-->hscaler-->vscaler; + * vdin1:prehsc-->hscaler-->vshrink-->vscaler + */ void vdin_set_hvscale(struct vdin_dev_s *devp) { unsigned int offset = devp->addr_offset; - + unsigned int vshrk_mode = 0; if ((devp->prop.scaling4w < devp->h_active) && (devp->prop.scaling4w > 0)) { - vdin_set_hscale(offset, devp->h_active, devp->prop.scaling4w); + if (devp->prehsc_en && (devp->prop.scaling4w <= + (devp->h_active >> 1))) { + vdin_set_prehscale(offset); + devp->h_active = devp->h_active >> 1; + } + if (devp->prop.scaling4w < devp->h_active) + vdin_set_hscale(offset, devp->h_active, + devp->prop.scaling4w); devp->h_active = devp->prop.scaling4w; - } else if (devp->h_active > max_hactive) { - vdin_set_hscale(offset, devp->h_active, max_hactive); - devp->h_active = max_hactive; + } else if (devp->h_active > VDIN_MAX_HACTIVE) { + vdin_set_hscale(offset, devp->h_active, VDIN_MAX_HACTIVE); + devp->h_active = VDIN_MAX_HACTIVE; } - pr_info("[vdin.%d] dst hactive:%u,", devp->index, devp->h_active); + if (vdin_ctl_dbg) + pr_info("[vdin.%d] dst hactive:%u,", + devp->index, devp->h_active); if ((devp->prop.scaling4h < devp->v_active) && (devp->prop.scaling4h > 0)) { - vdin_set_vscale(offset, devp->v_active, devp->prop.scaling4h); + if (devp->vshrk_en && (devp->h_active <= VDIN_VSHRINK_HLIMIT) && + (devp->index == 1) && (devp->prop.scaling4h <= + (devp->v_active >> 1))) { + vshrk_mode = devp->v_active/devp->prop.scaling4h; + if (vshrk_mode >= 8) + vshrk_mode = 2; + else if (vshrk_mode >= 4) + vshrk_mode = 1; + else if (vshrk_mode >= 2) + vshrk_mode = 0; + vdin_set_vshrink(offset, devp->v_active, vshrk_mode); + devp->v_active = devp->v_active >> (vshrk_mode + 1); + } + if (devp->prop.scaling4h < devp->v_active) + vdin_set_vscale(offset, devp->v_active, + devp->prop.scaling4h); devp->v_active = devp->prop.scaling4h; } - pr_info(" dst vactive:%u.\n", devp->v_active); + if (vdin_ctl_dbg) + pr_info(" dst vactive:%u.\n", devp->v_active); } - +/*set source_bitdepth + * base on color_depth_config: + * 10, 8, 0, other + */ void vdin_set_bitdepth(struct vdin_dev_s *devp) { unsigned int offset = devp->addr_offset; - switch (devp->color_depth_config) { case 8: devp->source_bitdepth = 8; @@ -2710,14 +3088,27 @@ void vdin_set_bitdepth(struct vdin_dev_s *devp) break; case 0: /* vdin_bit_depth is set to 0 by defaut, in this case, - * devp->source_bitdepth is controlled by colordepth + devp->source_bitdepth is controlled by colordepth + change default to 10bit for 8in8out detail maybe lost */ - if (devp->prop.colordepth == 8) { + if (((devp->prop.color_format == TVIN_RGB444) || + (devp->prop.color_format == TVIN_YUV444) || + (devp->prop.color_format == TVIN_BGGR) || + (devp->prop.color_format == TVIN_RGGB) || + (devp->prop.color_format == TVIN_GBRG) || + (devp->prop.color_format == TVIN_GRBG)) && + ((devp->prop.colordepth <= 8) || + is_meson_txlx_cpu())) { + /*txlx dmc is diff & bandwidth tension*/ devp->source_bitdepth = 8; wr_bits(offset, VDIN_WR_CTRL2, 0, VDIN_WR_10BIT_MODE_BIT, VDIN_WR_10BIT_MODE_WID); - } else if ((devp->prop.colordepth == 10) && - (devp->color_depth_support & VDIN_WR_COLOR_DEPTH_10BIT)) { + } else if ((devp->color_depth_support & + VDIN_WR_COLOR_DEPTH_10BIT) && + (devp->dv.dv_flag == false) && + ((devp->dv.dolby_input & + (1 << devp->index)) == false) && + (is_dolby_vision_enable() == false)) { devp->source_bitdepth = 10; wr_bits(offset, VDIN_WR_CTRL2, 1, VDIN_WR_10BIT_MODE_BIT, VDIN_WR_10BIT_MODE_WID); @@ -2735,6 +3126,15 @@ void vdin_set_bitdepth(struct vdin_dev_s *devp) } } +/*do horizontal reverse and veritical reverse + *hreverse: + *VDIN_WR_H_START_END + *Bit29: 1.reverse 0.do not reverse + * + *vreverse: + *VDIN_WR_V_START_END + *Bit29: 1.reverse 0.do not reverse + */ void vdin_wr_reverse(unsigned int offset, bool hreverse, bool vreverse) { if (hreverse) @@ -2783,7 +3183,12 @@ void vdin_set_cm2(unsigned int offset, unsigned int w, wr_bits(offset, VDIN_CM_BRI_CON_CTRL, 1, CM_TOP_EN_BIT, CM_TOP_EN_WID); } -void vdin0_output_ctl(unsigned int offset, unsigned int output_nr_flag) +/*vdin0 output ctrl + * Bit 26 vcp_nr_en. Only used in VDIN0. NOT used in VDIN1. + * Bit 25 vcp_wr_en. Only used in VDIN0. NOT used in VDIN1. + * Bit 24 vcp_in_en. Only used in VDIN0. NOT used in VDIN1. + */ +static void vdin_output_ctl(unsigned int offset, unsigned int output_nr_flag) { wr_bits(offset, VDIN_WR_CTRL, 1, VCP_IN_EN_BIT, VCP_IN_EN_WID); if (output_nr_flag) { @@ -2794,6 +3199,13 @@ void vdin0_output_ctl(unsigned int offset, unsigned int output_nr_flag) wr_bits(offset, VDIN_WR_CTRL, 0, VCP_NR_EN_BIT, VCP_NR_EN_WID); } } + +/* set mpegin + *VDIN_COM_CTRL0 + *Bit 31, mpeg_to_vdin_sel, + *0: mpeg source to NR directly, + *1: mpeg source pass through here + */ void vdin_set_mpegin(struct vdin_dev_s *devp) { unsigned int offset = devp->addr_offset; @@ -2813,14 +3225,773 @@ void vdin_set_mpegin(struct vdin_dev_s *devp) wr(offset, VDIN_HIST_CTRL, 0x3); wr(offset, VDIN_HIST_H_START_END, devp->h_active-1); wr(offset, VDIN_HIST_V_START_END, devp->v_active-1); - vdin0_output_ctl(offset, 1); + vdin_output_ctl(offset, 1); } void vdin_force_gofiled(struct vdin_dev_s *devp) { unsigned int offset = devp->addr_offset; - wr_bits(offset, VDIN_COM_CTRL0, 1, 28, 1); wr_bits(offset, VDIN_COM_CTRL0, 0, 28, 1); } +void vdin_dolby_addr_alloc(struct vdin_dev_s *devp, unsigned int size) +{ + unsigned int index, alloc_size; + alloc_size = dolby_size_byte*size; + devp->dv.dv_dma_vaddr = dma_alloc_coherent(devp->dev, + alloc_size, &devp->dv.dv_dma_paddr, GFP_KERNEL); + if (!devp->dv.dv_dma_vaddr) { + pr_info("%s:dmaalloc_coherent fail!!\n", __func__); + return; + } + memset(devp->dv.dv_dma_vaddr, 0, alloc_size); + for (index = 0; index < size; index++) { + devp->vfp->dv_buf_mem[index] = devp->dv.dv_dma_paddr + + dolby_size_byte * index; + devp->vfp->dv_buf_vmem[index] = devp->dv.dv_dma_vaddr + + dolby_size_byte * index; + if ((devp->cma_config_flag & 0x100) && devp->cma_config_en) + devp->vfp->dv_buf_ori[index] = + phys_to_virt(devp->vfmem_start[index] + + devp->vfmem_size - + dolby_size_byte); + else + devp->vfp->dv_buf_ori[index] = + phys_to_virt(devp->mem_start + devp->mem_size - + dolby_size_byte * + (devp->canvas_max_num - index)); + pr_info("%s:dv_buf[%d]=0x%p(0x%x,0x%p)\n", __func__, index, + devp->vfp->dv_buf_ori[index], + devp->vfp->dv_buf_mem[index], + devp->vfp->dv_buf_vmem[index]); + } + pr_info("%s:dv_dma_vaddr=0x%p,dv_dma_paddr=0x%lx\n", __func__, + devp->dv.dv_dma_vaddr, (ulong)devp->dv.dv_dma_paddr); +} +void vdin_dolby_addr_release(struct vdin_dev_s *devp, unsigned int size) +{ + unsigned int alloc_size; + + alloc_size = dolby_size_byte*size; + if (devp->dv.dv_dma_vaddr) + dma_free_coherent(devp->dev, alloc_size, + devp->dv.dv_dma_vaddr, devp->dv.dv_dma_paddr); + devp->dv.dv_dma_vaddr = NULL; +} + +static void vdin_dolby_metadata_swap(char *buf) +{ + char ext; + unsigned int i, j; + + for (i = 0; (i*16) < dolby_size_byte; i++) { + for (j = 0; j < 8; j++) { + ext = buf[i*16+j]; + buf[i*16+j] = buf[i*16+15-j]; + buf[i*16+15-j] = ext; + } + } +} + +#define swap32(num) \ + (((num>>24)&0xff) | \ + ((num<<8)&0xff0000) | \ + ((num>>8)&0xff00) | \ + ((num<<24)&0xff000000)) + +static uint32_t crc32_lut[256] = { + 0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9, 0x130476dc, 0x17c56b6b, + 0x1a864db2, 0x1e475005, 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61, + 0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd, 0x4c11db70, 0x48d0c6c7, + 0x4593e01e, 0x4152fda9, 0x5f15adac, 0x5bd4b01b, 0x569796c2, 0x52568b75, + 0x6a1936c8, 0x6ed82b7f, 0x639b0da6, 0x675a1011, 0x791d4014, 0x7ddc5da3, + 0x709f7b7a, 0x745e66cd, 0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039, + 0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5, 0xbe2b5b58, 0xbaea46ef, + 0xb7a96036, 0xb3687d81, 0xad2f2d84, 0xa9ee3033, 0xa4ad16ea, 0xa06c0b5d, + 0xd4326d90, 0xd0f37027, 0xddb056fe, 0xd9714b49, 0xc7361b4c, 0xc3f706fb, + 0xceb42022, 0xca753d95, 0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1, + 0xe13ef6f4, 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d, 0x34867077, 0x30476dc0, + 0x3d044b19, 0x39c556ae, 0x278206ab, 0x23431b1c, 0x2e003dc5, 0x2ac12072, + 0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16, 0x018aeb13, 0x054bf6a4, + 0x0808d07d, 0x0cc9cdca, 0x7897ab07, 0x7c56b6b0, 0x71159069, 0x75d48dde, + 0x6b93dddb, 0x6f52c06c, 0x6211e6b5, 0x66d0fb02, 0x5e9f46bf, 0x5a5e5b08, + 0x571d7dd1, 0x53dc6066, 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba, + 0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e, 0xbfa1b04b, 0xbb60adfc, + 0xb6238b25, 0xb2e29692, 0x8aad2b2f, 0x8e6c3698, 0x832f1041, 0x87ee0df6, + 0x99a95df3, 0x9d684044, 0x902b669d, 0x94ea7b2a, 0xe0b41de7, 0xe4750050, + 0xe9362689, 0xedf73b3e, 0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2, + 0xc6bcf05f, 0xc27dede8, 0xcf3ecb31, 0xcbffd686, 0xd5b88683, 0xd1799b34, + 0xdc3abded, 0xd8fba05a, 0x690ce0ee, 0x6dcdfd59, 0x608edb80, 0x644fc637, + 0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb, 0x4f040d56, 0x4bc510e1, + 0x46863638, 0x42472b8f, 0x5c007b8a, 0x58c1663d, 0x558240e4, 0x51435d53, + 0x251d3b9e, 0x21dc2629, 0x2c9f00f0, 0x285e1d47, 0x36194d42, 0x32d850f5, + 0x3f9b762c, 0x3b5a6b9b, 0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff, + 0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623, 0xf12f560e, 0xf5ee4bb9, + 0xf8ad6d60, 0xfc6c70d7, 0xe22b20d2, 0xe6ea3d65, 0xeba91bbc, 0xef68060b, + 0xd727bbb6, 0xd3e6a601, 0xdea580d8, 0xda649d6f, 0xc423cd6a, 0xc0e2d0dd, + 0xcda1f604, 0xc960ebb3, 0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7, + 0xae3afba2, 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b, 0x9b3660c6, 0x9ff77d71, + 0x92b45ba8, 0x9675461f, 0x8832161a, 0x8cf30bad, 0x81b02d74, 0x857130c3, + 0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640, 0x4e8ee645, 0x4a4ffbf2, + 0x470cdd2b, 0x43cdc09c, 0x7b827d21, 0x7f436096, 0x7200464f, 0x76c15bf8, + 0x68860bfd, 0x6c47164a, 0x61043093, 0x65c52d24, 0x119b4be9, 0x155a565e, + 0x18197087, 0x1cd86d30, 0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec, + 0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088, 0x2497d08d, 0x2056cd3a, + 0x2d15ebe3, 0x29d4f654, 0xc5a92679, 0xc1683bce, 0xcc2b1d17, 0xc8ea00a0, + 0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, 0xdbee767c, 0xe3a1cbc1, 0xe760d676, + 0xea23f0af, 0xeee2ed18, 0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4, + 0x89b8fd09, 0x8d79e0be, 0x803ac667, 0x84fbdbd0, 0x9abc8bd5, 0x9e7d9662, + 0x933eb0bb, 0x97ffad0c, 0xafb010b1, 0xab710d06, 0xa6322bdf, 0xa2f33668, + 0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4 +}; + +static uint32_t crc32(uint32_t crc, const void *buf, size_t size) +{ + const uint8_t *p = (const uint8_t *)buf; + + crc = ~crc; + while (size) { + crc = (crc << 8) ^ crc32_lut[((crc >> 24) ^ *p) & 0xff]; + p++; + size--; + } + return crc; +} + +void vdin_dolby_buffer_update(struct vdin_dev_s *devp, unsigned int index) +{ + uint32_t *p; + char *c; + uint32_t meta32, meta_size; + int i; + int count; + unsigned int offset = devp->addr_offset; + uint32_t crc_result, crc; + bool multimeta_flag = 0; + bool multimetatail_flag = 0; + uint32_t crc_result1 = 0; + uint32_t crc1 = 0; + int j, k; + char tmpmeta[1024]; + uint32_t extmetasize; + uint32_t metapayloadsize; + + metapayloadsize = DV_META_PACKET_SIZE - + DV_META_PACKET_TYPE_SIZE - + DV_META_HEADER_LEN - + DV_META_TAIL_CRC_SIZE; + if (index >= devp->canvas_max_num) + return; + + c = devp->vfp->dv_buf_ori[index]; + p = (uint32_t *)c; + for (count = 0; count < META_RETRY_MAX; count++) { + if (dv_dbg_mask & DV_READ_MODE_AXI) { + memcpy(p, devp->vfp->dv_buf_vmem[index], 128); + vdin_dolby_metadata_swap(c); + } else { + wr(offset, VDIN_DOLBY_DSC_CTRL3, 0); + wr(offset, VDIN_DOLBY_DSC_CTRL2, 0xd180c0d5); + for (i = 0; i < 128; i++) { + meta32 = rd(offset, VDIN_DOLBY_DSC_STATUS1); + p[i] = swap32(meta32); + if (((c[0] & (1 << 7)) == 0) && + ((c[0] & (1 << 6)) != 0)) + multimeta_flag = 1; + if ((i == 31) && (multimeta_flag == 0)) + break; + } + } + meta_size = (c[3] << 8) | c[4]; + crc = p[31]; + crc_result = crc32(0, p, 124); + crc_result = swap32(crc_result); + for (j = 128; j < 128 * 4; j += 128) { + if ((meta_size > metapayloadsize) && + ((c[j] & (1 << 7)) != 0) && + ((c[j] & (1 << 6)) != 0)) + multimetatail_flag = 1; + } + if (dv_dbg_log&(1<<0)) + pr_info("multimeta_flag=%d multimetatail_flag=%d\n", + multimeta_flag, multimetatail_flag); + if ((multimeta_flag == 1) && (multimetatail_flag == 1)) { + crc1 = p[127]; + crc_result1 = crc32(0, p + 32 * 3, 124); + crc_result1 = swap32(crc_result1); + } + if (crc == crc_result) { + if ((multimeta_flag == 1) && + (multimetatail_flag == 1)) { + if (crc1 == crc_result1) + break; + } else + break; + } + } + if ((crc != crc_result) || ((multimeta_flag == 1) + && (multimetatail_flag == 1) + && (crc1 != crc_result1))) { + /* set small size to make control path return -1 + * to use previous setting + */ + devp->vfp->dv_buf[index] = &c[5]; + devp->vfp->dv_buf_size[index] = 4; + if (dv_dbg_log&(1<<3)) { + pr_err("%s:hdmi dovi meta crc error:%08x!=%08x\n", + __func__, crc, crc_result); + pr_info("%s:index:%d dma:%x vaddr:%p size:%d\n", + __func__, index, + devp->vfp->dv_buf_mem[index], + devp->vfp->dv_buf_vmem[index], + meta_size); + for (i = 0; i < 128; i += 4) + pr_info("\t%08x %08x %08x %08x\n", + p[i], p[i+1], p[i+2], p[i+3]); + } + devp->dv.dv_crc_check = false; + } else { + devp->dv.dv_crc_check = true; + devp->vfp->dv_buf[index] = &c[5]; + devp->vfp->dv_buf_size[index] = meta_size; + if ((multimeta_flag == 1) && (multimetatail_flag == 1)) { + memcpy(tmpmeta, c + 5, metapayloadsize); + extmetasize = meta_size - metapayloadsize; + for (k = 0; k < extmetasize; k++) + tmpmeta[119 + k] = c[128 * 3 + 3 + k]; + memcpy(devp->vfp->dv_buf[index], tmpmeta, meta_size); + } else if (meta_size > metapayloadsize) + devp->dv.dv_crc_check = false; + if (dv_dbg_log&(1<<0)) + pr_info("%s:index:%d dma:%x vaddr:%p size:%d crc:%x crc1:%x\n", + __func__, index, + devp->vfp->dv_buf_mem[index], + devp->vfp->dv_buf_vmem[index], + meta_size, crc, crc1); + if (dv_dbg_log&(1<<2)) + for (i = 0; i < 128; i += 4) + pr_info("\t%08x %08x %08x %08x\n", + p[i], p[i+1], p[i+2], p[i+3]); + } +} + +void vdin_dolby_addr_update(struct vdin_dev_s *devp, unsigned int index) +{ + unsigned int offset = devp->addr_offset; + uint32_t *p; + + if (index >= devp->canvas_max_num) + return; + devp->vfp->dv_buf[index] = NULL; + devp->vfp->dv_buf_size[index] = 0; + p = (uint32_t *)devp->vfp->dv_buf_vmem[index]; + p[0] = p[1] = 0; + if (dv_dbg_mask & DV_READ_MODE_AXI) { + wr(offset, VDIN_DOLBY_AXI_CTRL1, + devp->vfp->dv_buf_mem[index]); + wr_bits(offset, VDIN_DOLBY_AXI_CTRL0, 1, 4, 1); + wr_bits(offset, VDIN_DOLBY_AXI_CTRL0, 0, 4, 1); + if (dv_dbg_log&(1<<0)) + pr_info("%s:index:%d dma:%x\n", __func__, + index, devp->vfp->dv_buf_mem[index]); + } else { + wr(offset, VDIN_DOLBY_DSC_CTRL2, 0x5180c0d5); + wr(offset, VDIN_DOLBY_DSC_CTRL3, 0); + if (dv_dbg_log&(1<<0)) + pr_info("%s:index:%d\n", __func__, index); + } + + if (dv_dbg_log&(1<<2)) + pr_info("%s:index:%d,paddr:0x%x\n", __func__, index, + devp->vfp->dv_buf_mem[index]); +} + +void vdin_dolby_config(struct vdin_dev_s *devp) +{ + unsigned int offset = devp->addr_offset; + + devp->dv.dv_config = 1; + wr_bits(offset, VDIN_DOLBY_DSC_CTRL0, 1, 30, 1); + wr_bits(offset, VDIN_DOLBY_DSC_CTRL0, 1, 26, 1); + wr_bits(offset, VDIN_DOLBY_DSC_CTRL0, 0, 26, 1); + if (dv_dbg_mask & DV_READ_MODE_AXI) { + wr(offset, VDIN_DOLBY_AXI_CTRL1, + devp->vfp->dv_buf_mem[0]); + /* hold line = 0 */ + wr_bits(offset, VDIN_DOLBY_AXI_CTRL0, 0, 8, 8); + wr_bits(offset, VDIN_DOLBY_AXI_CTRL0, 1, 4, 1); + wr_bits(offset, VDIN_DOLBY_AXI_CTRL0, 1, 5, 1); + wr_bits(offset, VDIN_DOLBY_AXI_CTRL0, 0, 5, 1); + wr_bits(offset, VDIN_DOLBY_AXI_CTRL0, 0, 4, 1); + } else { + wr(offset, VDIN_DOLBY_DSC_CTRL2, 0x5180c0d5); + wr(offset, VDIN_DOLBY_DSC_CTRL3, 0x0); + } +} + +int vdin_event_cb(int type, void *data, void *op_arg) +{ + unsigned long flags; + struct vf_pool *p; + + if (!op_arg) { + if (vdin_ctl_dbg&(1<<3)) + pr_info("%s:op_arg is NULL!\n", __func__); + return -1; + } + if (!data) { + if (vdin_ctl_dbg&(1<<4)) + pr_info("%s:data is NULL!\n", __func__); + return -1; + } + p = (struct vf_pool *)op_arg; + if (type & VFRAME_EVENT_RECEIVER_GET_AUX_DATA) { + struct provider_aux_req_s *req = + (struct provider_aux_req_s *)data; + unsigned char index; + + if (!req->vf) { + pr_info("%s:req->vf is NULL!\n", __func__); + return -1; + } + spin_lock_irqsave(&p->dv_lock, flags); + index = req->vf->index & 0xff; + req->aux_buf = NULL; + req->aux_size = 0; + req->dv_enhance_exist = 0; + /* TODO: need change the low latency flag when LL mode */ + req->low_latency = 0; + if (req->bot_flag) + index = (req->vf->index >> 8) & 0xff; + if (index != 0xff && index >= 0 + && index < p->size + && p->dv_buf[index]) { + req->aux_buf = p->dv_buf[index]; + req->aux_size = p->dv_buf_size[index]; + } + spin_unlock_irqrestore(&p->dv_lock, flags); + + if (dv_dbg_log&(1<<1)) + pr_info("%s(type 0x%x vf index 0x%x)=>size 0x%x\n", + __func__, type, index, req->aux_size); + } else if (type & VFRAME_EVENT_RECEIVER_DISP_MODE) { + struct provider_disp_mode_req_s *req = + (struct provider_disp_mode_req_s *)data; + unsigned int index_disp; + + if (!req->vf) { + pr_info("%s:req->vf is NULL!\n", __func__); + return -1; + } + index_disp = req->vf->index_disp & 0xff; + if (index_disp >= VFRAME_DISP_MAX_NUM) { + if (vdin_ctl_dbg) + pr_info("%s:req->vf->index_disp(%d) is overflow!\n", + __func__, index_disp); + return -1; + } + req->disp_mode = p->disp_mode[index_disp]; + if ((req->req_mode == 1) && (p->skip_vf_num)) + p->disp_mode[index_disp] = VFRAME_DISP_MODE_UNKNOWN; + if (vdin_ctl_dbg) + pr_info("%s(type 0x%x vf index 0x%x)=>disp_mode %d,req_mode:%d\n", + __func__, type, index_disp, req->disp_mode, + req->req_mode); + } + return 0; +} + +void set_invert_top_bot(bool invert_flag) +{ + invert_top_bot = invert_flag; +} + +static int vdin_hdr_sei_error_check(struct vdin_dev_s *devp) +{ + int primary_data[3][2]; + int i; + /*GBR compare with standard 709 primary*/ + for (i = 0; i < 3; i++) { + primary_data[i][0] = + devp->prop.hdr_info.hdr_data.primaries[i].x; + primary_data[i][1] = + devp->prop.hdr_info.hdr_data.primaries[i].y; + } + if (((primary_data[0][0] + 250) / 500 == 30) && + ((primary_data[0][1] + 250) / 500 == 60) && + ((primary_data[1][0] + 250) / 500 == 15) && + ((primary_data[1][1] + 250) / 500 == 6) && + ((primary_data[2][0] + 250) / 500 == 64) && + ((primary_data[2][1] + 250) / 500 == 33)) + return 1; + + /*RGB compare with standard 709 primary*/ + for (i = 0; i < 3; i++) { + primary_data[(i + 2) % 3][0] = + devp->prop.hdr_info.hdr_data.primaries[i].x; + primary_data[(i + 2) % 3][1] = + devp->prop.hdr_info.hdr_data.primaries[i].y; + } + + if (((primary_data[0][0] + 250) / 500 == 30) && + ((primary_data[0][1] + 250) / 500 == 60) && + ((primary_data[1][0] + 250) / 500 == 15) && + ((primary_data[1][1] + 250) / 500 == 6) && + ((primary_data[2][0] + 250) / 500 == 64) && + ((primary_data[2][1] + 250) / 500 == 33)) + return 1; + + /*GxBxRxGyByRy compare with standard 709 primary*/ + primary_data[0][0] = devp->prop.hdr_info.hdr_data.primaries[0].x; + primary_data[0][1] = devp->prop.hdr_info.hdr_data.primaries[1].y; + primary_data[1][0] = devp->prop.hdr_info.hdr_data.primaries[0].y; + primary_data[1][1] = devp->prop.hdr_info.hdr_data.primaries[2].x; + primary_data[2][0] = devp->prop.hdr_info.hdr_data.primaries[1].x; + primary_data[2][1] = devp->prop.hdr_info.hdr_data.primaries[2].y; + + if (((primary_data[0][0] + 250) / 500 == 30) && + ((primary_data[0][1] + 250) / 500 == 60) && + ((primary_data[1][0] + 250) / 500 == 15) && + ((primary_data[1][1] + 250) / 500 == 6) && + ((primary_data[2][0] + 250) / 500 == 64) && + ((primary_data[2][1] + 250) / 500 == 33)) + return 1; + else + return 0; +} + +void vdin_set_drm_data(struct vdin_dev_s *devp, + struct vframe_s *vf) +{ + struct vframe_master_display_colour_s *vf_dp + = &vf->prop.master_display_colour; + + if (devp->prop.hdr_info.hdr_state == HDR_STATE_GET) { + if (vdin_hdr_sei_error_check(devp) == 1) { + devp->prop.vdin_hdr_Flag = false; + vf_dp->present_flag = false; + vf->signal_type &= ~(1 << 29); + vf->signal_type &= ~(1 << 25); + /*todo;default is bt709,if change need sync*/ + vf->signal_type = ((1 << 16) | + (vf->signal_type & (~0xFF0000))); + vf->signal_type = ((1 << 8) | + (vf->signal_type & (~0xFF00))); + } else { + memcpy(vf_dp->primaries, + devp->prop.hdr_info.hdr_data.primaries, + sizeof(u32)*6); + memcpy(vf_dp->white_point, + &devp->prop.hdr_info.hdr_data.white_points, + sizeof(u32)*2); + memcpy(vf_dp->luminance, + &devp->prop.hdr_info.hdr_data.master_lum, + sizeof(u32)*2); + /* content_light_level */ + vf_dp->content_light_level.max_content = + devp->prop.hdr_info.hdr_data.mcll; + vf_dp->content_light_level.max_pic_average = + devp->prop.hdr_info.hdr_data.mfall; + + vf_dp->present_flag = true; + + if ((devp->prop.hdr_info.hdr_data.mcll != 0) && + (devp->prop.hdr_info.hdr_data.mfall != 0)) + vf_dp->content_light_level.present_flag = 1; + else + vf_dp->content_light_level.present_flag = 0; + + if ((devp->prop.hdr_info.hdr_data.eotf == + EOTF_SMPTE_ST_2048) || + (devp->prop.hdr_info.hdr_data.eotf == + EOTF_HDR)) { + vf->signal_type |= (1 << 29); + vf->signal_type |= (0 << 25);/*0:limit*/ + vf->signal_type = ((9 << 16) | + (vf->signal_type & (~0xFF0000))); + vf->signal_type = ((16 << 8) | + (vf->signal_type & (~0xFF00))); + vf->signal_type = ((9 << 0) | + (vf->signal_type & (~0xFF))); + } else { + vf->signal_type &= ~(1 << 29); + vf->signal_type &= ~(1 << 25); + /*todo;default is bt709,if change need sync*/ + vf->signal_type = ((1 << 16) | + (vf->signal_type & (~0xFF0000))); + vf->signal_type = ((1 << 8) | + (vf->signal_type & (~0xFF00))); + } + + devp->prop.vdin_hdr_Flag = true; + } + devp->prop.hdr_info.hdr_state = HDR_STATE_SET; + } else if (devp->prop.hdr_info.hdr_state == HDR_STATE_NULL) { + devp->prop.vdin_hdr_Flag = false; + vf_dp->present_flag = false; + vf->signal_type &= ~(1 << 29); + vf->signal_type &= ~(1 << 25); + /*todo;default is bt709,if change need sync*/ + vf->signal_type = ((1 << 16) | + (vf->signal_type & (~0xFF0000))); + vf->signal_type = ((1 << 8) | + (vf->signal_type & (~0xFF00))); + } +} + +u32 vdin_get_curr_field_type(struct vdin_dev_s *devp) +{ + u32 field_status; + u32 type = VIDTYPE_VIU_SINGLE_PLANE | VIDTYPE_VIU_FIELD; + enum vdin_format_convert_e format_convert; + + /* struct tvin_parm_s *parm = &devp->parm; */ + const struct tvin_format_s *fmt_info = devp->fmt_info_p; + + if (fmt_info->scan_mode == TVIN_SCAN_MODE_PROGRESSIVE) { + type |= VIDTYPE_PROGRESSIVE; + } else { + field_status = vdin_get_field_type(devp->addr_offset); + /*tvafe FIELD POLARITY 0 TOP,vdin must invert for correct*/ + if (invert_top_bot || + (devp->parm.port >= TVIN_PORT_CVBS0 && + devp->parm.port <= TVIN_PORT_CVBS7)) + type |= field_status ? + VIDTYPE_INTERLACE_TOP : VIDTYPE_INTERLACE_BOTTOM; + else + type |= field_status ? + VIDTYPE_INTERLACE_BOTTOM : VIDTYPE_INTERLACE_TOP; + } + format_convert = devp->format_convert; + if ((format_convert == VDIN_FORMAT_CONVERT_YUV_YUV444) || + (format_convert == VDIN_FORMAT_CONVERT_RGB_YUV444)) + type |= VIDTYPE_VIU_444; + else if ((format_convert == VDIN_FORMAT_CONVERT_YUV_YUV422) || + (format_convert == VDIN_FORMAT_CONVERT_RGB_YUV422)) + type |= VIDTYPE_VIU_422; + else if (devp->prop.dest_cfmt == TVIN_NV21) { + type |= VIDTYPE_VIU_NV21; + type &= (~VIDTYPE_VIU_SINGLE_PLANE); + } else if (devp->prop.dest_cfmt == TVIN_NV12) { + /* type |= VIDTYPE_VIU_NV12; */ + type &= (~VIDTYPE_VIU_SINGLE_PLANE); + + } + return type; +} + +/* function: set vf source type + * source type list: + * a.VFRAME_SOURCE_TYPE_TUNER (TVIN_PORT CVBS3/CVBS0) + * b.VFRAME_SOURCE_TYPE_CVBS (TVIN_PORT CVBS1/ + * CVBS2/CVBS4/CVBS5/CVBS6/CVBS7) + * c.VFRAME_SOURCE_TYPE_COMP (TVIN_PORT COMP0~COMP7) + * d.VFRAME_SOURCE_TYPE_HDMI (TVIN_PORT HDMI0~HDMI7/DVIN0) + * e.others + */ +inline void vdin_set_source_type(struct vdin_dev_s *devp, + struct vframe_s *vf) +{ + switch (devp->parm.port) { + case TVIN_PORT_CVBS3: + case TVIN_PORT_CVBS0: + vf->source_type = VFRAME_SOURCE_TYPE_TUNER; + break; + case TVIN_PORT_CVBS1: + case TVIN_PORT_CVBS2: + case TVIN_PORT_CVBS4: + case TVIN_PORT_CVBS5: + case TVIN_PORT_CVBS6: + case TVIN_PORT_CVBS7: + vf->source_type = VFRAME_SOURCE_TYPE_CVBS; + break; + case TVIN_PORT_COMP0: + case TVIN_PORT_COMP1: + case TVIN_PORT_COMP2: + case TVIN_PORT_COMP3: + case TVIN_PORT_COMP4: + case TVIN_PORT_COMP5: + case TVIN_PORT_COMP6: + case TVIN_PORT_COMP7: + vf->source_type = VFRAME_SOURCE_TYPE_COMP; + break; + case TVIN_PORT_HDMI0: + case TVIN_PORT_HDMI1: + case TVIN_PORT_HDMI2: + case TVIN_PORT_HDMI3: + case TVIN_PORT_HDMI4: + case TVIN_PORT_HDMI5: + case TVIN_PORT_HDMI6: + case TVIN_PORT_HDMI7: + case TVIN_PORT_DVIN0:/* external hdmiin used default */ + vf->source_type = VFRAME_SOURCE_TYPE_HDMI; + break; + default: + vf->source_type = VFRAME_SOURCE_TYPE_OTHERS; + break; + } +} + +/**function:set + *main source modes: + *a.NTSC b.PAL + *c.SECAM d.others + */ +inline void vdin_set_source_mode(struct vdin_dev_s *devp, + struct vframe_s *vf) +{ + switch (devp->parm.info.fmt) { + case TVIN_SIG_FMT_CVBS_NTSC_M: + case TVIN_SIG_FMT_CVBS_NTSC_443: + vf->source_mode = VFRAME_SOURCE_MODE_NTSC; + break; + case TVIN_SIG_FMT_CVBS_PAL_I: + case TVIN_SIG_FMT_CVBS_PAL_M: + case TVIN_SIG_FMT_CVBS_PAL_60: + case TVIN_SIG_FMT_CVBS_PAL_CN: + vf->source_mode = VFRAME_SOURCE_MODE_PAL; + break; + case TVIN_SIG_FMT_CVBS_SECAM: + vf->source_mode = VFRAME_SOURCE_MODE_SECAM; + break; + default: + vf->source_mode = VFRAME_SOURCE_MODE_OTHERS; + break; + } +} + +/* + * 480p/i = 9:8 + * 576p/i = 16:15 + * 720p and 1080p/i = 1:1 + * All VGA format = 1:1 + */ +void vdin_set_pixel_aspect_ratio(struct vdin_dev_s *devp, + struct vframe_s *vf) +{ + switch (devp->parm.info.fmt) { + /* 480P */ + case TVIN_SIG_FMT_COMP_480P_60HZ_D000: + case TVIN_SIG_FMT_HDMI_640X480P_60HZ: + case TVIN_SIG_FMT_HDMI_640X480P_72HZ: + case TVIN_SIG_FMT_HDMI_640X480P_75HZ: + case TVIN_SIG_FMT_HDMI_720X480P_60HZ: + case TVIN_SIG_FMT_HDMI_1440X480P_60HZ: + case TVIN_SIG_FMT_HDMI_2880X480P_60HZ: + case TVIN_SIG_FMT_HDMI_720X480P_120HZ: + case TVIN_SIG_FMT_HDMI_720X480P_240HZ: + case TVIN_SIG_FMT_HDMI_720X480P_60HZ_FRAME_PACKING: + case TVIN_SIG_FMT_CAMERA_640X480P_30HZ: + /* 480I */ + case TVIN_SIG_FMT_CVBS_NTSC_M: + case TVIN_SIG_FMT_CVBS_NTSC_443: + case TVIN_SIG_FMT_CVBS_PAL_M: + case TVIN_SIG_FMT_CVBS_PAL_60: + case TVIN_SIG_FMT_COMP_480I_59HZ_D940: + case TVIN_SIG_FMT_HDMI_1440X480I_60HZ: + case TVIN_SIG_FMT_HDMI_2880X480I_60HZ: + case TVIN_SIG_FMT_HDMI_1440X480I_120HZ: + case TVIN_SIG_FMT_HDMI_1440X480I_240HZ: + case TVIN_SIG_FMT_BT656IN_480I_60HZ: + case TVIN_SIG_FMT_BT601IN_480I_60HZ: + vf->pixel_ratio = PIXEL_ASPECT_RATIO_8_9; + break; + /* 576P */ + case TVIN_SIG_FMT_COMP_576P_50HZ_D000: + case TVIN_SIG_FMT_HDMI_720X576P_50HZ: + case TVIN_SIG_FMT_HDMI_1440X576P_50HZ: + case TVIN_SIG_FMT_HDMI_2880X576P_50HZ: + case TVIN_SIG_FMT_HDMI_720X576P_100HZ: + case TVIN_SIG_FMT_HDMI_720X576P_200HZ: + case TVIN_SIG_FMT_HDMI_720X576P_50HZ_FRAME_PACKING: + /* 576I */ + case TVIN_SIG_FMT_CVBS_PAL_I: + case TVIN_SIG_FMT_CVBS_PAL_CN: + case TVIN_SIG_FMT_CVBS_SECAM: + case TVIN_SIG_FMT_COMP_576I_50HZ_D000: + case TVIN_SIG_FMT_HDMI_1440X576I_50HZ: + case TVIN_SIG_FMT_HDMI_2880X576I_50HZ: + case TVIN_SIG_FMT_HDMI_1440X576I_100HZ: + case TVIN_SIG_FMT_HDMI_1440X576I_200HZ: + case TVIN_SIG_FMT_BT656IN_576I_50HZ: + case TVIN_SIG_FMT_BT601IN_576I_50HZ: + vf->pixel_ratio = PIXEL_ASPECT_RATIO_16_15; + break; + default: + vf->pixel_ratio = PIXEL_ASPECT_RATIO_1_1; + break; + } +} +/* + * based on the bellow parameters: + *1.h_active + *2.v_active + */ +void vdin_set_display_ratio(struct vdin_dev_s *devp, + struct vframe_s *vf) +{ + unsigned int re = 0; + enum tvin_aspect_ratio_e aspect_ratio = devp->prop.aspect_ratio; + + if (vf->width == 0 || vf->height == 0) + return; + re = (vf->width * 36)/vf->height; + if ((re > 36 && re <= 56) || (re == 90) || (re == 108)) + vf->ratio_control = 0xc0 << DISP_RATIO_ASPECT_RATIO_BIT; + else if (re > 56) + vf->ratio_control = 0x90 << DISP_RATIO_ASPECT_RATIO_BIT; + else + vf->ratio_control = 0x0 << DISP_RATIO_ASPECT_RATIO_BIT; + + if (aspect_ratio == TVIN_ASPECT_4x3) + vf->ratio_control = 0xc0 << DISP_RATIO_ASPECT_RATIO_BIT; + else if (aspect_ratio == TVIN_ASPECT_16x9) + vf->ratio_control = 0x90 << DISP_RATIO_ASPECT_RATIO_BIT; +} + +/*function:set source bitdepth + * based on parameter: + * devp->source_bitdepth: 8/9/10 + */ +inline void vdin_set_source_bitdepth(struct vdin_dev_s *devp, + struct vframe_s *vf) +{ + switch (devp->source_bitdepth) { + case 10: + vf->bitdepth = BITDEPTH_Y10 | BITDEPTH_U10 | BITDEPTH_V10; + break; + case 9: + vf->bitdepth = BITDEPTH_Y9 | BITDEPTH_U9 | BITDEPTH_V9; + break; + case 8: + vf->bitdepth = BITDEPTH_Y8 | BITDEPTH_U8 | BITDEPTH_V8; + break; + default: + vf->bitdepth = BITDEPTH_Y8 | BITDEPTH_U8 | BITDEPTH_V8; + break; + } + if (devp->color_depth_mode && (devp->source_bitdepth > 8) && + ((devp->format_convert == VDIN_FORMAT_CONVERT_YUV_YUV422) || + (devp->format_convert == VDIN_FORMAT_CONVERT_RGB_YUV422) || + (devp->format_convert == VDIN_FORMAT_CONVERT_GBR_YUV422) || + (devp->format_convert == VDIN_FORMAT_CONVERT_BRG_YUV422))) + vf->bitdepth |= FULL_PACK_422_MODE; +} + +/*@20170905new add for support dynamic adj dest_format yuv422/yuv444, + *not support nv21 dynamic adj!!! + */ +void vdin_source_bitdepth_reinit(struct vdin_dev_s *devp) +{ + int i = 0; + struct vf_entry *master; + struct vframe_s *vf; + struct vf_pool *p = devp->vfp; + + for (i = 0; i < p->size; ++i) { + master = vf_get_master(p, i); + vf = &master->vf; + vdin_set_source_bitdepth(devp, vf); + } +} diff --git a/drivers/amlogic/media/vin/tvin/vdin/vdin_ctl.h b/drivers/amlogic/media/vin/tvin/vdin/vdin_ctl.h index 6c808e714dad..4938a337cb78 100644 --- a/drivers/amlogic/media/vin/tvin/vdin/vdin_ctl.h +++ b/drivers/amlogic/media/vin/tvin/vdin/vdin_ctl.h @@ -18,12 +18,15 @@ #ifndef __TVIN_VDIN_CTL_H #define __TVIN_VDIN_CTL_H - -#include - #include "vdin_drv.h" - +#define DV_SWAP_EN (1 << 0) +#define DV_BUF_START_RESET (1 << 1) +#define DV_FRAME_BUF_START_RESET (1 << 2) +#define DV_UPDATE_DATA_MODE_DELBY_WORK (1 << 4) +#define DV_CLEAN_UP_MEM (1 << 5) +#define DV_READ_MODE_AXI (1 << 6) +#define DV_CRC_CHECK (1 << 7) /* *********************************************************************** */ /* *** enum definitions ********************************************* */ @@ -92,12 +95,7 @@ struct vdin_matrix_lup_s { unsigned int post_offset2; }; -struct vdin_stat_s { - unsigned int sum_luma; /* VDIN_HIST_LUMA_SUM_REG */ - unsigned int sum_pixel; /* VDIN_HIST_PIX_CNT_REG */ -}; - -#ifdef CONFIG_AMLOGIC_LOCAL_DIMMING +#ifdef CONFIG_AML_LOCAL_DIMMING struct ldim_max_s { /* general parameters */ int ld_pic_rowmax; @@ -107,15 +105,6 @@ struct ldim_max_s { }; #endif -struct vdin_hist_cfg_s { - unsigned int pow; - unsigned int win_en; - unsigned int rd_en; - unsigned int hstart; - unsigned int hend; - unsigned int vstart; - unsigned int vend; -}; /* ************************************************************************ */ /* ******** GLOBAL FUNCTION CLAIM ******** */ @@ -156,18 +145,13 @@ extern void vdin_set_chma_canvas_id(struct vdin_dev_s *devp, unsigned int rdma_enable, unsigned int canvas_id); extern void vdin_enable_module(unsigned int offset, bool enable); extern void vdin_set_matrix(struct vdin_dev_s *devp); -void vdin_set_matrixs(struct vdin_dev_s *devp, unsigned char no, +extern void vdin_set_matrixs(struct vdin_dev_s *devp, unsigned char no, enum vdin_format_convert_e csc); -extern void vdin_set_matrix_blank(struct vdin_dev_s *devp); -extern void vdin_delay_line(unsigned short num, unsigned int offset); -extern void set_wr_ctrl(int h_pos, int v_pos, struct vdin_dev_s *devp); extern bool vdin_check_cycle(struct vdin_dev_s *devp); extern bool vdin_write_done_check(unsigned int offset, struct vdin_dev_s *devp); extern bool vdin_check_vs(struct vdin_dev_s *devp); extern void vdin_calculate_duration(struct vdin_dev_s *devp); -extern void vdin_output_ctl(unsigned int offset, - unsigned int output_flag); extern void vdin_wr_reverse(unsigned int offset, bool hreverse, bool vreverse); extern void vdin_set_hvscale(struct vdin_dev_s *devp); @@ -178,6 +162,39 @@ extern void vdin_bypass_isp(unsigned int offset); extern void vdin_set_mpegin(struct vdin_dev_s *devp); extern void vdin_force_gofiled(struct vdin_dev_s *devp); extern void vdin_set_config(struct vdin_dev_s *devp); +extern void vdin_set_wr_mif(struct vdin_dev_s *devp); +extern void vdin_dolby_config(struct vdin_dev_s *devp); +extern void vdin_dolby_buffer_update(struct vdin_dev_s *devp, + unsigned int index); +extern void vdin_dolby_addr_update(struct vdin_dev_s *devp, unsigned int index); +extern void vdin_dolby_addr_alloc(struct vdin_dev_s *devp, unsigned int size); +extern void vdin_dolby_addr_release(struct vdin_dev_s *devp, unsigned int size); +extern int vdin_event_cb(int type, void *data, void *op_arg); +extern void vdin_hdmiin_patch(struct vdin_dev_s *devp); +extern void vdin_set_top(unsigned int offset, + enum tvin_port_e port, + enum tvin_color_fmt_e input_cfmt, unsigned int h, + enum bt_path_e bt_path); +extern void vdin_set_wr_ctrl_vsync(struct vdin_dev_s *devp, + unsigned int offset, enum vdin_format_convert_e format_convert, + unsigned int color_depth_mode, unsigned int source_bitdeth, + unsigned int rdma_enable); +extern void vdin_urgent_patch_resume(unsigned int offset); +extern void vdin_set_drm_data(struct vdin_dev_s *devp, + struct vframe_s *vf); +extern u32 vdin_get_curr_field_type(struct vdin_dev_s *devp); +extern void vdin_set_source_type(struct vdin_dev_s *devp, + struct vframe_s *vf); +extern void vdin_set_source_mode(struct vdin_dev_s *devp, + struct vframe_s *vf); +extern void vdin_set_source_bitdepth(struct vdin_dev_s *devp, + struct vframe_s *vf); +extern void vdin_set_pixel_aspect_ratio(struct vdin_dev_s *devp, + struct vframe_s *vf); +extern void vdin_set_display_ratio(struct vdin_dev_s *devp, + struct vframe_s *vf); +extern void vdin_source_bitdepth_reinit(struct vdin_dev_s *devp); +extern void set_invert_top_bot(bool invert_flag); #endif diff --git a/drivers/amlogic/media/vin/tvin/vdin/vdin_debug.c b/drivers/amlogic/media/vin/tvin/vdin/vdin_debug.c index 5b00247e4a4b..069e05c5fce3 100644 --- a/drivers/amlogic/media/vin/tvin/vdin/vdin_debug.c +++ b/drivers/amlogic/media/vin/tvin/vdin/vdin_debug.c @@ -26,13 +26,6 @@ #include #include #include -/* Amlogic Headers */ -/* #include */ -/* #include */ -/* #include */ -/* #if MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON8 */ -/* #include */ -/* #endif */ /* Local Headers */ #include "../tvin_format_table.h" #include "vdin_drv.h" @@ -46,11 +39,14 @@ static void vdin_get_vdin_yuv_rgb_mat0(unsigned int offset, { *rgb_yuv0 = 0; *rgb_yuv1 = 0; *rgb_yuv2 = 0; - *rgb_yuv0 = ((rd_bits(offset, VDIN_MATRIX_PROBE_COLOR, 0, 10) + *rgb_yuv0 = ((rd_bits(offset, VDIN_MATRIX_PROBE_COLOR, + COMPONENT2_PROBE_COLOR_BIT, COMPONENT2_PROBE_COLOR_WID) << 8) >> 10); - *rgb_yuv1 = ((rd_bits(offset, VDIN_MATRIX_PROBE_COLOR, 10, 10) + *rgb_yuv1 = ((rd_bits(offset, VDIN_MATRIX_PROBE_COLOR, + COMPONENT1_PROBE_COLOR_BIT, COMPONENT1_PROBE_COLOR_WID) << 8) >> 10); - *rgb_yuv2 = ((rd_bits(offset, VDIN_MATRIX_PROBE_COLOR, 20, 10) + *rgb_yuv2 = ((rd_bits(offset, VDIN_MATRIX_PROBE_COLOR, + COMPONENT0_PROBE_COLOR_BIT, COMPONENT0_PROBE_COLOR_WID) << 8) >> 10); } @@ -61,8 +57,10 @@ static void vdin_set_prob_matrix0_xy(unsigned int offset, if (devp->fmt_info_p->scan_mode == TVIN_SCAN_MODE_INTERLACED) y = y/2; - wr_bits(offset, VDIN_MATRIX_PROBE_POS, y, 0, 13); - wr_bits(offset, VDIN_MATRIX_PROBE_POS, x, 16, 13); + wr_bits(offset, VDIN_MATRIX_PROBE_POS, y, + PROBE_POX_Y_BIT, PROBE_POX_Y_WID); + wr_bits(offset, VDIN_MATRIX_PROBE_POS, x, + PROBE_POS_X_BIT, PROBE_POS_X_WID); } static void vdin_set_before_after_mat0(unsigned int offset, @@ -75,13 +73,12 @@ static void vdin_set_before_after_mat0(unsigned int offset, VDIN_PROBE_POST_BIT, VDIN_PROBE_POST_WID); } -static void parse_param(char *buf_orig, char **parm) +static void vdin_parse_param(char *buf_orig, char **parm) { char *ps, *token; char delim1[2] = " "; char delim2[2] = "\n"; unsigned int n = 0; - ps = buf_orig; strcat(delim1, delim2); while (1) { @@ -98,7 +95,6 @@ static ssize_t sig_det_show(struct device *dev, struct device_attribute *attr, char *buf) { int callmaster_status = 0; - return sprintf(buf, "%d\n", callmaster_status); } @@ -114,9 +110,11 @@ static ssize_t sig_det_store(struct device *dev, if (!buf) return len; /* port = simple_strtol(buf, NULL, 10); */ - if (kstrtol(buf, 10, &val) < 0) + if (kstrtol(buf, 10, &val) == 0) + port = val; + else return -EINVAL; - port = val; + frontend = tvin_get_frontend(port, 0); if (frontend && frontend->dec_ops && frontend->dec_ops->callmaster_det) { @@ -137,7 +135,6 @@ static ssize_t vdin_attr_show(struct device *dev, { struct vdin_dev_s *devp = dev_get_drvdata(dev); ssize_t len = 0; - len += sprintf(buf+len, "\n0 HDMI0\t1 HDMI1\t2 HDMI2\t3 Component0\t4 Component1"); len += sprintf(buf+len, "\n5 CVBS0\t6 CVBS1\t7 Vga0\t8 CVBS2\n"); @@ -155,15 +152,119 @@ static ssize_t vdin_attr_show(struct device *dev, "scan_fmt:\t1 : PROGRESSIVE\t2 INTERLACE\n"); len += sprintf(buf+len, "abnormal cnt %u\n", devp->abnormal_cnt); + len += sprintf(buf+len, + "echo fps >/sys/class/vdin/vdinx/attr\n"); + len += sprintf(buf+len, + "echo conversion w h dest_cfmt >/sys/class/vdin/vdinx/attr\n"); + len += sprintf(buf+len, + "\ndest_cfmt: 0 TVIN_RGB444\t1 TVIN_YUV422\t2 TVIN_YUV444"); + len += sprintf(buf+len, + "\n3 TVIN_YUYV422\t4 TVIN_YVYU422\t5 TVIN_UYVY422"); + len += sprintf(buf+len, + "\n6 TVIN_VYUY422\t7 TVIN_NV12\t8 TVIN_NV21\t9 TVIN_BGGR"); + len += sprintf(buf+len, + "\n10 TVIN_RGGB\t11 TVIN_GBRG\t12 TVIN_GRBG"); + len += sprintf(buf+len, + "echo state >/sys/class/vdin/vdinx/attr\n"); + len += sprintf(buf+len, + "echo histgram hnum vnum >/sys/class/vdin/vdinx/attr\n"); + len += sprintf(buf+len, + "echo force_recycle >/sys/class/vdin/vdinx/attr\n"); + len += sprintf(buf+len, + "echo read_pic parm1 parm2 >/sys/class/vdin/vdinx/attr\n"); + len += sprintf(buf+len, + "echo read_bin parm1 parm2 parm3 >/sys/class/vdin/vdinx/attr\n"); + len += sprintf(buf+len, + "echo dump_reg >/sys/class/vdin/vdinx/attr\n"); + len += sprintf(buf+len, + "echo capture external_storage/xxx.bin >/sys/class/vdin/vdinx/attr\n"); + len += sprintf(buf+len, + "echo freeze >/sys/class/vdin/vdinx/attr\n"); + len += sprintf(buf+len, + "echo unfreeze >/sys/class/vdin/vdinx/attr\n"); + len += sprintf(buf+len, + "echo rgb_xy x y >/sys/class/vdin/vdinx/attr\n"); + len += sprintf(buf+len, + "echo rgb_info >/sys/class/vdin/vdinx/attr\n"); + len += sprintf(buf+len, + "echo mpeg2vdin h_active v_active >/sys/class/vdin/vdinx/attr\n"); + len += sprintf(buf+len, + "echo yuv_rgb_info >/sys/class/vdin/vdinx/attr\n"); + len += sprintf(buf+len, + "echo mat0_xy x y >/sys/class/vdin/vdinx/attr\n"); + len += sprintf(buf+len, + "echo mat0_set x >/sys/class/vdin/vdinx/attr\n"); + len += sprintf(buf+len, + "echo hdr >/sys/class/vdin/vdinx/attr\n"); + len += sprintf(buf+len, + "echo snowon >/sys/class/vdin/vdinx/attr\n"); + len += sprintf(buf+len, + "echo snowoff >/sys/class/vdin/vdinx/attr\n"); + len += sprintf(buf+len, + "echo vf_reg >/sys/class/vdin/vdinx/attr\n"); + len += sprintf(buf+len, + "echo vf_unreg >/sys/class/vdin/vdinx/attr\n"); + len += sprintf(buf+len, + "echo pause_dec >/sys/class/vdin/vdinx/attr\n"); + len += sprintf(buf+len, + "echo resume_dec >/sys/class/vdin/vdinx/attr\n"); + len += sprintf(buf+len, + "echo color_depth val >/sys/class/vdin/vdinx/attr\n"); + len += sprintf(buf+len, + "echo color_depth_support val >/sys/class/vdin/vdinx/attr\n"); + len += sprintf(buf+len, + "echo color_depth_mode val >/sys/class/vdin/vdinx/attr\n"); + len += sprintf(buf+len, + "echo auto_cutwindow_en 0(1) >/sys/class/vdin/vdinx/attr\n"); + len += sprintf(buf+len, + "echo auto_ratio_en 0(1) >/sys/class/vdin/vdinx/attr\n"); + len += sprintf(buf+len, + "echo dolby_config >/sys/class/vdin/vdinx/attr\n"); + len += sprintf(buf+len, + "echo metadata >/sys/class/vdin/vdinx/attr\n"); + len += sprintf(buf+len, + "echo dolby_config >/sys/class/vdin/vdinx/attr\n"); + len += sprintf(buf+len, + "echo clean_dv >/sys/class/vdin/vdinx/attr\n"); + len += sprintf(buf+len, + "echo dv_debug >/sys/class/vdin/vdinx/attr\n"); + len += sprintf(buf+len, + "echo channel_order_config c0 c1 c2 >/sys/class/vdin/vdinx/attr\n"); + len += sprintf(buf+len, + "echo open_port portname >/sys/class/vdin/vdinx/attr\n"); + len += sprintf(buf+len, + "echo close_port >/sys/class/vdin/vdinx/attr\n"); + len += sprintf(buf+len, + "echo vshrk_en 0(1) >/sys/class/vdin/vdinx/attr.\n"); + len += sprintf(buf+len, + "echo prehsc_en 0(1) >/sys/class/vdin/vdinx/attr.\n"); + len += sprintf(buf+len, + "echo cma_mem_mode 0(1) >/sys/class/vdin/vdinx/attr.\n"); + len += sprintf(buf+len, + "echo dolby_input 0(1) >/sys/class/vdin/vdinx/attr.\n"); + len += sprintf(buf+len, + "echo hist_bar_enable 0(1) >/sys/class/vdin/vdinx/attr.\n"); + len += sprintf(buf+len, + "echo black_bar_enable 0(1) >/sys/class/vdin/vdinx/attr.\n"); + len += sprintf(buf+len, + "echo use_frame_rate 0(1) >/sys/class/vdin/vdinx/attr.\n"); + len += sprintf(buf+len, + "echo rdma_enable 0(1) >/sys/class/vdin/vdinx/attr.\n"); + len += sprintf(buf+len, + "echo irq_cnt >/sys/class/vdin/vdinx/attr.\n"); + len += sprintf(buf+len, + "echo rdma_irq_cnt >/sys/class/vdin/vdinx/attr.\n"); + len += sprintf(buf+len, + "echo skip_vf_num 0/1/2 /sys/class/vdin/vdinx/attr.\n"); return len; } -static void vdin_dump_mem(char *path, struct vdin_dev_s *devp) +static void vdin_dump_one_buf_mem(char *path, struct vdin_dev_s *devp, + unsigned int buf_num) { struct file *filp = NULL; loff_t pos = 0; void *buf = NULL; - loff_t i = 0; - unsigned int canvas_real_size = devp->canvas_h * devp->canvas_w; + unsigned int i; mm_segment_t old_fs = get_fs(); set_fs(KERNEL_DS); @@ -173,21 +274,77 @@ static void vdin_dump_mem(char *path, struct vdin_dev_s *devp) pr_info("create %s error.\n", path); return; } - if ((devp->cma_config_flag == 1) && + if ((devp->cma_config_flag & 0x1) && (devp->cma_mem_alloc == 0)) { pr_info("%s:no cma alloc mem!!!\n", __func__); return; } + if (buf_num < devp->canvas_max_num) { + if (devp->cma_config_flag == 0x1) + buf = codec_mm_phys_to_virt(devp->mem_start + + devp->canvas_max_size*buf_num); + else if (devp->cma_config_flag == 0x101) + buf = codec_mm_phys_to_virt(devp->vfmem_start[buf_num]); + else if (devp->cma_config_flag == 0x100) + buf = phys_to_virt(devp->vfmem_start[buf_num]); + else + buf = phys_to_virt(devp->mem_start + + devp->canvas_max_size*buf_num); + /*only write active data*/ + for (i = 0; i < devp->canvas_h; i++) { + vfs_write(filp, buf, devp->canvas_active_w, &pos); + buf += devp->canvas_w; + } + /*vfs_write(filp, buf, devp->canvas_max_size, &pos);*/ + pr_info("write buffer %2d of %2u to %s.\n", + buf_num, devp->canvas_max_num, path); + } + vfs_fsync(filp, 0); + filp_close(filp, NULL); + set_fs(old_fs); +} +static void vdin_dump_mem(char *path, struct vdin_dev_s *devp) +{ + struct file *filp = NULL; + loff_t pos = 0; + loff_t i = 0; + void *buf = NULL; + void *vfbuf[VDIN_CANVAS_MAX_CNT]; + mm_segment_t old_fs = get_fs(); + + set_fs(KERNEL_DS); + filp = filp_open(path, O_RDWR|O_CREAT, 0666); + + for (i = 0; i < VDIN_CANVAS_MAX_CNT; i++) + vfbuf[i] = NULL; + if (IS_ERR(filp)) { + pr_info("create %s error.\n", path); + return; + } + if ((devp->cma_config_flag & 0x1) && + (devp->cma_mem_alloc == 0)) { + pr_info("%s:no cma alloc mem!!!\n", __func__); + return; + } for (i = 0; i < devp->canvas_max_num; i++) { - pos = canvas_real_size * i; - if (devp->cma_config_flag == 1) + pos = devp->canvas_max_size * i; + if (devp->cma_config_flag == 0x1) buf = codec_mm_phys_to_virt(devp->mem_start + devp->canvas_max_size*i); + else if (devp->cma_config_flag == 0x101) + vfbuf[i] = codec_mm_phys_to_virt( + devp->vfmem_start[i]); + else if (devp->cma_config_flag == 0x100) + vfbuf[i] = phys_to_virt(devp->vfmem_start[i]); else buf = phys_to_virt(devp->mem_start + devp->canvas_max_size*i); - vfs_write(filp, buf, canvas_real_size, &pos); + if (devp->cma_config_flag & 0x100) + vfs_write(filp, vfbuf[i], devp->canvas_max_size, &pos); + else + vfs_write(filp, buf, devp->canvas_max_size, &pos); + pr_info("write buffer %lld of %2u to %s.\n", i, devp->canvas_max_num, path); } @@ -203,7 +360,6 @@ static void dump_other_mem(char *path, loff_t pos = 0; void *buf = NULL; mm_segment_t old_fs = get_fs(); - set_fs(KERNEL_DS); filp = filp_open(path, O_RDWR|O_CREAT, 0666); @@ -219,15 +375,71 @@ static void dump_other_mem(char *path, filp_close(filp, NULL); set_fs(old_fs); } +static void vdin_dv_debug(struct vdin_dev_s *devp) +{ + struct vframe_s *dv_vf; + struct vf_entry *vfe; + struct provider_aux_req_s req; + + vfe = devp->curr_wr_vfe; + if (!vfe) { + pr_info("current wr vfe is null\n"); + return; + } + dv_vf = &vfe->vf; + req.vf = dv_vf; + req.bot_flag = 0; + req.aux_buf = NULL; + req.aux_size = 0; + req.dv_enhance_exist = 0; + vf_notify_provider_by_name("vdin0", + VFRAME_EVENT_RECEIVER_GET_AUX_DATA, + (void *)&req); +} + +/*config vidn output channel order*/ +static void vdin_channel_order_config(unsigned int offset, + unsigned int vdin_data_bus_0, unsigned int vdin_data_bus_1, + unsigned int vdin_data_bus_2) +{ + wr_bits(offset, VDIN_COM_CTRL0, vdin_data_bus_0, + COMP0_OUT_SWT_BIT, COMP0_OUT_SWT_WID); + wr_bits(offset, VDIN_COM_CTRL0, vdin_data_bus_1, + COMP1_OUT_SWT_BIT, COMP1_OUT_SWT_WID); + wr_bits(offset, VDIN_COM_CTRL0, vdin_data_bus_2, + COMP2_OUT_SWT_BIT, COMP2_OUT_SWT_WID); +} +static void vdin_channel_order_status(unsigned int offset) +{ + unsigned int c0, c1, c2; + + c0 = rd_bits(offset, VDIN_COM_CTRL0, + COMP0_OUT_SWT_BIT, COMP0_OUT_SWT_WID); + c1 = rd_bits(offset, VDIN_COM_CTRL0, + COMP1_OUT_SWT_BIT, COMP1_OUT_SWT_WID); + c2 = rd_bits(offset, VDIN_COM_CTRL0, + COMP2_OUT_SWT_BIT, COMP2_OUT_SWT_WID); + pr_info("vdin(%x) current channel order is: %d %d %d\n", + offset, c0, c1, c2); +} + static void vdin_dump_state(struct vdin_dev_s *devp) { + unsigned int i; struct vframe_s *vf = &devp->curr_wr_vfe->vf; struct tvin_parm_s *curparm = &devp->parm; - + struct vf_pool *vfp = devp->vfp; pr_info("h_active = %d, v_active = %d\n", devp->h_active, devp->v_active); - pr_info("canvas_w = %d, canvas_h = %d\n", - devp->canvas_w, devp->canvas_h); + pr_info("canvas_w = %d, canvas_h = %d, canvas_alin_w = %d\n", + devp->canvas_w, devp->canvas_h, devp->canvas_alin_w); + if ((devp->cma_config_en != 1) || !(devp->cma_config_flag & 0x1)) + pr_info("mem_start = %ld, mem_size = %d\n", + devp->mem_start, devp->mem_size); + else + for (i = 0; i < devp->canvas_max_num; i++) + pr_info("buf[%d]mem_start = %ld, mem_size = %d\n", + i, devp->vfmem_start[i], devp->vfmem_size); pr_info("signal format = %s(0x%x)\n", tvin_sig_fmt_str(devp->parm.info.fmt), devp->parm.info.fmt); @@ -237,55 +449,98 @@ static void vdin_dump_state(struct vdin_dev_s *devp) pr_info("color_format = %s(%d)\n", tvin_color_fmt_str(devp->prop.color_format), devp->prop.color_format); - pr_info(" format_convert = %s(%d)\n", + pr_info("format_convert = %s(%d)\n", vdin_fmt_convert_str(devp->format_convert), devp->format_convert); - pr_info("aspect_ratio = %s(%d)\n decimation_ratio/dvi = %u / %u\n", + pr_info("aspect_ratio = %s(%d)\ndecimation_ratio/dvi = %u / %u\n", tvin_aspect_ratio_str(devp->prop.aspect_ratio), devp->prop.aspect_ratio, devp->prop.decimation_ratio, devp->prop.dvi_info); + pr_info("[pre->cur]:hs(%d->%d),he(%d->%d),vs(%d->%d),ve(%d->%d)\n", + devp->prop.pre_hs, devp->prop.hs, + devp->prop.pre_he, devp->prop.he, + devp->prop.pre_vs, devp->prop.vs, + devp->prop.pre_ve, devp->prop.ve); + pr_info("frontend_fps:%d\n", devp->prop.fps); pr_info("frontend_colordepth:%d\n", devp->prop.colordepth); pr_info("source_bitdepth:%d\n", devp->source_bitdepth); pr_info("color_depth_config:%d\n", devp->color_depth_config); pr_info("color_depth_mode:%d\n", devp->color_depth_mode); pr_info("color_depth_support:0x%x\n", devp->color_depth_support); - pr_info("cma_flag:%d\n", devp->cma_config_flag); + pr_info("cma_flag:0x%x\n", devp->cma_config_flag); + pr_info("auto_cutwindow_en:%d\n", devp->auto_cutwindow_en); + pr_info("auto_ratio_en:%d\n", devp->auto_ratio_en); + pr_info("cma_mem_alloc:%d\n", devp->cma_mem_alloc); + pr_info("cma_mem_size:0x%x\n", devp->cma_mem_size); + pr_info("cma_mem_mode:%d\n", devp->cma_mem_mode); + pr_info("force_yuv444_malloc:%d\n", devp->force_yuv444_malloc); vdin_dump_vf_state(devp->vfp); if (vf) { - pr_info("current vframe(%u):\n", vf->index); - pr_info(" buf(w%u, h%u),type(0x%x, %u), duration(%d),", + pr_info("current vframe index(%u):\n", vf->index); + pr_info("\t buf(w%u, h%u),type(0x%x, %u), duration(%d),", vf->width, vf->height, vf->type, vf->type, vf->duration); - pr_info("ratio_control(0x%x).\n", vf->ratio_control); - pr_info(" trans fmt %u, left_start_x %u,", + pr_info("\t ratio_control(0x%x).\n", vf->ratio_control); + pr_info("\t trans fmt %u, left_start_x %u,", vf->trans_fmt, vf->left_eye.start_x); - pr_info("right_start_x %u, width_x %u\n", + pr_info("\t right_start_x %u, width_x %u\n", vf->right_eye.start_x, vf->left_eye.width); - pr_info("left_start_y %u, right_start_y %u, height_y %u\n", + pr_info("\t left_start_y %u, right_start_y %u, height_y %u\n", vf->left_eye.start_y, vf->right_eye.start_y, vf->left_eye.height); - pr_info("current parameters:\n"); - pr_info(" frontend of vdin index : %d, 3d flag : 0x%x,", - curparm->index, curparm->flag); - pr_info("reserved 0x%x, devp->flags:0x%x,", - curparm->reserved, devp->flags); - pr_info("max buffer num %u.\n", devp->canvas_max_num); } - pr_info(" format_convert = %s(%d)\n", - vdin_fmt_convert_str(devp->format_convert), - devp->format_convert); - pr_info("color fmt(%d),csc_cfg:0x%x\n", - devp->prop.color_format, - devp->csc_cfg); - pr_info("range(%d),csc_cfg:0x%x\n", + if (vfp) { + pr_info("skip_vf_num:%d\n", vfp->skip_vf_num); + pr_info("**************disp_mode**************\n"); + for (i = 0; i < VFRAME_DISP_MAX_NUM; i++) + pr_info("[%d]:%-5d", i, vfp->disp_mode[i]); + pr_info("\n**************disp_index**************\n"); + for (i = 0; i < VFRAME_DISP_MAX_NUM; i++) + pr_info("[%d]:%-5d", i, vfp->disp_index[i]); + } + pr_info("\n current parameters:\n"); + pr_info("\t frontend of vdin index : %d, 3d flag : 0x%x\n", + curparm->index, curparm->flag); + pr_info("\t reserved 0x%x, devp->flags:0x%x\n", + curparm->reserved, devp->flags); + pr_info("max buffer num %u, msr_clk_val:%d.\n", + devp->canvas_max_num, devp->msr_clk_val); + pr_info("canvas buffer size %u, rdma_enable: %d, game_mode: %d.\n", + devp->canvas_max_size, devp->rdma_enable, devp->game_mode); + pr_info("range(%d),csc_cfg:0x%x,urgent_en:%d\n", devp->prop.color_fmt_range, - devp->csc_cfg); + devp->csc_cfg, devp->urgent_en); + pr_info("black_bar_enable: %d, hist_bar_enable: %d, use_frame_rate: %d\n ", + devp->black_bar_enable, + devp->hist_bar_enable, devp->use_frame_rate); + pr_info("vdin_irq_flag: %d, vdin_rest_flag: %d, irq_cnt: %d, rdma_irq_cnt: %d\n", + devp->vdin_irq_flag, devp->vdin_reset_flag, + devp->irq_cnt, devp->rdma_irq_cnt); + pr_info("rdma_enable : %d\n", devp->rdma_enable); + pr_info("dolby_input : %d\n", devp->dv.dolby_input); + if ((devp->cma_config_en != 1) || !(devp->cma_config_flag & 0x100)) + pr_info("dolby_mem_start = %ld, dolby_mem_size = %d\n", + (devp->mem_start + + devp->mem_size - devp->canvas_max_num*dolby_size_byte), + dolby_size_byte); + else + for (i = 0; i < devp->canvas_max_num; i++) + pr_info("dolby_mem_start[%d] = %ld, dolby_mem_size = %d\n", + i, (devp->vfmem_start[i] + devp->vfmem_size - + dolby_size_byte), dolby_size_byte); + for (i = 0; i < devp->canvas_max_num; i++) { + pr_info("dv_mem(%d):0x%x\n", + devp->vfp->dv_buf_size[i], + devp->vfp->dv_buf_mem[i]); + } + pr_info("dv_flag:%d;dv_config:%d,dolby_vision:%d\n", + devp->dv.dv_flag, devp->dv.dv_config, devp->prop.dolby_vision); + pr_info("size of struct vdin_dev_s: %d\n", devp->vdin_dev_ssize); pr_info("Vdin driver version : %s\n", VDIN_VER); } static void vdin_dump_histgram(struct vdin_dev_s *devp) { uint i; - pr_info("%s:\n", __func__); for (i = 0; i < 64; i++) { pr_info("[%d]0x%-8x\t", i, devp->parm.histgram[i]); @@ -294,21 +549,26 @@ static void vdin_dump_histgram(struct vdin_dev_s *devp) } } -static void vdin_write_mem(struct vdin_dev_s *devp, char *type, char *path) +static void vdin_write_mem( + struct vdin_dev_s *devp, char *type, + char *path, char *md_path) { - unsigned int real_size = 0, size = 0, vtype = 0; - struct file *filp = NULL; + unsigned int size = 0, vtype = 0; + struct file *filp = NULL, *md_flip = NULL; loff_t pos = 0; mm_segment_t old_fs; void *dts = NULL; long val; + int index; unsigned long addr; - + struct vf_pool *p = devp->vfp; /* vtype = simple_strtol(type, NULL, 10); */ - if (kstrtol(type, 10, &val) < 0) + + if (kstrtol(type, 10, &val) == 0) + vtype = val; + else return; - vtype = val; if (!devp->curr_wr_vfe) { devp->curr_wr_vfe = provider_vf_get(devp->vfp); if (!devp->curr_wr_vfe) { @@ -328,47 +588,183 @@ static void vdin_write_mem(struct vdin_dev_s *devp, char *type, char *path) VIDTYPE_VIU_FIELD | VIDTYPE_VIU_422; if (vtype == 1) { devp->curr_wr_vfe->vf.type |= VIDTYPE_INTERLACE_TOP; - real_size = (devp->curr_wr_vfe->vf.width * - devp->curr_wr_vfe->vf.height); pr_info("current vframe type is top.\n"); } else if (vtype == 3) { devp->curr_wr_vfe->vf.type |= VIDTYPE_INTERLACE_BOTTOM; - real_size = (devp->curr_wr_vfe->vf.width * - devp->curr_wr_vfe->vf.height); pr_info("current vframe type is bottom.\n"); } else { - real_size = (devp->curr_wr_vfe->vf.width * - devp->curr_wr_vfe->vf.height<<1); + devp->curr_wr_vfe->vf.type |= VIDTYPE_PROGRESSIVE; + } + if (vtype == 6) { + devp->curr_wr_vfe->vf.bitdepth = BITDEPTH_Y10; + devp->curr_wr_vfe->vf.bitdepth |= FULL_PACK_422_MODE; + devp->curr_wr_vfe->vf.signal_type = 0x91000; + devp->curr_wr_vfe->vf.source_type = VFRAME_SOURCE_TYPE_HDMI; + } + if ((vtype == 7) || (vtype == 8)) { + devp->curr_wr_vfe->vf.type = 0x7000; + devp->curr_wr_vfe->vf.bitdepth = 0; + devp->curr_wr_vfe->vf.signal_type = 0x10100; + devp->curr_wr_vfe->vf.source_type = VFRAME_SOURCE_TYPE_HDMI; } addr = canvas_get_addr(devp->curr_wr_vfe->vf.canvas0Addr); /* dts = ioremap(canvas_get_addr(devp->curr_wr_vfe->vf.canvas0Addr), */ /* real_size); */ dts = phys_to_virt(addr); - size = vfs_read(filp, dts, real_size, &pos); - if (size < real_size) { - pr_info("%s read %u < %u error.\n", - __func__, size, real_size); - return; - } + size = vfs_read(filp, dts, devp->canvas_max_size, &pos); + pr_info("warning: %s read %u < %u\n", + __func__, size, devp->canvas_max_size); + vfs_fsync(filp, 0); iounmap(dts); filp_close(filp, NULL); set_fs(old_fs); + if (vtype == 8) { + old_fs = get_fs(); + set_fs(KERNEL_DS); + pr_info("md file path = %s\n", md_path); + md_flip = filp_open(md_path, O_RDONLY, 0); + if (IS_ERR(md_flip)) { + pr_info("read %s error.\n", md_path); + return; + } + index = devp->curr_wr_vfe->vf.index & 0xff; + if (index != 0xff && index >= 0 + && index < p->size) { + u8 *c = devp->vfp->dv_buf_ori[index]; + + pos = 0; + size = vfs_read(md_flip, + devp->vfp->dv_buf_ori[index], + 4096, &pos); + p->dv_buf_size[index] = size; + devp->vfp->dv_buf[index] = &c[0]; + } + vfs_fsync(md_flip, 0); + filp_close(md_flip, NULL); + set_fs(old_fs); + } + provider_vf_put(devp->curr_wr_vfe, devp->vfp); devp->curr_wr_vfe = NULL; vf_notify_receiver(devp->name, VFRAME_EVENT_PROVIDER_VFRAME_READY, NULL); } -#ifdef CONFIG_AMLOGIC_LOCAL_DIMMING +static void vdin_write_cont_mem(struct vdin_dev_s *devp, char *type, + char *path, char *num) +{ + unsigned int size = 0, i = 0; + struct file *filp = NULL; + loff_t pos = 0; + mm_segment_t old_fs; + void *dts = NULL; + long field_num; + unsigned long addr; + + /* vtype = simple_strtol(type, NULL, 10); */ + + if (kstrtol(num, 10, &field_num) < 0) + return; + + if (!devp->curr_wr_vfe) { + devp->curr_wr_vfe = provider_vf_get(devp->vfp); + if (!devp->curr_wr_vfe) { + pr_info("no buffer to write.\n"); + return; + } + } + old_fs = get_fs(); + set_fs(KERNEL_DS); + pr_info("bin file path = %s\n", path); + filp = filp_open(path, O_RDONLY, 0); + if (IS_ERR(filp)) { + pr_info("read %s error.\n", path); + return; + } + for (i = 0; i < field_num; i++) { + if (!devp->curr_wr_vfe) { + devp->curr_wr_vfe = provider_vf_get(devp->vfp); + if (!devp->curr_wr_vfe) { + pr_info("no buffer to write.\n"); + return; + } + } + if (!strcmp("top", type)) { + if (i%2 == 0) { + devp->curr_wr_vfe->vf.type |= + VIDTYPE_INTERLACE_TOP; + pr_info("current vframe type is top.\n"); + } else { + devp->curr_wr_vfe->vf.type |= + VIDTYPE_INTERLACE_BOTTOM; + pr_info("current vframe type is bottom.\n"); + } + } else if (!strcmp("bot", type)) { + if (i%2 == 1) { + devp->curr_wr_vfe->vf.type |= + VIDTYPE_INTERLACE_TOP; + pr_info("current vframe type is top.\n"); + } else { + devp->curr_wr_vfe->vf.type |= + VIDTYPE_INTERLACE_BOTTOM; + pr_info("current vframe type is bottom.\n"); + } + } else { + devp->curr_wr_vfe->vf.type |= VIDTYPE_PROGRESSIVE; + } + addr = canvas_get_addr(devp->curr_wr_vfe->vf.canvas0Addr); + /* real_size); */ + dts = phys_to_virt(addr); + size = vfs_read(filp, dts, devp->canvas_max_size, &pos); + if (size < devp->canvas_max_size) { + pr_info("%s read %u < %u error.\n", + __func__, size, devp->canvas_max_size); + return; + } + vfs_fsync(filp, 0); + provider_vf_put(devp->curr_wr_vfe, devp->vfp); + devp->curr_wr_vfe = NULL; + vf_notify_receiver(devp->name, + VFRAME_EVENT_PROVIDER_VFRAME_READY, NULL); + iounmap(dts); + } + filp_close(filp, NULL); + set_fs(old_fs); + +} + +static void dump_dolby_metadata(struct vdin_dev_s *devp) +{ + unsigned int i, j; + + pr_info("*****dolby_metadata(%d byte):*****\n", dolby_size_byte); + for (i = 0; i < devp->canvas_max_num; i++) { + pr_info("*****dolby_metadata(%d)[0x%x](%d byte):*****\n", + i, devp->vfp->dv_buf_mem[i], dolby_size_byte); + for (j = 0; j < dolby_size_byte; j++) { + if ((j % 16) == 0) + pr_info("\n"); + pr_info("0x%02x\t", *(devp->vfp->dv_buf_ori[i] + j)); + } + } +} +static void dump_dolby_buf_clean(struct vdin_dev_s *devp) +{ + unsigned int i; + + for (i = 0; i < devp->canvas_max_num; i++) + memset(devp->vfp->dv_buf_ori[i], 0, dolby_size_byte); +} +#ifdef CONFIG_AML_LOCAL_DIMMING static void vdin_dump_histgram_ldim(struct vdin_dev_s *devp, unsigned int hnum, unsigned int vnum) { uint i, j; unsigned int local_ldim_max[100] = {0}; - /* memcpy(&local_ldim_max[0], &vdin_ldim_max_global[0], - * 100*sizeof(unsigned int)); + /*memcpy(&local_ldim_max[0], &vdin_ldim_max_global[0], + *100*sizeof(unsigned int)); */ pr_info("%s:\n", __func__); for (i = 0; i < hnum; i++) { @@ -383,20 +779,20 @@ static void vdin_dump_histgram_ldim(struct vdin_dev_s *devp, #endif /* - * 1.show the current frame rate - * echo fps >/sys/class/vdin/vdinx/attr - * 2.dump the data from vdin memory - * echo capture dir >/sys/class/vdin/vdinx/attr - * 3.start the vdin hardware - * echo tvstart/v4l2start port fmt_id/resolution(width height frame_rate) >dir - * 4.freeze the vdin buffer - * echo freeze/unfreeze >/sys/class/vdin/vdinx/attr - * 5.enable vdin0-nr path or vdin0-mem - * echo output2nr >/sys/class/vdin/vdin0/attr - * echo output2mem >/sys/class/vdin/vdin0/attr - * 6.modify for vdin fmt & color fmt conversion - * echo conversion w h cfmt >/sys/class/vdin/vdin0/attr - */ +* 1.show the current frame rate +* echo fps >/sys/class/vdin/vdinx/attr +* 2.dump the data from vdin memory +* echo capture dir >/sys/class/vdin/vdinx/attr +* 3.start the vdin hardware +* echo tvstart/v4l2start port fmt_id/resolution(width height frame_rate) >dir +* 4.freeze the vdin buffer +* echo freeze/unfreeze >/sys/class/vdin/vdinx/attr +* 5.enable vdin0-nr path or vdin0-mem +* echo output2nr >/sys/class/vdin/vdin0/attr +* echo output2mem >/sys/class/vdin/vdin0/attr +* 6.modify for vdin fmt & color fmt conversion +* echo conversion w h cfmt >/sys/class/vdin/vdin0/attr +*/ static ssize_t vdin_attr_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t len) @@ -404,15 +800,14 @@ static ssize_t vdin_attr_store(struct device *dev, unsigned int fps = 0; char ret = 0, *buf_orig, *parm[47] = {NULL}; struct vdin_dev_s *devp; - long val; unsigned int time_start, time_end, time_delta; + long val = 0; if (!buf) return len; buf_orig = kstrdup(buf, GFP_KERNEL); - /* pr_info(KERN_INFO "input cmd : %s",buf_orig); */ devp = dev_get_drvdata(dev); - parse_param(buf_orig, (char **)&parm); + vdin_parse_param(buf_orig, (char **)&parm); if (!strncmp(parm[0], "fps", 3)) { if (devp->cycle) @@ -422,32 +817,31 @@ static ssize_t vdin_attr_store(struct device *dev, pr_info("hdmirx: %u f/s\n", devp->parm.info.fps); } else if (!strcmp(parm[0], "capture")) { if (parm[3] != NULL) { - unsigned int start, offset; + unsigned int start = 0, offset = 0; - /* start = simple_strtol(parm[2], NULL, 16); */ - /* offset = simple_strtol(parm[3], NULL, 16); */ - - if (kstrtol(parm[2], 16, &val) < 0) { - kfree(buf_orig); - return -EINVAL; - } - start = val; - if (kstrtol(parm[3], 16, &val) < 0) { - kfree(buf_orig); - return -EINVAL; - } - offset = val; + if (kstrtol(parm[2], 16, &val) == 0) + start = val; + if (kstrtol(parm[3], 16, &val) == 0) + offset = val; dump_other_mem(parm[1], start, offset); + } else if (parm[2] != NULL) { + unsigned int buf_num = 0; + + if (kstrtol(parm[2], 10, &val) == 0) + buf_num = val; + vdin_dump_one_buf_mem(parm[1], devp, buf_num); } else if (parm[1] != NULL) { vdin_dump_mem(parm[1], devp); } } else if (!strcmp(parm[0], "tvstart")) { - unsigned int port, fmt; + unsigned int port = 0, fmt = 0; - /* port = simple_strtol(parm[1], NULL, 10); */ - if (kstrtol(parm[1], 16, &val) < 0) - return -EINVAL; - port = val; + if (!parm[2]) { + kfree(buf_orig); + return len; + } + if (kstrtol(parm[1], 16, &val) == 0) + port = val; switch (port) { case 0:/* HDMI0 */ port = TVIN_PORT_HDMI0; @@ -483,12 +877,8 @@ static ssize_t vdin_attr_store(struct device *dev, port = TVIN_PORT_CVBS0; break; } - /* fmt = simple_strtol(parm[2], NULL, 16); */ - if (kstrtol(parm[2], 16, &val) < 0) { - kfree(buf_orig); - return -EINVAL; - } - fmt = val; + if (kstrtol(parm[2], 16, &val) == 0) + fmt = val; /* devp->flags |= VDIN_FLAG_FS_OPENED; */ /* request irq */ @@ -498,8 +888,10 @@ static ssize_t vdin_attr_store(struct device *dev, ret = request_irq(devp->irq, vdin_isr, IRQF_SHARED, devp->irq_name, (void *)devp); - /*disable irq until vdin is configured completely*/ + /*disable irq until vdin is configured completely*/ disable_irq_nosync(devp->irq); + /*init queue*/ + init_waitqueue_head(&devp->queue); /* remove the hardware limit to vertical [0-max]*/ /* WRITE_VCBUS_REG(VPP_PREBLEND_VD1_V_START_END, 0x00000fff); */ /* pr_info("open device %s ok\n", dev_name(devp->dev)); */ @@ -532,7 +924,7 @@ start_chk: (time_delta <= 5000)) goto start_chk; - pr_info(" status: %s, fmt: %s\n", + pr_info("status: %s, fmt: %s\n", tvin_sig_status_str(devp->parm.info.status), tvin_sig_fmt_str(devp->parm.info.fmt)); if (devp->parm.info.fmt != TVIN_SIG_FMT_NULL) @@ -561,9 +953,9 @@ start_chk: /* WRITE_VCBUS_REG(VPP_PREBLEND_VD1_V_START_END, 0x00000437); */ } else if (!strcmp(parm[0], "v4l2stop")) { stop_tvin_service(devp->index); + devp->flags &= (~VDIN_FLAG_V4L2_DEBUG); } else if (!strcmp(parm[0], "v4l2start")) { struct vdin_parm_s param; - if (!parm[4]) { pr_err("usage: echo v4l2start port width height"); pr_err("fps cfmt > /sys/class/vdin/vdinx/attr.\n"); @@ -588,111 +980,61 @@ start_chk: pr_info(" port is TVIN_PORT_ISP\n"); } /*parse the resolution*/ - /* param.h_active = simple_strtol(parm[2], NULL, 10); */ - /* param.v_active = simple_strtol(parm[3], NULL, 10); */ - /* param.frame_rate = simple_strtol(parm[4], NULL, 10); */ - if (kstrtol(parm[2], 10, &val) < 0) { - kfree(buf_orig); - return -EINVAL; - } - param.h_active = val; - if (kstrtol(parm[3], 10, &val) < 0) { - kfree(buf_orig); - return -EINVAL; - } - param.v_active = val; - if (kstrtol(parm[4], 10, &val) < 0) { - kfree(buf_orig); - return -EINVAL; - } - param.frame_rate = val; + if (kstrtol(parm[2], 10, &val) == 0) + param.h_active = val; + if (kstrtol(parm[3], 10, &val) == 0) + param.v_active = val; + if (kstrtol(parm[4], 10, &val) == 0) + param.frame_rate = val; pr_info(" hactive:%d,vactive:%d, rate:%d\n", param.h_active, param.v_active, param.frame_rate); if (!parm[5]) param.cfmt = TVIN_YUV422; - else { - /* param.cfmt = simple_strtol(parm[5], NULL, 10); */ - if (kstrtol(parm[5], 10, &val) < 0) { - kfree(buf_orig); - return -EINVAL; - } + else if (kstrtol(parm[5], 10, &val) == 0) param.cfmt = val; - } pr_info(" cfmt:%d\n", param.cfmt); if (!parm[6]) param.dfmt = TVIN_YUV422; - else { - /* param.dfmt = simple_strtol(parm[6], NULL, 10); */ - if (kstrtol(parm[6], 10, &val) < 0) { - kfree(buf_orig); - return -EINVAL; - } + else if (kstrtol(parm[6], 10, &val) == 0) param.dfmt = val; - } pr_info(" dfmt:%d\n", param.dfmt); if (!parm[7]) param.scan_mode = TVIN_SCAN_MODE_PROGRESSIVE; - else { - /* param.scan_mode = - * simple_strtol(parm[7], NULL, 10); - */ - if (kstrtol(parm[7], 10, &val) < 0) { - kfree(buf_orig); - return -EINVAL; - } + else if (kstrtol(parm[7], 10, &val) == 0) param.scan_mode = val; - } pr_info(" scan_mode:%d\n", param.scan_mode); param.fmt = TVIN_SIG_FMT_MAX; + devp->flags |= VDIN_FLAG_V4L2_DEBUG; /* param.scan_mode = TVIN_SCAN_MODE_PROGRESSIVE; */ /*start the vdin hardware*/ start_tvin_service(devp->index, ¶m); } else if (!strcmp(parm[0], "disablesm")) del_timer_sync(&devp->timer); else if (!strcmp(parm[0], "freeze")) { - if (!(devp->flags & VDIN_FLAG_DEC_STARTED)) { - kfree(buf_orig); - return len; - } - if (devp->fmt_info_p->scan_mode == TVIN_SCAN_MODE_PROGRESSIVE) + if (!(devp->flags & VDIN_FLAG_DEC_STARTED)) + pr_info("vdin not started,can't do freeze!!!\n"); + else if (devp->fmt_info_p->scan_mode == + TVIN_SCAN_MODE_PROGRESSIVE) vdin_vf_freeze(devp->vfp, 1); else vdin_vf_freeze(devp->vfp, 2); } else if (!strcmp(parm[0], "unfreeze")) { - if (!(devp->flags & VDIN_FLAG_DEC_STARTED)) { - kfree(buf_orig); - return len; - } - vdin_vf_unfreeze(devp->vfp); + if (!(devp->flags & VDIN_FLAG_DEC_STARTED)) + pr_info("vdin not started,can't do unfreeze!!!\n"); + else + vdin_vf_unfreeze(devp->vfp); } else if (!strcmp(parm[0], "conversion")) { - if (parm[1] && - parm[2] && - parm[3]) { - /* devp->debug.scaler4w = */ - /* simple_strtoul(parm[1], NULL, 10); */ - /* devp->debug.scaler4h = */ - /* simple_strtoul(parm[2], NULL, 10); */ - /* devp->debug.dest_cfmt = */ - /* simple_strtoul(parm[3], NULL, 10); */ - if (kstrtoul(parm[1], 10, &val) < 0) { - kfree(buf_orig); - return -EINVAL; - } - devp->debug.scaler4w = val; - if (kstrtoul(parm[2], 10, &val) < 0) { - kfree(buf_orig); - return -EINVAL; - } - devp->debug.scaler4h = val; - if (kstrtoul(parm[3], 10, &val) < 0) { - kfree(buf_orig); - return -EINVAL; - } - devp->debug.dest_cfmt = val; + if (parm[1] && parm[2] && parm[3]) { + if (kstrtoul(parm[1], 10, &val) == 0) + devp->debug.scaler4w = val; + if (kstrtoul(parm[2], 10, &val) == 0) + devp->debug.scaler4h = val; + if (kstrtoul(parm[3], 10, &val) == 0) + devp->debug.dest_cfmt = val; devp->flags |= VDIN_FLAG_MANUAL_CONVERSION; pr_info("enable manual conversion w = %u h = %u ", @@ -710,30 +1052,33 @@ start_chk: vdin_dump_state(devp); } else if (!strcmp(parm[0], "histgram")) { vdin_dump_histgram(devp); - } -#ifdef CONFIG_AMLOGIC_LOCAL_DIMMING - else if (!strcmp(parm[0], "histgram_ldim")) { +#ifdef CONFIG_AML_LOCAL_DIMMING + } else if (!strcmp(parm[0], "histgram_ldim")) { unsigned int hnum, vnum; - if (parm[1] && parm[2]) { hnum = kstrtoul(parm[1], 10, (unsigned long *)&hnum); vnum = kstrtoul(parm[2], 10, (unsigned long *)&vnum); - } - else{ + } else { hnum = 8; vnum = 2; - } - vdin_dump_histgram_ldim(devp, hnum, vnum); } + vdin_dump_histgram_ldim(devp, hnum, vnum); #endif - else if (!strcmp(parm[0], "force_recycle")) { + } else if (!strcmp(parm[0], "force_recycle")) { devp->flags |= VDIN_FLAG_FORCE_RECYCLE; } else if (!strcmp(parm[0], "read_pic")) { - vdin_write_mem(devp, parm[1], parm[2]); + if (parm[1] && parm[2]) + vdin_write_mem(devp, parm[1], parm[2], parm[3]); + else + pr_err("miss parameters .\n"); + } else if (!strcmp(parm[0], "read_bin")) { + if (parm[1] && parm[2] && parm[3]) + vdin_write_cont_mem(devp, parm[1], parm[2], parm[3]); + else + pr_err("miss parameters .\n"); } else if (!strcmp(parm[0], "dump_reg")) { unsigned int reg; unsigned int offset = devp->addr_offset; - pr_info("vdin%d addr offset:0x%x regs start----\n", devp->index, offset); for (reg = VDIN_SCALE_COEF_IDX; reg <= 0x1273; reg++) @@ -742,78 +1087,67 @@ start_chk: (reg+offset), rd(offset, reg)); pr_info("vdin%d regs end----\n", devp->index); } else if (!strcmp(parm[0], "rgb_xy")) { - unsigned int x, y; + unsigned int x = 0, y = 0; - if (kstrtoul(parm[1], 10, &val) < 0) { - kfree(buf_orig); - return -EINVAL; - } - x = val; - if (kstrtoul(parm[2], 10, &val) < 0) { - kfree(buf_orig); - return -EINVAL; - } - y = val; - vdin_set_prob_xy(devp->addr_offset, x, y, devp); + if (parm[1] && parm[2]) { + if (kstrtoul(parm[1], 10, &val) == 0) + x = val; + if (kstrtoul(parm[2], 10, &val) == 0) + y = val; + vdin_set_prob_xy(devp->addr_offset, x, y, devp); + } else + pr_err("miss parameters .\n"); } else if (!strcmp(parm[0], "rgb_info")) { unsigned int r, g, b; - vdin_get_prob_rgb(devp->addr_offset, &r, &g, &b); pr_info("rgb_info-->r:%d,g:%d,b:%d\n", r, g, b); } else if (!strcmp(parm[0], "mpeg2vdin")) { - if (kstrtoul(parm[1], 10, &val) < 0) { - kfree(buf_orig); - return -EINVAL; - } - devp->h_active = val; - if (kstrtoul(parm[2], 10, &val) < 0) { - kfree(buf_orig); - return -EINVAL; - } - devp->v_active = val; - vdin_set_mpegin(devp); - pr_info("mpeg2vdin:h_active:%d,v_active:%d\n", + if (parm[1] && parm[2]) { + if (kstrtoul(parm[1], 10, &val) == 0) + devp->h_active = val; + if (kstrtoul(parm[2], 10, &val) == 0) + devp->v_active = val; + vdin_set_mpegin(devp); + pr_info("mpeg2vdin:h_active:%d,v_active:%d\n", devp->h_active, devp->v_active); + } else + pr_err("miss parameters .\n"); } else if (!strcmp(parm[0], "yuv_rgb_info")) { unsigned int rgb_yuv0, rgb_yuv1, rgb_yuv2; - vdin_get_vdin_yuv_rgb_mat0(devp->addr_offset, &rgb_yuv0, &rgb_yuv1, &rgb_yuv2); pr_info("rgb_yuv0 :%d, rgb_yuv1 :%d , rgb_yuv2 :%d\n", rgb_yuv0, rgb_yuv1, rgb_yuv2); } else if (!strcmp(parm[0], "mat0_xy")) { - unsigned int x, y; + unsigned int x = 0, y = 0; - if (kstrtoul(parm[1], 10, &val) < 0) { - kfree(buf_orig); - return -EINVAL; - } - x = val; - if (kstrtoul(parm[2], 10, &val) < 0) { - kfree(buf_orig); - return -EINVAL; - } - y = val; - pr_info("pos x :%d, pos y :%d\n", x, y); - vdin_set_prob_matrix0_xy(devp->addr_offset, x, y, devp); + if (parm[1] && parm[2]) { + if (kstrtoul(parm[1], 10, &val) == 0) + x = val; + if (kstrtoul(parm[2], 10, &val) == 0) + y = val; + pr_info("pos x :%d, pos y :%d\n", x, y); + vdin_set_prob_matrix0_xy(devp->addr_offset, x, y, devp); + } else + pr_err("miss parameters .\n"); } else if (!strcmp(parm[0], "mat0_set")) { - unsigned int x; - if (kstrtoul(parm[1], 10, &val) < 0) { - kfree(buf_orig); - return -EINVAL; - } - x = val; + unsigned int x = 0; + + if (!parm[1]) + pr_err("miss parameters .\n"); + if (kstrtoul(parm[1], 10, &val) == 0) + x = val; pr_info("matrix set : %d\n", x); vdin_set_before_after_mat0(devp->addr_offset, x, devp); } else if (!strcmp(parm[0], "hdr")) { int i; struct vframe_master_display_colour_s *prop; - prop = &devp->curr_wr_vfe->vf.prop.master_display_colour; pr_info("present_flag: %d\n", prop->present_flag); for (i = 0; i < 6; i++) pr_info("primaries %d: %#x\n", i, *(((u32 *)(prop->primaries)) + i)); + pr_info("white point x: %#x, y: %#x\n", *((u32 *)(prop->white_point)), *((u32 *)(prop->white_point) + 1)); @@ -822,7 +1156,6 @@ start_chk: *(((u32 *)(prop->luminance)) + 1)); } else if (!strcmp(parm[0], "snowon")) { unsigned int fmt; - fmt = TVIN_SIG_FMT_CVBS_NTSC_M; devp->flags |= VDIN_FLAG_SNOW_FLAG; devp->flags |= VDIN_FLAG_SM_DISABLE; @@ -837,18 +1170,14 @@ start_chk: pr_info("TVIN_IOC_START_DEC port TVIN_PORT_CVBS3, decode started ok\n\n"); } devp->flags &= (~VDIN_FLAG_SM_DISABLE); - #ifdef CONFIG_AMLOGIC_MEDIA_TVAFE - tvafe_snow_config(1); - tvafe_snow_config_clamp(1); - #endif + /*tvafe_snow_config(1);*/ + /*tvafe_snow_config_clamp(1);*/ pr_info("snowon config done!!\n"); } else if (!strcmp(parm[0], "snowoff")) { devp->flags &= (~VDIN_FLAG_SNOW_FLAG); devp->flags |= VDIN_FLAG_SM_DISABLE; - #ifdef CONFIG_AMLOGIC_MEDIA_TVAFE - tvafe_snow_config(0); - tvafe_snow_config_clamp(0); - #endif + /*tvafe_snow_config(0);*/ + /*tvafe_snow_config_clamp(0);*/ /* if fmt change, need restart dec vdin */ if ((devp->parm.info.fmt != TVIN_SIG_FMT_CVBS_NTSC_M) && (devp->parm.info.fmt != TVIN_SIG_FMT_NULL)) { @@ -879,20 +1208,20 @@ start_chk: pr_info("snowoff config done!!\n"); } else if (!strcmp(parm[0], "vf_reg")) { if ((devp->flags & VDIN_FLAG_DEC_REGED) - == VDIN_FLAG_DEC_REGED) { + == VDIN_FLAG_DEC_REGED) pr_err("vf_reg(%d) decoder is registered already\n", devp->index); - } else { + else { devp->flags |= VDIN_FLAG_DEC_REGED; vdin_vf_reg(devp); pr_info("vf_reg(%d) ok\n\n", devp->index); } } else if (!strcmp(parm[0], "vf_unreg")) { if ((devp->flags & VDIN_FLAG_DEC_REGED) - != VDIN_FLAG_DEC_REGED) { + != VDIN_FLAG_DEC_REGED) pr_err("vf_unreg(%d) decoder isn't registered\n", devp->index); - } else { + else { devp->flags &= (~VDIN_FLAG_DEC_REGED); vdin_vf_unreg(devp); pr_info("vf_unreg(%d) ok\n\n", devp->index); @@ -904,21 +1233,197 @@ start_chk: vdin_resume_dec(devp); pr_info("resume_dec(%d) ok\n\n", devp->index); } else if (!strcmp(parm[0], "color_depth")) { - if (kstrtoul(parm[1], 10, &val) < 0) { - kfree(buf_orig); - return -EINVAL; + if (!parm[1]) + pr_err("miss parameters .\n"); + else if (kstrtoul(parm[1], 10, &val) == 0) { + devp->color_depth_config = val; + pr_info("color_depth(%d):%d\n\n", devp->index, + devp->color_depth_config); + } + } else if (!strcmp(parm[0], "color_depth_support")) { + if (!parm[1]) + pr_err("miss parameters .\n"); + else if (kstrtoul(parm[1], 16, &val) == 0) { + devp->color_depth_support = val; + pr_info("color_depth_support(%d):%d\n\n", devp->index, + devp->color_depth_support); } - devp->color_depth_config = val; - pr_info("color_depth(%d):%d\n\n", devp->index, - devp->color_depth_config); } else if (!strcmp(parm[0], "color_depth_mode")) { - if (kstrtoul(parm[1], 10, &val) < 0) { - kfree(buf_orig); - return -EINVAL; + if (!parm[1]) + pr_err("miss parameters .\n"); + else if (kstrtoul(parm[1], 10, &val) == 0) { + devp->color_depth_mode = val; + pr_info("color_depth_mode(%d):%d\n\n", devp->index, + devp->color_depth_mode); + } + } else if (!strcmp(parm[0], "auto_cutwindow_en")) { + if (!parm[1]) + pr_err("miss parameters .\n"); + else if (kstrtoul(parm[1], 10, &val) == 0) { + devp->auto_cutwindow_en = val; + pr_info("auto_cutwindow_en(%d):%d\n\n", devp->index, + devp->auto_cutwindow_en); + } + } else if (!strcmp(parm[0], "auto_ratio_en")) { + if (!parm[1]) + pr_err("miss parameters .\n"); + else if (kstrtoul(parm[1], 10, &val) == 0) { + devp->auto_ratio_en = val; + pr_info("auto_ratio_en(%d):%d\n\n", devp->index, + devp->auto_ratio_en); + } + } else if (!strcmp(parm[0], "dolby_config")) { + vdin_dolby_config(devp); + pr_info("dolby_config done\n"); + } else if (!strcmp(parm[0], "metadata")) { + dump_dolby_metadata(devp); + pr_info("dolby_config done\n"); + } else if (!strcmp(parm[0], "clean_dv")) { + dump_dolby_buf_clean(devp); + pr_info("clean dolby vision mem done\n"); + } else if (!strcmp(parm[0], "dv_debug")) { + vdin_dv_debug(devp); + } else if (!strcmp(parm[0], "channel_order_config")) { + unsigned int c0, c1, c2; + + if (!parm[3]) + pr_info("miss parameters\n"); + else { + c0 = c1 = c2 = 0; + if (kstrtoul(parm[1], 10, &val) == 0) + c0 = val; + if (kstrtoul(parm[2], 10, &val) == 0) + c1 = val; + if (kstrtoul(parm[3], 10, &val) == 0) + c2 = val; + vdin_channel_order_config(devp->addr_offset, + c0, c1, c2); + } + } else if (!strcmp(parm[0], "channel_order_status")) + vdin_channel_order_status(devp->addr_offset); + else if (!strcmp(parm[0], "open_port")) { + if (!parm[1]) + pr_err("miss parameters .\n"); + else if (kstrtoul(parm[1], 16, &val) == 0) { + devp->parm.index = 0; + devp->parm.port = val; + devp->unstable_flag = false; + ret = vdin_open_fe(devp->parm.port, + devp->parm.index, devp); + if (ret) { + pr_err("TVIN_IOC_OPEN(%d) failed to open port 0x%x\n", + devp->parm.index, devp->parm.port); + } else { + devp->flags |= VDIN_FLAG_DEC_OPENED; + pr_info("TVIN_IOC_OPEN(%d) port %s opened ok\n\n", + devp->parm.index, + tvin_port_str(devp->parm.port)); + } + } + } else if (!strcmp(parm[0], "close_port")) { + enum tvin_port_e port = devp->parm.port; + + if (!(devp->flags & VDIN_FLAG_DEC_OPENED)) + pr_err("TVIN_IOC_CLOSE(%d) you have not opened port\n", + devp->index); + else { + vdin_close_fe(devp); + devp->flags &= (~VDIN_FLAG_DEC_OPENED); + pr_info("TVIN_IOC_CLOSE(%d) port %s closed ok\n\n", + devp->parm.index, tvin_port_str(port)); + } + } else if (!strcmp(parm[0], "prehsc_en")) { + if (!parm[1]) + pr_err("miss parameters .\n"); + else if (kstrtoul(parm[1], 10, &val) == 0) { + devp->prehsc_en = val; + pr_info("prehsc_en(%d):%d\n\n", devp->index, + devp->prehsc_en); + } + } else if (!strcmp(parm[0], "vshrk_en")) { + if (!parm[1]) + pr_err("miss parameters .\n"); + else if (kstrtoul(parm[1], 10, &val) == 0) { + devp->vshrk_en = val; + pr_info("vshrk_en(%d):%d\n\n", devp->index, + devp->vshrk_en); + } + } else if (!strcmp(parm[0], "cma_mem_mode")) { + if (!parm[1]) + pr_err("miss parameters .\n"); + else if (kstrtoul(parm[1], 10, &val) == 0) { + devp->cma_mem_mode = val; + pr_info("cma_mem_mode(%d):%d\n\n", devp->index, + devp->cma_mem_mode); + } + } else if (!strcmp(parm[0], "black_bar_enable")) { + if (!parm[1]) + pr_err("miss parameters .\n"); + else if (kstrtoul(parm[1], 10, &val) == 0) { + devp->black_bar_enable = val; + pr_info("black_bar_enable(%d):%d\n\n", devp->index, + devp->black_bar_enable); + } + } else if (!strcmp(parm[0], "hist_bar_enable")) { + if (!parm[1]) + pr_err("miss parameters .\n"); + else if (kstrtoul(parm[1], 10, &val) == 0) { + devp->hist_bar_enable = val; + pr_info("hist_bar_enable(%d):%d\n\n", devp->index, + devp->hist_bar_enable); + } + } else if (!strcmp(parm[0], "use_frame_rate")) { + if (!parm[1]) + pr_err("miss parameters .\n"); + else if (kstrtoul(parm[1], 10, &val) == 0) { + devp->use_frame_rate = val; + pr_info("use_frame_rate(%d):%d\n\n", devp->index, + devp->use_frame_rate); + } + } else if (!strcmp(parm[0], "dolby_input")) { + if (!parm[1]) + pr_err("miss parameters .\n"); + else if (kstrtoul(parm[1], 10, &val) == 0) { + devp->dv.dolby_input = val; + pr_info("dolby_input(%d):%d\n\n", devp->index, + devp->dv.dolby_input); + } + } else if (!strcmp(parm[0], "rdma_enable")) { + if (!parm[1]) + pr_err("miss parameters .\n"); + else if (kstrtoul(parm[1], 10, &val) == 0) { + devp->rdma_enable = val; + pr_info("rdma_enable (%d):%d\n", devp->index, + devp->rdma_enable); + } + } else if (!strcmp(parm[0], "urgent_en")) { + if (!parm[1]) + pr_err("miss parameters .\n"); + else if (kstrtoul(parm[1], 10, &val) == 0) { + devp->urgent_en = val; + pr_info("urgent_en (%d):%d\n", devp->index, + devp->urgent_en); + } + } else if (!strcmp(parm[0], "irq_flag")) { + if (!parm[1]) + pr_err("miss parameters .\n"); + else if (kstrtoul(parm[1], 10, &val) == 0) { + devp->vdin_irq_flag = val; + pr_info("vdin(%d) irq_flag: %d\n", devp->index, + devp->vdin_irq_flag); + } + } else if (!strcmp(parm[0], "skip_vf_num")) { + if (!parm[1]) + pr_err("miss parameters .\n"); + else if ((kstrtoul(parm[1], 10, &val) == 0) && (devp->vfp)) { + devp->vfp->skip_vf_num = val; + if (val == 0) + memset(devp->vfp->disp_mode, 0, + (sizeof(enum vframe_disp_mode_e) * + VFRAME_DISP_MAX_NUM)); + pr_info("vframe_skip(%d):%d\n\n", devp->index, + devp->vfp->skip_vf_num); } - devp->color_depth_mode = val; - pr_info("color_depth_mode(%d):%d\n\n", devp->index, - devp->color_depth_mode); } else { pr_info("unknown command\n"); } @@ -949,94 +1454,54 @@ static ssize_t vdin_vf_log_store(struct device *dev, vf_log_print(devp->vfp); } else { pr_info("unknown command : %s\n" - "Usage:\n" - "a. show log message:\n" - "echo print > /sys/class/vdin/vdin0/vf_log\n" - "b. restart log message:\n" - "echo start > /sys/class/vdin/vdin0/vf_log\n" - "c. show log records\n" - "cat > /sys/class/vdin/vdin0/vf_log\n", buf); + "Usage:\n" + "a. show log message:\n" + "echo print > / sys/class/vdin/vdin0/vf_log\n" + "b. restart log message:\n" + "echo start > / sys/class/vdin/vdin0/vf_log\n" + "c. show log records\n" + "cat > / sys/class/vdin/vdin0/vf_log\n", buf); } return count; } /* - * 1. show log length. - * cat /sys/class/vdin/vdin0/vf_log - * cat /sys/class/vdin/vdin1/vf_log - * 2. clear log buffer and start log. - * echo start > /sys/class/vdin/vdin0/vf_log - * echo start > /sys/class/vdin/vdin1/vf_log - * 3. print log - * echo print > /sys/class/vdin/vdin0/vf_log - * echo print > /sys/class/vdin/vdin1/vf_log - */ + 1. show log length. + cat /sys/class/vdin/vdin0/vf_log + cat /sys/class/vdin/vdin1/vf_log + 2. clear log buffer and start log. + echo start > /sys/class/vdin/vdin0/vf_log + echo start > /sys/class/vdin/vdin1/vf_log + 3. print log + echo print > /sys/class/vdin/vdin0/vf_log + echo print > /sys/class/vdin/vdin1/vf_log +*/ static DEVICE_ATTR(vf_log, 0664, vdin_vf_log_show, vdin_vf_log_store); #endif /* VF_LOG_EN */ -#if 0 -static ssize_t vdin_debug_for_isp_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - int len = 0; - - return len; -} - -static ssize_t vdin_debug_for_isp_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count) -{ - char *buf_orig, *parm[6] = {NULL}; - cam_parameter_t tmp_isp; - struct vdin_dev_s *devp; - - if (!buf) - return count; - buf_orig = kstrdup(buf, GFP_KERNEL); - devp = dev_get_drvdata(dev); - parse_param(buf_orig, (char **)&parm); - - if (!strcmp(parm[0], "bypass_isp")) { - vdin_bypass_isp(devp->addr_offset); - tmp_isp.cam_command = CMD_ISP_BYPASS; - if (devp->frontend->dec_ops->ioctl) - devp->frontend->dec_ops->ioctl(devp->frontend, - (void *)&tmp_isp); - pr_info("vdin bypass isp for raw data.\n"); - } -return count; -} - -static DEVICE_ATTR(debug_for_isp, 0664, - vdin_debug_for_isp_show, vdin_debug_for_isp_store); -#endif - - #ifdef ISR_LOG_EN static ssize_t vdin_isr_log_show(struct device *dev, struct device_attribute *attr, char *buf) { u32 len = 0; struct vdin_dev_s *vdevp; - vdevp = dev_get_drvdata(dev); len += sprintf(buf + len, "%d of %d\n", vdevp->vfp->isr_log.log_cur, ISR_LOG_LEN); return len; } /* - *1. show isr log length. - *cat /sys/class/vdin/vdin0/vf_log - *2. clear isr log buffer and start log. - *echo start > /sys/class/vdin/vdinx/isr_log - *3. print isr log - *echo print > /sys/class/vdin/vdinx/isr_log - */ +*1. show isr log length. +*cat /sys/class/vdin/vdin0/vf_log +*2. clear isr log buffer and start log. +*echo start > /sys/class/vdin/vdinx/isr_log +*3. print isr log +*echo print > /sys/class/vdin/vdinx/isr_log +*/ static ssize_t vdin_isr_log_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct vdin_dev_s *vdevp; - vdevp = dev_get_drvdata(dev); if (!strncmp(buf, "start", 5)) isr_log_init(vdevp->vfp); @@ -1068,41 +1533,32 @@ struct device_attribute *attr, const char *buf, size_t count) struct vdin_dev_s *devp = dev_get_drvdata(dev); struct tvin_cutwin_s *crop = &devp->debug.cutwin; long val; + ssize_t ret_ext = count; if (!buf) return count; buf_orig = kstrdup(buf, GFP_KERNEL); - parse_param(buf_orig, parm); + vdin_parse_param(buf_orig, parm); - /* crop->hs = simple_strtol(parm[0], NULL, 10); */ - /* crop->he = simple_strtol(parm[1], NULL, 10); */ - /* crop->vs = simple_strtol(parm[2], NULL, 10); */ - /* crop->ve = simple_strtol(parm[3], NULL, 10); */ + if (!parm[3]) { + ret_ext = -EINVAL; + pr_info("miss param!!\n"); + } else { + if (kstrtol(parm[0], 10, &val) == 0) + crop->hs = val; + if (kstrtol(parm[1], 10, &val) == 0) + crop->he = val; + if (kstrtol(parm[2], 10, &val) == 0) + crop->vs = val; + if (kstrtol(parm[3], 10, &val) == 0) + crop->ve = val; + } + + kfree(buf_orig); - if (kstrtol(parm[0], 10, &val) < 0) { - kfree(buf_orig); - return -EINVAL; - } - crop->hs = val; - if (kstrtol(parm[1], 10, &val) < 0) { - kfree(buf_orig); - return -EINVAL; - } - crop->he = val; - if (kstrtol(parm[2], 10, &val) < 0) { - kfree(buf_orig); - return -EINVAL; - } - crop->vs = val; - if (kstrtol(parm[3], 10, &val) < 0) { - kfree(buf_orig); - return -EINVAL; - } - crop->ve = val; pr_info("hs_offset %u, he_offset %u, vs_offset %u, ve_offset %u.\n", crop->hs, crop->he, crop->vs, crop->ve); - kfree(buf_orig); - return count; + return ret_ext; } static DEVICE_ATTR(crop, 0664, vdin_crop_show, vdin_crop_store); @@ -1139,15 +1595,17 @@ static ssize_t vdin_cm2_store(struct device *dev, { struct vdin_dev_s *devp; int n = 0; - char delim1[2] = " "; - char delim2[2] = "\n"; char *buf_orig, *ps, *token; char *parm[7]; - u32 addr; + u32 addr = 0; int data[5] = {0}; unsigned int addr_port = VDIN_CHROMA_ADDR_PORT; unsigned int data_port = VDIN_CHROMA_DATA_PORT; long val; + char delim1[2] = " "; + char delim2[2] = "\n"; + + strcat(delim1, delim2); devp = dev_get_drvdata(dev); if (devp->addr_offset != 0) { @@ -1156,7 +1614,6 @@ static ssize_t vdin_cm2_store(struct device *dev, } buf_orig = kstrdup(buffer, GFP_KERNEL); ps = buf_orig; - strcat(delim1, delim2); while (1) { token = strsep(&ps, delim1); if (token == NULL) @@ -1166,7 +1623,7 @@ static ssize_t vdin_cm2_store(struct device *dev, parm[n++] = token; } if (n == 0) { - pr_info("parm[] not initialized.\n"); + pr_info("parm not initialized.\n"); kfree(buf_orig); return count; } @@ -1184,36 +1641,16 @@ static ssize_t vdin_cm2_store(struct device *dev, } addr = val; addr = addr - addr%8; - /* data[0] = simple_strtol(parm[2], NULL, 16); */ - /* data[1] = simple_strtol(parm[3], NULL, 16); */ - /* data[2] = simple_strtol(parm[4], NULL, 16); */ - /* data[3] = simple_strtol(parm[5], NULL, 16); */ - /* data[4] = simple_strtol(parm[6], NULL, 16); */ - if (kstrtol(parm[2], 16, &val) < 0) { - kfree(buf_orig); - return -EINVAL; - } - data[0] = val; - if (kstrtol(parm[3], 16, &val) < 0) { - kfree(buf_orig); - return -EINVAL; - } - data[1] = val; - if (kstrtol(parm[4], 16, &val) < 0) { - kfree(buf_orig); - return -EINVAL; - } - data[2] = val; - if (kstrtol(parm[5], 16, &val) < 0) { - kfree(buf_orig); - return -EINVAL; - } - data[3] = val; - if (kstrtol(parm[6], 16, &val) < 0) { - kfree(buf_orig); - return -EINVAL; - } - data[4] = val; + if (kstrtol(parm[2], 16, &val) == 0) + data[0] = val; + if (kstrtol(parm[3], 16, &val) == 0) + data[1] = val; + if (kstrtol(parm[4], 16, &val) == 0) + data[2] = val; + if (kstrtol(parm[5], 16, &val) == 0) + data[3] = val; + if (kstrtol(parm[6], 16, &val) == 0) + data[4] = val; aml_write_vcbus(addr_port, addr); aml_write_vcbus(data_port, data[0]); aml_write_vcbus(addr_port, addr + 1); @@ -1233,12 +1670,8 @@ static ssize_t vdin_cm2_store(struct device *dev, kfree(buf_orig); return count; } - /* addr = simple_strtol(parm[1], NULL, 16); */ - if (kstrtol(parm[1], 16, &val) < 0) { - kfree(buf_orig); - return -EINVAL; - } - addr = val; + if (kstrtol(parm[1], 16, &val) == 0) + addr = val; addr = addr - addr%8; aml_write_vcbus(addr_port, addr); data[0] = aml_read_vcbus(data_port); @@ -1283,7 +1716,6 @@ static DEVICE_ATTR(cm2, 0644, vdin_cm2_show, vdin_cm2_store); int vdin_create_device_files(struct device *dev) { int ret = 0; - ret = device_create_file(dev, &dev_attr_sig_det); /* create sysfs attribute files */ #ifdef VF_LOG_EN @@ -1316,8 +1748,9 @@ void vdin_remove_device_files(struct device *dev) device_remove_file(dev, &dev_attr_crop); device_remove_file(dev, &dev_attr_sig_det); } -static int memp = MEMP_DCDR_WITHOUT_3D; +#ifdef DEBUG_SUPPORT +static int memp = MEMP_DCDR_WITHOUT_3D; static char *memp_str(int profile) { switch (profile) { @@ -1337,22 +1770,19 @@ static char *memp_str(int profile) return "unknown"; } } - /* - * cat /sys/class/vdin/memp - */ +* cat /sys/class/vdin/memp +*/ static ssize_t memp_show(struct class *class, struct class_attribute *attr, char *buf) { int len = 0; - len += sprintf(buf+len, "%d %s\n", memp, memp_str(memp)); return len; } - /* - * echo 0|1|2|3|4|5 > /sys/class/vdin/memp - */ +* echo 0|1|2|3|4|5 > /sys/class/vdin/memp +*/ static void memp_set(int type) { switch (type) { @@ -1485,11 +1915,11 @@ static ssize_t memp_store(struct class *class, /* int type = simple_strtol(buf, NULL, 10); */ long type; - if (kstrtol(buf, 10, &type) < 0) + if (kstrtol(buf, 10, &type) == 0) + memp_set(type); + else return -EINVAL; - memp_set(type); - return count; } @@ -1498,7 +1928,6 @@ static CLASS_ATTR(memp, 0644, memp_show, memp_store); int vdin_create_class_files(struct class *vdin_clsp) { int ret = 0; - ret = class_create_file(vdin_clsp, &class_attr_memp); return ret; } @@ -1507,3 +1936,4 @@ void vdin_remove_class_files(struct class *vdin_clsp) class_remove_file(vdin_clsp, &class_attr_memp); } +#endif diff --git a/drivers/amlogic/media/vin/tvin/vdin/vdin_drv.c b/drivers/amlogic/media/vin/tvin/vdin/vdin_drv.c index e311342f8282..68760d4daee4 100644 --- a/drivers/amlogic/media/vin/tvin/vdin/vdin_drv.c +++ b/drivers/amlogic/media/vin/tvin/vdin/vdin_drv.c @@ -31,10 +31,10 @@ #include #include #include +#include #include #include #include -/* #include */ #include #include #include @@ -45,8 +45,6 @@ #include #include /* Amlogic Headers */ -/* #include */ -/* #include */ #include #include #include @@ -54,12 +52,6 @@ #include #include #include -/* #include */ -/* #include */ -/* #include */ -/* #if MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON8 */ -/* #include */ -/* #endif */ /* Local Headers */ #include "../tvin_global.h" #include "../tvin_format_table.h" @@ -72,29 +64,19 @@ #include "vdin_vf.h" #include "vdin_canvas.h" - -#define VDIN_NAME "vdin" #define VDIN_DRV_NAME "vdin" -#define VDIN_MOD_NAME "vdin" #define VDIN_DEV_NAME "vdin" #define VDIN_CLS_NAME "vdin" #define PROVIDER_NAME "vdin" -#define SMOOTH_DEBUG - -#define VDIN_PUT_INTERVAL (HZ/100) /* 10ms, #define HZ 100 */ - -#define INVALID_VDIN_INPUT 0xffffffff - -#define VDIN0_ALLOC_SIZE SZ_64M +#define VDIN_PUT_INTERVAL (HZ/100) /* 10ms, #define HZ 100 */ static dev_t vdin_devno; static struct class *vdin_clsp; - static unsigned int vdin_addr_offset[VDIN_MAX_DEVS] = {0, 0x80}; -struct vdin_dev_s *vdin_devp[VDIN_MAX_DEVS]; -static int callmaster_status; - +static struct vdin_dev_s *vdin_devp[VDIN_MAX_DEVS]; +static unsigned long mem_start, mem_end; +static unsigned int use_reserved_mem; /* * canvas_config_mode * 0: canvas_config in driver probe @@ -102,28 +84,35 @@ static int callmaster_status; * 2: auto config */ static int canvas_config_mode = 2; +static bool work_mode_simple; +static int max_ignore_frames = 2; +static int ignore_frames; +static unsigned int dv_work_delby; +/* viu isr select: + * enable viu_hw_irq for the bandwidth is enough on gxbb/gxtvbb and laters ic + */ +static bool viu_hw_irq = 1; + +#ifdef DEBUG_SUPPORT module_param(canvas_config_mode, int, 0664); MODULE_PARM_DESC(canvas_config_mode, "canvas configure mode"); -static bool work_mode_simple; module_param(work_mode_simple, bool, 0664); MODULE_PARM_DESC(work_mode_simple, "enable/disable simple work mode"); -static char *first_field_type; -module_param(first_field_type, charp, 0664); -MODULE_PARM_DESC(first_field_type, "first field type in simple work mode"); - -static int max_ignore_frames = 2; module_param(max_ignore_frames, int, 0664); MODULE_PARM_DESC(max_ignore_frames, "ignore first frames"); -static int ignore_frames; module_param(ignore_frames, int, 0664); MODULE_PARM_DESC(ignore_frames, "ignore first frames"); -static int start_provider_delay; -module_param(start_provider_delay, int, 0664); -MODULE_PARM_DESC(start_provider_delay, "ignore first frames"); +module_param(dv_work_delby, uint, 0664); +MODULE_PARM_DESC(dv_work_delby, "dv_work_delby"); + +module_param(viu_hw_irq, bool, 0664); +MODULE_PARM_DESC(viu_hw_irq, "viu_hw_irq"); +#endif + static bool vdin_dbg_en; module_param(vdin_dbg_en, bool, 0664); MODULE_PARM_DESC(vdin_dbg_en, "enable/disable vdin debug information"); @@ -131,147 +120,30 @@ MODULE_PARM_DESC(vdin_dbg_en, "enable/disable vdin debug information"); static bool time_en; module_param(time_en, bool, 0664); MODULE_PARM_DESC(time_en, "enable/disable vdin debug information"); -static bool invert_top_bot; -module_param(invert_top_bot, bool, 0644); -MODULE_PARM_DESC(invert_top_bot, "invert field type top or bottom"); - /* - * the check flag in vdin_isr - * bit0:bypass stop check,bit1:bypass cyc check - * bit2:bypass vsync check,bit3:bypass vga check - */ +*the check flag in vdin_isr +*bit0:bypass stop check,bit1:bypass cyc check +*bit2:bypass vsync check,bit3:bypass vga check +*/ static unsigned int isr_flag; module_param(isr_flag, uint, 0664); MODULE_PARM_DESC(isr_flag, "flag which affect the skip field"); -static unsigned int irq_cnt; -module_param(irq_cnt, uint, 0664); -MODULE_PARM_DESC(irq_cnt, "counter of irq"); - -static unsigned int rdma_irq_cnt; -module_param(rdma_irq_cnt, uint, 0664); -MODULE_PARM_DESC(rdma_irq_cnt, "counter of rdma irq"); - -static unsigned int vdin_irq_flag; -module_param(vdin_irq_flag, uint, 0664); -MODULE_PARM_DESC(vdin_irq_flag, "vdin_irq_flag"); - -/* viu isr select: - * enable viu_hw_irq for the bandwidth is enough on gxbb/gxtvbb and laters ic - */ -static unsigned int viu_hw_irq = 1; -module_param(viu_hw_irq, uint, 0664); -MODULE_PARM_DESC(viu_hw_irq, "viu_hw_irq"); - -static unsigned int vdin_reset_flag; -module_param(vdin_reset_flag, uint, 0664); -MODULE_PARM_DESC(vdin_reset_flag, "vdin_reset_flag"); - -static unsigned int vdin_reset_flag1; -module_param(vdin_reset_flag1, uint, 0664); -MODULE_PARM_DESC(vdin_reset_flag1, "vdin_reset_flag1"); - -/* - * 2:enable manul rdam - * 1:enable auto rdma - * 0:no support rdma - */ -static unsigned int rdma_enable; -module_param(rdma_enable, uint, 0664); -MODULE_PARM_DESC(rdma_enable, "rdma_enable"); +static unsigned int vdin_drop_cnt; +module_param(vdin_drop_cnt, uint, 0664); +MODULE_PARM_DESC(vdin_drop_cnt, "vdin_drop_cnt"); +static bool game_mode; +module_param(game_mode, bool, 0664); +MODULE_PARM_DESC(game_mode, "game_mode"); static int irq_max_count; + static void vdin_backup_histgram(struct vframe_s *vf, struct vdin_dev_s *devp); char *vf_get_receiver_name(const char *provider_name); -static void vdin_set_drm_data(struct vdin_dev_s *devp, - struct vframe_s *vf) -{ - if (devp->prop.hdr_info.hdr_state == HDR_STATE_GET) { - memcpy(vf->prop.master_display_colour.primaries, - devp->prop.hdr_info.hdr_data.primaries, - sizeof(u32)*6); - memcpy(vf->prop.master_display_colour.white_point, - &devp->prop.hdr_info.hdr_data.white_points, - sizeof(u32)*2); - memcpy(vf->prop.master_display_colour.luminance, - &devp->prop.hdr_info.hdr_data.master_lum, - sizeof(u32)*2); - - vf->prop.master_display_colour.present_flag = true; - - if ((devp->prop.hdr_info.hdr_data.eotf == EOTF_SMPTE_ST_2048) || - (devp->prop.hdr_info.hdr_data.eotf == EOTF_HDR)) { - vf->signal_type |= (1 << 29); - vf->signal_type |= (0 << 25);/*0:limit*/ - vf->signal_type = ((9 << 16) | - (vf->signal_type & (~0xFF0000))); - vf->signal_type = ((16 << 8) | - (vf->signal_type & (~0xFF00))); - vf->signal_type = ((9 << 0) | - (vf->signal_type & (~0xFF))); - } else { - vf->signal_type &= ~(1 << 29); - vf->signal_type &= ~(1 << 25); - } - - devp->prop.vdin_hdr_Flag = true; - - devp->prop.hdr_info.hdr_state = HDR_STATE_SET; - } else if (devp->prop.hdr_info.hdr_state == HDR_STATE_NULL) { - devp->prop.vdin_hdr_Flag = false; - vf->prop.master_display_colour.present_flag = false; - vf->signal_type &= ~(1 << 29); - vf->signal_type &= ~(1 << 25); - } -} - -static u32 vdin_get_curr_field_type(struct vdin_dev_s *devp) -{ - u32 field_status; - u32 type = VIDTYPE_VIU_SINGLE_PLANE | VIDTYPE_VIU_FIELD; - enum vdin_format_convert_e format_convert; - - /* struct tvin_parm_s *parm = &devp->parm; */ - const struct tvin_format_s *fmt_info = devp->fmt_info_p; - - if (fmt_info->scan_mode == TVIN_SCAN_MODE_PROGRESSIVE) { - type |= VIDTYPE_PROGRESSIVE; - } else { - field_status = vdin_get_field_type(devp->addr_offset); - if (invert_top_bot) - type |= field_status ? - VIDTYPE_INTERLACE_TOP : VIDTYPE_INTERLACE_BOTTOM; - else - type |= field_status ? - VIDTYPE_INTERLACE_BOTTOM : VIDTYPE_INTERLACE_TOP; - } - format_convert = devp->format_convert; - if ((format_convert == VDIN_FORMAT_CONVERT_YUV_YUV444) || - (format_convert == VDIN_FORMAT_CONVERT_RGB_YUV444)) - type |= VIDTYPE_VIU_444; - else if ((format_convert == VDIN_FORMAT_CONVERT_YUV_YUV422) || - (format_convert == VDIN_FORMAT_CONVERT_RGB_YUV422)) - type |= VIDTYPE_VIU_422; - else if (devp->prop.dest_cfmt == TVIN_NV21) { - type |= VIDTYPE_VIU_NV21; - type &= (~VIDTYPE_VIU_SINGLE_PLANE); - } else if (devp->prop.dest_cfmt == TVIN_NV12) { - /* type |= VIDTYPE_VIU_NV12; */ - type &= (~VIDTYPE_VIU_SINGLE_PLANE); - - } - return type; -} - -void set_invert_top_bot(bool invert_flag) -{ - invert_top_bot = invert_flag; -} - -void vdin_timer_func(unsigned long arg) +static void vdin_timer_func(unsigned long arg) { struct vdin_dev_s *devp = (struct vdin_dev_s *)arg; @@ -286,115 +158,10 @@ static const struct vframe_operations_s vdin_vf_ops = { .peek = vdin_vf_peek, .get = vdin_vf_get, .put = vdin_vf_put, + .event_cb = vdin_event_cb, .vf_states = vdin_vf_states, }; -#ifdef CONFIG_CMA -void vdin_cma_alloc(struct vdin_dev_s *devp) -{ - char vdin_name[6]; - unsigned int mem_size, h_size; - int flags = CODEC_MM_FLAGS_CMA_FIRST|CODEC_MM_FLAGS_CMA_CLEAR| - CODEC_MM_FLAGS_CPU; - if ((devp->format_convert == VDIN_FORMAT_CONVERT_YUV_YUV444) || - (devp->format_convert == VDIN_FORMAT_CONVERT_YUV_RGB) || - (devp->format_convert == VDIN_FORMAT_CONVERT_RGB_YUV444) || - (devp->format_convert == VDIN_FORMAT_CONVERT_RGB_RGB)) { - if (devp->source_bitdepth > 8) - h_size = roundup(devp->h_active * 4, 32); - else - h_size = roundup(devp->h_active * 3, 32); - } else { - /* txl new add mode yuv422 pack mode:canvas-w=h*2*10/8 - * canvas_w must ensure divided exact by 256bit(32byte) - */ - if ((devp->source_bitdepth > 8) && - ((devp->format_convert == VDIN_FORMAT_CONVERT_YUV_YUV422) || - (devp->format_convert == VDIN_FORMAT_CONVERT_RGB_YUV422) || - (devp->format_convert == VDIN_FORMAT_CONVERT_GBR_YUV422) || - (devp->format_convert == VDIN_FORMAT_CONVERT_BRG_YUV422)) && - (devp->color_depth_mode == 1)) - h_size = roundup((devp->h_active * 5)/2, 32); - else if ((devp->source_bitdepth > 8) && - (devp->color_depth_mode == 0)) - h_size = roundup(devp->h_active * 3, 32); - else - h_size = roundup(devp->h_active * 2, 32); - } - mem_size = h_size * devp->v_active; - mem_size = PAGE_ALIGN(mem_size)*max_buf_num; - mem_size = (mem_size/PAGE_SIZE + 1)*PAGE_SIZE; - if (mem_size > devp->cma_mem_size) - mem_size = devp->cma_mem_size; - if (devp->cma_config_en == 0) - return; - if (devp->cma_mem_alloc == 1) - return; - devp->cma_mem_alloc = 1; - if (devp->cma_config_flag == 1) { - if (devp->index == 0) - strcpy(vdin_name, "vdin0"); - else if (devp->index == 1) - strcpy(vdin_name, "vdin1"); - devp->mem_start = codec_mm_alloc_for_dma(vdin_name, - mem_size/PAGE_SIZE, 0, flags); - devp->mem_size = mem_size; - if (devp->mem_start == 0) - pr_err("\nvdin%d codec alloc fail!!!\n", - devp->index); - else { - pr_info("vdin%d mem_start = 0x%x, mem_size = 0x%x\n", - devp->index, devp->mem_start, devp->mem_size); - pr_info("vdin%d codec cma alloc ok!\n", devp->index); - } - } else if (devp->cma_config_flag == 0) { - devp->venc_pages = dma_alloc_from_contiguous( - &(devp->this_pdev->dev), - devp->cma_mem_size >> PAGE_SHIFT, 0); - if (devp->venc_pages) { - devp->mem_start = - page_to_phys(devp->venc_pages); - devp->mem_size = mem_size; - pr_info("vdin%d mem_start = 0x%x, mem_size = 0x%x\n", - devp->index, devp->mem_start, devp->mem_size); - pr_info("vdin%d cma alloc ok!\n", devp->index); - } else { - pr_err("\nvdin%d cma mem undefined2.\n", - devp->index); - } - } -} - -void vdin_cma_release(struct vdin_dev_s *devp) -{ - char vdin_name[6]; - - if (devp->cma_config_en == 0) - return; - if ((devp->cma_config_flag == 1) && devp->mem_start - && (devp->cma_mem_alloc == 1)) { - if (devp->index == 0) - strcpy(vdin_name, "vdin0"); - else if (devp->index == 1) - strcpy(vdin_name, "vdin1"); - codec_mm_free_for_dma(vdin_name, devp->mem_start); - devp->mem_start = 0; - devp->mem_size = 0; - devp->cma_mem_alloc = 0; - pr_info("vdin%d codec cma release ok!\n", devp->index); - } else if (devp->venc_pages - && devp->cma_mem_size - && (devp->cma_mem_alloc == 1) - && (devp->cma_config_flag == 0)) { - devp->cma_mem_alloc = 0; - dma_release_from_contiguous( - &(devp->this_pdev->dev), - devp->venc_pages, - devp->cma_mem_size >> PAGE_SHIFT); - pr_info("vdin%d cma release ok!\n", devp->index); - } -} -#endif /* * 1. find the corresponding frontend according to the port & save it. * 2. set default register, including: @@ -430,22 +197,19 @@ int vdin_open_fe(enum tvin_port_e port, int index, struct vdin_dev_s *devp) else devp->parm.info.fmt = TVIN_SIG_FMT_NULL; devp->parm.info.status = TVIN_SIG_STATUS_NULL; - if (devp->pre_info.status != TVIN_SIG_STATUS_NULL) { - devp->pre_info.status = TVIN_SIG_STATUS_NULL; - #if 0 - switch_set_state(&devp->sig_sdev, TVIN_SIG_STATUS_NULL); - #endif - } - devp->dec_enable = 1; /* enable decoder */ /* clear color para*/ memset(&devp->pre_prop, 0, sizeof(devp->pre_prop)); - /* clear color para*/ + /* clear color para*/ memset(&devp->prop, 0, sizeof(devp->prop)); vdin_set_default_regmap(devp->addr_offset); + /*only for vdin0*/ + if (devp->urgent_en && (devp->index == 0)) + vdin_urgent_patch_resume(devp->addr_offset); /* vdin msr clock gate enable */ - clk_prepare_enable(devp->msr_clk); + if (devp->msr_clk != NULL) + clk_prepare_enable(devp->msr_clk); if (devp->frontend->dec_ops && devp->frontend->dec_ops->open) ret = devp->frontend->dec_ops->open(devp->frontend, port); @@ -464,14 +228,12 @@ int vdin_open_fe(enum tvin_port_e port, int index, struct vdin_dev_s *devp) return 0; } -/* - * 1. disable hw work, including: +/* 1. disable hw work, including: * a. mux null input. * b. set clock off. * 2. delete timer for state machine. * 3. unregiseter provider & notify receiver. * 4. call the callback function of the frontend to close. - * */ void vdin_close_fe(struct vdin_dev_s *devp) { @@ -480,10 +242,9 @@ void vdin_close_fe(struct vdin_dev_s *devp) pr_info("%s: null pointer\n", __func__); return; } - devp->dec_enable = 0; /* disable decoder */ - /* bt656 clock gate disable */ - clk_disable_unprepare(devp->msr_clk); + if (devp->msr_clk != NULL) + clk_disable_unprepare(devp->msr_clk); vdin_hw_disable(devp->addr_offset); del_timer_sync(&devp->timer); @@ -494,195 +255,21 @@ void vdin_close_fe(struct vdin_dev_s *devp) devp->parm.port = TVIN_PORT_NULL; devp->parm.info.fmt = TVIN_SIG_FMT_NULL; devp->parm.info.status = TVIN_SIG_STATUS_NULL; - if (devp->pre_info.status != TVIN_SIG_STATUS_NULL) { - devp->pre_info.status = TVIN_SIG_STATUS_NULL; - #if 0 - switch_set_state(&devp->sig_sdev, TVIN_SIG_STATUS_NULL); - #endif - } pr_info("%s ok\n", __func__); } -static inline void vdin_set_source_type(struct vdin_dev_s *devp, - struct vframe_s *vf) -{ - switch (devp->parm.port) { - case TVIN_PORT_CVBS3: - case TVIN_PORT_CVBS0: - vf->source_type = VFRAME_SOURCE_TYPE_TUNER; - break; - case TVIN_PORT_CVBS1: - case TVIN_PORT_CVBS2: - case TVIN_PORT_CVBS4: - case TVIN_PORT_CVBS5: - case TVIN_PORT_CVBS6: - case TVIN_PORT_CVBS7: - vf->source_type = VFRAME_SOURCE_TYPE_CVBS; - break; - case TVIN_PORT_COMP0: - case TVIN_PORT_COMP1: - case TVIN_PORT_COMP2: - case TVIN_PORT_COMP3: - case TVIN_PORT_COMP4: - case TVIN_PORT_COMP5: - case TVIN_PORT_COMP6: - case TVIN_PORT_COMP7: - vf->source_type = VFRAME_SOURCE_TYPE_COMP; - break; - case TVIN_PORT_HDMI0: - case TVIN_PORT_HDMI1: - case TVIN_PORT_HDMI2: - case TVIN_PORT_HDMI3: - case TVIN_PORT_HDMI4: - case TVIN_PORT_HDMI5: - case TVIN_PORT_HDMI6: - case TVIN_PORT_HDMI7: - case TVIN_PORT_DVIN0:/* hdmirx_ext used */ - case TVIN_PORT_BT656_HDMI:/* hdmirx_ext used */ - case TVIN_PORT_BT601_HDMI:/* hdmirx_ext used */ - vf->source_type = VFRAME_SOURCE_TYPE_HDMI; - break; - default: - vf->source_type = VFRAME_SOURCE_TYPE_OTHERS; - break; - } -} - - - -static inline void vdin_set_source_mode(struct vdin_dev_s *devp, - struct vframe_s *vf) -{ - switch (devp->parm.info.fmt) { - case TVIN_SIG_FMT_CVBS_NTSC_M: - case TVIN_SIG_FMT_CVBS_NTSC_443: - vf->source_mode = VFRAME_SOURCE_MODE_NTSC; - break; - case TVIN_SIG_FMT_CVBS_PAL_I: - case TVIN_SIG_FMT_CVBS_PAL_M: - case TVIN_SIG_FMT_CVBS_PAL_60: - case TVIN_SIG_FMT_CVBS_PAL_CN: - vf->source_mode = VFRAME_SOURCE_MODE_PAL; - break; - case TVIN_SIG_FMT_CVBS_SECAM: - vf->source_mode = VFRAME_SOURCE_MODE_SECAM; - break; - default: - vf->source_mode = VFRAME_SOURCE_MODE_OTHERS; - break; - } -} - /* - * 480p/i = 9:8 - * 576p/i = 16:15 - * 720p and 1080p/i = 1:1 - * All VGA format = 1:1 - */ -static void vdin_set_pixel_aspect_ratio(struct vdin_dev_s *devp, - struct vframe_s *vf) -{ - switch (devp->parm.info.fmt) { - /* 480P */ - case TVIN_SIG_FMT_COMP_480P_60HZ_D000: - case TVIN_SIG_FMT_HDMI_640X480P_60HZ: - case TVIN_SIG_FMT_HDMI_720X480P_60HZ: - case TVIN_SIG_FMT_HDMI_1440X480P_60HZ: - case TVIN_SIG_FMT_HDMI_2880X480P_60HZ: - case TVIN_SIG_FMT_HDMI_720X480P_120HZ: - case TVIN_SIG_FMT_HDMI_720X480P_240HZ: - case TVIN_SIG_FMT_HDMI_720X480P_60HZ_FRAME_PACKING: - case TVIN_SIG_FMT_CAMERA_640X480P_30HZ: - /* 480I */ - case TVIN_SIG_FMT_CVBS_NTSC_M: - case TVIN_SIG_FMT_CVBS_NTSC_443: - case TVIN_SIG_FMT_CVBS_PAL_M: - case TVIN_SIG_FMT_CVBS_PAL_60: - case TVIN_SIG_FMT_COMP_480I_59HZ_D940: - case TVIN_SIG_FMT_HDMI_1440X480I_60HZ: - case TVIN_SIG_FMT_HDMI_2880X480I_60HZ: - case TVIN_SIG_FMT_HDMI_1440X480I_120HZ: - case TVIN_SIG_FMT_HDMI_1440X480I_240HZ: - case TVIN_SIG_FMT_BT656IN_480I_60HZ: - case TVIN_SIG_FMT_BT601IN_480I_60HZ: - vf->pixel_ratio = PIXEL_ASPECT_RATIO_8_9; - break; - /* 576P */ - case TVIN_SIG_FMT_COMP_576P_50HZ_D000: - case TVIN_SIG_FMT_HDMI_720X576P_50HZ: - case TVIN_SIG_FMT_HDMI_1440X576P_50HZ: - case TVIN_SIG_FMT_HDMI_2880X576P_50HZ: - case TVIN_SIG_FMT_HDMI_720X576P_100HZ: - case TVIN_SIG_FMT_HDMI_720X576P_200HZ: - case TVIN_SIG_FMT_HDMI_720X576P_50HZ_FRAME_PACKING: - /* 576I */ - case TVIN_SIG_FMT_CVBS_PAL_I: - case TVIN_SIG_FMT_CVBS_PAL_CN: - case TVIN_SIG_FMT_CVBS_SECAM: - case TVIN_SIG_FMT_COMP_576I_50HZ_D000: - case TVIN_SIG_FMT_HDMI_1440X576I_50HZ: - case TVIN_SIG_FMT_HDMI_2880X576I_50HZ: - case TVIN_SIG_FMT_HDMI_1440X576I_100HZ: - case TVIN_SIG_FMT_HDMI_1440X576I_200HZ: - case TVIN_SIG_FMT_BT656IN_576I_50HZ: - case TVIN_SIG_FMT_BT601IN_576I_50HZ: - vf->pixel_ratio = PIXEL_ASPECT_RATIO_16_15; - break; - default: - vf->pixel_ratio = PIXEL_ASPECT_RATIO_1_1; - break; - } -} -/* - * based on the bellow parameters: - * 1.h_active - * 2.v_active - */ -static void vdin_set_display_ratio(struct vframe_s *vf) -{ - unsigned int re = 0; - - if (vf->width == 0 || vf->height == 0) - return; - - re = (vf->width * 36)/vf->height; - if ((re > 36 && re <= 56) || (re == 90) || (re == 108)) - vf->ratio_control = 0xc0 << DISP_RATIO_ASPECT_RATIO_BIT; - else if (re > 56) - vf->ratio_control = 0x90 << DISP_RATIO_ASPECT_RATIO_BIT; - else - vf->ratio_control = 0x100 << DISP_RATIO_ASPECT_RATIO_BIT; -} - -static inline void vdin_set_source_bitdepth(struct vdin_dev_s *devp, - struct vframe_s *vf) -{ - switch (devp->source_bitdepth) { - case 10: - vf->bitdepth = BITDEPTH_Y10 | BITDEPTH_U10 | BITDEPTH_V10; - break; - case 9: - vf->bitdepth = BITDEPTH_Y9 | BITDEPTH_U9 | BITDEPTH_V9; - break; - case 8: - vf->bitdepth = BITDEPTH_Y8 | BITDEPTH_U8 | BITDEPTH_V8; - break; - default: - vf->bitdepth = BITDEPTH_Y8 | BITDEPTH_U8 | BITDEPTH_V8; - break; - } - if (devp->color_depth_mode && (devp->source_bitdepth > 8) && - ((devp->format_convert == VDIN_FORMAT_CONVERT_YUV_YUV422) || - (devp->format_convert == VDIN_FORMAT_CONVERT_RGB_YUV422) || - (devp->format_convert == VDIN_FORMAT_CONVERT_GBR_YUV422) || - (devp->format_convert == VDIN_FORMAT_CONVERT_BRG_YUV422))) - vf->bitdepth |= FULL_PACK_422_MODE; -} - -/* based on the bellow parameters: - * 1.h_active - * 2.v_active + *based on the bellow parameters: + * a.h_active (vf->width = devp->h_active) + * b.v_active (vf->height = devp->v_active) + *function: init vframe + *1.set source type & mode + *2.set source signal format + *3.set pixel aspect ratio + *4.set display ratio control + *5.init slave vframe + *6.set slave vf source type & mode */ static void vdin_vf_init(struct vdin_dev_s *devp) { @@ -691,7 +278,7 @@ static void vdin_vf_init(struct vdin_dev_s *devp) struct vf_entry *master, *slave; struct vframe_s *vf; struct vf_pool *p = devp->vfp; - enum tvin_scan_mode_e scan_mode; + enum tvin_scan_mode_e scan_mode; index = devp->index; /* const struct tvin_format_s *fmt_info = tvin_get_fmt_info(fmt); */ @@ -709,18 +296,18 @@ static void vdin_vf_init(struct vdin_dev_s *devp) vf->height = devp->v_active; scan_mode = devp->fmt_info_p->scan_mode; if (((scan_mode == TVIN_SCAN_MODE_INTERLACED) && - (!(devp->parm.flag & TVIN_PARM_FLAG_2D_TO_3D) && - (devp->parm.info.fmt != TVIN_SIG_FMT_NULL))) || - (devp->parm.port == TVIN_PORT_CVBS3)) + (!(devp->parm.flag & TVIN_PARM_FLAG_2D_TO_3D) && + (devp->parm.info.fmt != TVIN_SIG_FMT_NULL))) || + (devp->parm.port == TVIN_PORT_CVBS3)) vf->height <<= 1; #ifndef VDIN_DYNAMIC_DURATION vf->duration = devp->fmt_info_p->duration; #endif - /* if output fmt is nv21 or nv12 , + /*if output fmt is nv21 or nv12 , * use the two continuous canvas for one field */ if ((devp->prop.dest_cfmt == TVIN_NV12) || - (devp->prop.dest_cfmt == TVIN_NV21)) { + (devp->prop.dest_cfmt == TVIN_NV21)) { chromaid = (vdin_canvas_ids[index][(vf->index<<1)+1])<<8; addr = @@ -739,18 +326,18 @@ static void vdin_vf_init(struct vdin_dev_s *devp) /* set pixel aspect ratio */ vdin_set_pixel_aspect_ratio(devp, vf); /*set display ratio control */ - vdin_set_display_ratio(vf); + vdin_set_display_ratio(devp, vf); vdin_set_source_bitdepth(devp, vf); /* init slave vframe */ - slave = vf_get_slave(p, i); + slave = vf_get_slave(p, i); if (slave == NULL) continue; slave->flag = master->flag; memset(&slave->vf, 0, sizeof(struct vframe_s)); - slave->vf.index = vf->index; - slave->vf.width = vf->width; - slave->vf.height = vf->height; - slave->vf.duration = vf->duration; + slave->vf.index = vf->index; + slave->vf.width = vf->width; + slave->vf.height = vf->height; + slave->vf.duration = vf->duration; slave->vf.ratio_control = vf->ratio_control; slave->vf.canvas0Addr = vf->canvas0Addr; slave->vf.canvas1Addr = vf->canvas1Addr; @@ -764,10 +351,14 @@ static void vdin_vf_init(struct vdin_dev_s *devp) vf->height, vf->duration); } } + #ifdef CONFIG_AML_RDMA static void vdin_rdma_irq(void *arg) { - rdma_irq_cnt++; + struct vdin_dev_s *devp = arg; + + devp->rdma_irq_cnt++; + return; } static struct rdma_op_s vdin_rdma_op = { @@ -777,15 +368,21 @@ static struct rdma_op_s vdin_rdma_op = { #endif /* - * 1. config canvas for video frame. - * 2. enable hw work, including: + * 1. config canvas base on canvas_config_mode + * 0: canvas_config in driver probe + * 1: start cofig + * 2: auto config + * 2. recalculate h_active and v_active, including: + * a. vdin_set_decimation. + * b. vdin_set_cutwin. + * c. vdin_set_hvscale. + * 3. enable hw work, including: * a. mux null input. * b. set clock auto. - * 3. set all registeres including: + * 4. set all registeres including: * a. mux input. - * 4. call the callback function of the frontend to start. - * 5. enable irq . - * + * 5. call the callback function of the frontend to start. + * 6. enable irq . */ void vdin_start_dec(struct vdin_dev_s *devp) { @@ -800,7 +397,8 @@ void vdin_start_dec(struct vdin_dev_s *devp) sm_ops = devp->frontend->sm_ops; sm_ops->get_sig_property(devp->frontend, &devp->prop); - devp->parm.info.cfmt = devp->prop.color_format; + if (!(devp->flags & VDIN_FLAG_V4L2_DEBUG)) + devp->parm.info.cfmt = devp->prop.color_format; if ((devp->parm.dest_width != 0) || (devp->parm.dest_height != 0)) { devp->prop.scaling4w = devp->parm.dest_width; @@ -821,35 +419,47 @@ void vdin_start_dec(struct vdin_dev_s *devp) devp->prop.ve = devp->debug.cutwin.ve; } } + /*gxbb/gxl/gxm use clkb as vdin clk, *for clkb is low speed,wich is enough for 1080p process, *gxtvbb/txl use vpu clk for process 4k */ - if (is_meson_gxl_cpu() || is_meson_gxm_cpu() || is_meson_gxbb_cpu()) + if (is_meson_gxl_cpu() || is_meson_gxm_cpu() || is_meson_gxbb_cpu() || + is_meson_txhd_cpu()) switch_vpu_clk_gate_vmod(VPU_VPU_CLKB, VPU_CLK_GATE_ON); vdin_get_format_convert(devp); devp->curr_wr_vfe = NULL; + devp->game_mode = game_mode; + if (game_mode) + devp->vfp->skip_vf_num = 1; + else + devp->vfp->skip_vf_num = devp->prop.skip_vf_num; + if (devp->vfp->skip_vf_num >= VDIN_CANVAS_MAX_CNT) + devp->vfp->skip_vf_num = 0; + devp->canvas_config_mode = canvas_config_mode; /* h_active/v_active will be recalculated by bellow calling */ vdin_set_decimation(devp); vdin_set_cutwin(devp); vdin_set_hvscale(devp); - if (is_meson_gxtvbb_cpu() || is_meson_txl_cpu()) + if (cpu_after_eq(MESON_CPU_MAJOR_ID_GXTVBB)) vdin_set_bitdepth(devp); /* txl new add fix for hdmi switch resolution cause cpu holding */ if (get_cpu_type() >= MESON_CPU_MAJOR_ID_TXL) vdin_fix_nonstd_vsync(devp); -#ifdef CONFIG_AML_RDMA - if (rdma_enable && devp->rdma_handle > 0) - devp->flags |= VDIN_FLAG_RDMA_ENABLE; -#endif + /*reverse / disable reverse write buffer*/ vdin_wr_reverse(devp->addr_offset, devp->parm.h_reverse, devp->parm.v_reverse); #ifdef CONFIG_CMA - vdin_cma_alloc(devp); + vdin_cma_malloc_mode(devp); + if (vdin_cma_alloc(devp)) { + pr_err("\nvdin%d %s fail for cma alloc fail!!!\n", + devp->index, __func__); + return; + } #endif /* h_active/v_active will be used by bellow calling */ if (canvas_config_mode == 1) @@ -863,16 +473,25 @@ void vdin_start_dec(struct vdin_dev_s *devp) else devp->vfp->size = devp->canvas_max_num; #endif - if (devp->prop.dvi_info>>4 && + if (devp->prop.fps && devp->parm.port >= TVIN_PORT_HDMI0 && devp->parm.port <= TVIN_PORT_HDMI7) - devp->duration = 96000/(devp->prop.dvi_info>>4); + devp->duration = 96000/(devp->prop.fps); else devp->duration = devp->fmt_info_p->duration; devp->vfp->size = devp->canvas_max_num; vf_pool_init(devp->vfp, devp->vfp->size); vdin_vf_init(devp); + if ((devp->dv.dolby_input & (1 << devp->index)) || + (devp->dv.dv_flag && is_dolby_vision_enable())) { + /* config dolby mem base */ + vdin_dolby_addr_alloc(devp, devp->vfp->size); + /* config dolby vision */ + vdin_dolby_config(devp); + if (vdin_dbg_en) + pr_info("vdin start dec dv input config\n"); + } devp->abnormal_cnt = 0; devp->last_wr_vfe = NULL; @@ -883,43 +502,47 @@ void vdin_start_dec(struct vdin_dev_s *devp) devp->cycle_tag = 0; devp->hcnt64 = 0; devp->hcnt64_tag = 0; - - devp->vga_clr_cnt = devp->canvas_max_num; - devp->vs_cnt_valid = 0; devp->vs_cnt_ignore = 0; memset(&devp->parm.histgram[0], 0, sizeof(unsigned short) * 64); devp->curr_field_type = vdin_get_curr_field_type(devp); - /* pr_info("start clean_counter is %d\n",clean_counter); */ /* configure regs and enable hw */ +#ifdef CONFIG_AML_VPU switch_vpu_mem_pd_vmod(devp->addr_offset?VPU_VIU_VDIN1:VPU_VIU_VDIN0, VPU_MEM_POWER_ON); +#endif vdin_hw_enable(devp->addr_offset); vdin_set_all_regs(devp); - if (!(devp->parm.flag & TVIN_PARM_FLAG_CAP) && (devp->frontend) && devp->frontend->dec_ops && devp->frontend->dec_ops->start && - (devp->parm.port != TVIN_PORT_CVBS3)) + ((devp->parm.port != TVIN_PORT_CVBS3) || + ((devp->flags & VDIN_FLAG_SNOW_FLAG) == 0))) devp->frontend->dec_ops->start(devp->frontend, devp->parm.info.fmt); - /* register provider, so the receiver can get the valid vframe */ - udelay(start_provider_delay); - vf_reg_provider(&devp->vprov); - if (vf_get_receiver_name(devp->name)) { - if (strcmp(vf_get_receiver_name(devp->name), "deinterlace") - == 0) - devp->send2di = true; - else - devp->send2di = false; - } - - vf_notify_receiver(devp->name, VFRAME_EVENT_PROVIDER_START, NULL); +#ifdef CONFIG_AML_RDMA + /*it is better put after all reg init*/ + if (devp->rdma_enable && devp->rdma_handle > 0) + devp->flags |= VDIN_FLAG_RDMA_ENABLE; +#endif + /*only for vdin0;vdin1 used for debug*/ + if ((devp->dv.dolby_input & (1 << 0)) || + (devp->dv.dv_flag && is_dolby_vision_enable())) + vf_reg_provider(&devp->dv.vprov_dv); + else + vf_reg_provider(&devp->vprov); + if ((devp->dv.dolby_input & (1 << devp->index)) || + (devp->dv.dv_flag && is_dolby_vision_enable())) + vf_notify_receiver("dv_vdin", + VFRAME_EVENT_PROVIDER_START, NULL); + else + vf_notify_receiver(devp->name, + VFRAME_EVENT_PROVIDER_START, NULL); if ((devp->parm.port != TVIN_PORT_VIU) || (viu_hw_irq != 0)) { /*enable irq */ @@ -941,8 +564,8 @@ void vdin_start_dec(struct vdin_dev_s *devp) __func__); } #endif - irq_cnt = 0; - rdma_irq_cnt = 0; + devp->irq_cnt = 0; + devp->rdma_irq_cnt = 0; if (time_en) pr_info("vdin.%d start time: %ums, run time:%ums.\n", devp->index, jiffies_to_msecs(jiffies), @@ -954,33 +577,54 @@ void vdin_start_dec(struct vdin_dev_s *devp) * 2. disable hw work, including: * a. mux null input. * b. set clock off. - * 3. call the callback function of the frontend to stop. - * + * 3. reset default canvas + * 4.call the callback function of the frontend to stop vdin. */ void vdin_stop_dec(struct vdin_dev_s *devp) { /* avoid null pointer oops */ if (!devp || !devp->frontend) return; - +#ifdef CONFIG_CMA + if ((devp->cma_mem_alloc == 0) && devp->cma_config_en) { + pr_info("%s:cma not alloc,don't need do others!\n", __func__); + return; + } +#endif disable_irq_nosync(devp->irq); vdin_hw_disable(devp->addr_offset); if (!(devp->parm.flag & TVIN_PARM_FLAG_CAP) && devp->frontend->dec_ops && devp->frontend->dec_ops->stop && - (devp->parm.port != TVIN_PORT_CVBS3)) + ((devp->parm.port != TVIN_PORT_CVBS3) || + ((devp->flags & VDIN_FLAG_SNOW_FLAG) == 0))) devp->frontend->dec_ops->stop(devp->frontend, devp->parm.port); vdin_set_default_regmap(devp->addr_offset); + /*only for vdin0*/ + if (devp->urgent_en && (devp->index == 0)) + vdin_urgent_patch_resume(devp->addr_offset); /* reset default canvas */ vdin_set_def_wr_canvas(devp); - vf_unreg_provider(&devp->vprov); +#if 1/*def CONFIG_AM_HDMIIN_DV*/ + if (((devp->dv.dolby_input & (1 << devp->index)) || + is_dolby_vision_enable()) && + (devp->dv.dv_config == true)) + vf_unreg_provider(&devp->dv.vprov_dv); + else +#endif + vf_unreg_provider(&devp->vprov); + devp->dv.dv_config = 0; #ifdef CONFIG_CMA vdin_cma_release(devp); #endif + vdin_dolby_addr_release(devp, devp->vfp->size); + +#ifdef CONFIG_AML_VPU switch_vpu_mem_pd_vmod(devp->addr_offset?VPU_VIU_VDIN1:VPU_VIU_VDIN0, VPU_MEM_POWER_DOWN); +#endif memset(&devp->prop, 0, sizeof(struct tvin_sig_property_s)); #ifdef CONFIG_AML_RDMA rdma_clear(devp->rdma_handle); @@ -998,8 +642,11 @@ void vdin_stop_dec(struct vdin_dev_s *devp) if (vdin_dbg_en) pr_info("%s ok\n", __func__); } -/* @todo */ +/* + *config the vdin use default regmap + *call vdin_start_dec to start vdin + */ int start_tvin_service(int no, struct vdin_parm_s *para) { struct tvin_frontend_s *fe; @@ -1034,11 +681,15 @@ int start_tvin_service(int no, struct vdin_parm_s *para) (viu_hw_irq != 0)) { ret = request_irq(devp->irq, vdin_v4l2_isr, IRQF_SHARED, devp->irq_name, (void *)devp); - /* disable vsync irq until vdin configured completely */ + devp->flags |= VDIN_FLAG_ISR_REQ; + /*disable vsync irq until vdin configured completely*/ disable_irq_nosync(devp->irq); } - /* config the vdin use default value*/ + /*config the vdin use default value*/ vdin_set_default_regmap(devp->addr_offset); + /*only for vdin0*/ + if (devp->urgent_en && (devp->index == 0)) + vdin_urgent_patch_resume(devp->addr_offset); devp->parm.port = para->port; devp->parm.info.fmt = para->fmt; @@ -1047,17 +698,30 @@ int start_tvin_service(int no, struct vdin_parm_s *para) if (para->fmt >= TVIN_SIG_FMT_MAX) { devp->fmt_info_p = kmalloc(sizeof(struct tvin_format_s), GFP_KERNEL); - if (!devp->fmt_info_p) + if (!devp->fmt_info_p) { + pr_err("[vdin]%s kmalloc error.\n", __func__); return -ENOMEM; + } devp->fmt_info_p->hs_bp = para->hs_bp; devp->fmt_info_p->vs_bp = para->vs_bp; devp->fmt_info_p->hs_pol = para->hsync_phase; devp->fmt_info_p->vs_pol = para->vsync_phase; - if ((para->h_active * para->v_active * para->frame_rate) > - devp->vdin_max_pixelclk) + if ((para->h_active * para->v_active * para->frame_rate) + > devp->vdin_max_pixelclk) para->h_active >>= 1; devp->fmt_info_p->h_active = para->h_active; devp->fmt_info_p->v_active = para->v_active; + if ((devp->parm.port == TVIN_PORT_VIDEO) && + (!(devp->flags & VDIN_FLAG_V4L2_DEBUG))) { + devp->fmt_info_p->v_active = + ((rd(0, VPP_POSTBLEND_VD1_V_START_END) & + 0xfff) - ((rd(0, VPP_POSTBLEND_VD1_V_START_END) + >> 16) & 0xfff) + 1); + devp->fmt_info_p->h_active = + ((rd(0, VPP_POSTBLEND_VD1_H_START_END) & + 0xfff) - ((rd(0, VPP_POSTBLEND_VD1_H_START_END) + >> 16) & 0xfff) + 1); + } devp->fmt_info_p->scan_mode = para->scan_mode; devp->fmt_info_p->duration = 96000/para->frame_rate; devp->fmt_info_p->pixel_clk = para->h_active * @@ -1073,18 +737,19 @@ int start_tvin_service(int no, struct vdin_parm_s *para) return -1; } - if (para->bt_path == BT_PATH_GPIO_B) { + if ((is_meson_gxbb_cpu()) && (para->bt_path == BT_PATH_GPIO_B)) { devp->bt_path = para->bt_path; - fe = tvin_get_frontend(para->port, 2); - } else fe = tvin_get_frontend(para->port, 1); + } else + fe = tvin_get_frontend(para->port, 0); if (fe) { fe->private_data = para; fe->port = para->port; devp->frontend = fe; /* vdin msr clock gate enable */ - clk_prepare_enable(devp->msr_clk); + if (devp->msr_clk != NULL) + clk_prepare_enable(devp->msr_clk); if (fe->dec_ops->open) fe->dec_ops->open(fe, fe->port); @@ -1103,7 +768,12 @@ int start_tvin_service(int no, struct vdin_parm_s *para) return 0; } EXPORT_SYMBOL(start_tvin_service); -/* @todo */ + +/* + *call vdin_stop_dec to stop the frontend + *close frontend + *free the memory allocated in start tvin service + */ int stop_tvin_service(int no) { struct vdin_dev_s *devp; @@ -1114,12 +784,6 @@ int stop_tvin_service(int no) pr_err("%s:decode hasn't started.\n", __func__); return -EBUSY; } -/* remove for m6&m8 camera function, - * may cause hardware disable bug on kernel 3.10 - */ -/* #if MESON_CPU_TYPE < MESON_CPU_TYPE_MESON8 */ -/* devp->flags |= VDIN_FLAG_DEC_STOP_ISR; */ -/* #endif */ vdin_stop_dec(devp); /*close fe*/ if (devp->frontend->dec_ops->close) @@ -1133,8 +797,10 @@ int stop_tvin_service(int no) devp->flags &= (~VDIN_FLAG_DEC_OPENED); devp->flags &= (~VDIN_FLAG_DEC_STARTED); if ((devp->parm.port != TVIN_PORT_VIU) || - (viu_hw_irq != 0)) + (viu_hw_irq != 0)) { free_irq(devp->irq, (void *)devp); + devp->flags &= (~VDIN_FLAG_ISR_REQ); + } end_time = jiffies_to_msecs(jiffies); if (time_en) pr_info("[vdin]:vdin start time:%ums,stop time:%ums,run time:%u.\n", @@ -1146,7 +812,7 @@ int stop_tvin_service(int no) } EXPORT_SYMBOL(stop_tvin_service); -void get_tvin_canvas_info(int *start, int *num) +static void get_tvin_canvas_info(int *start, int *num) { *start = vdin_canvas_ids[0][0]; *num = vdin_devp[0]->canvas_max_num; @@ -1157,7 +823,6 @@ static int vdin_ioctl_fe(int no, struct fe_arg_s *parm) { struct vdin_dev_s *devp = vdin_devp[no]; int ret = 0; - if (IS_ERR(devp)) { pr_err("[vdin]%s vdin%d has't registered,please register.\n", __func__, no); @@ -1177,11 +842,28 @@ static int vdin_ioctl_fe(int no, struct fe_arg_s *parm) } return ret; } + +/* + * if parm.port is TVIN_PORT_VIU,call vdin_v4l2_isr + * vdin_v4l2_isr is used to the sample + * v4l2 application such as camera,viu + */ static void vdin_rdma_isr(struct vdin_dev_s *devp) { if (devp->parm.port == TVIN_PORT_VIU) vdin_v4l2_isr(devp->irq, devp); } + +/*based on parameter + *parm->cmd : + * VDIN_CMD_SET_CSC + * VDIN_CMD_SET_CM2 + * VDIN_CMD_ISR + * VDIN_CMD_MPEGIN_START + * VDIN_CMD_GET_HISTGRAM + * VDIN_CMD_MPEGIN_STOP + * VDIN_CMD_FORCE_GO_FIELD + */ static int vdin_func(int no, struct vdin_arg_s *arg) { struct vdin_dev_s *devp = vdin_devp[no]; @@ -1197,10 +879,6 @@ static int vdin_func(int no, struct vdin_arg_s *arg) return -1; } else if (!(devp->flags&VDIN_FLAG_DEC_STARTED) && (parm->cmd != VDIN_CMD_MPEGIN_START)) { - if (vdin_dbg_en) - ;/* pr_err("[vdin]%s vdin%d has't started.\n", - * __func__,no); - */ return -1; } if (vdin_dbg_en) @@ -1279,28 +957,38 @@ static struct vdin_v4l2_ops_s vdin_4v4l2_ops = { .tvin_vdin_func = vdin_func, }; +/*call vdin_hw_disable to pause hw*/ void vdin_pause_dec(struct vdin_dev_s *devp) { vdin_hw_disable(devp->addr_offset); } +/*call vdin_hw_enable to resume hw*/ void vdin_resume_dec(struct vdin_dev_s *devp) { vdin_hw_enable(devp->addr_offset); } +/*register provider & notify receiver */ void vdin_vf_reg(struct vdin_dev_s *devp) { vf_reg_provider(&devp->vprov); vf_notify_receiver(devp->name, VFRAME_EVENT_PROVIDER_START, NULL); } +/*unregister provider*/ void vdin_vf_unreg(struct vdin_dev_s *devp) { vf_unreg_provider(&devp->vprov); } -static inline void vdin_set_view(struct vdin_dev_s *devp, struct vframe_s *vf) +/* + * set vframe_view base on parameters: + * left_eye, right_eye, parm.info.trans_fmt + * set view: + * start_x, start_y, width, height + */ +inline void vdin_set_view(struct vdin_dev_s *devp, struct vframe_s *vf) { struct vframe_view_s *left_eye, *right_eye; enum tvin_sig_fmt_e fmt = devp->parm.info.fmt; @@ -1314,33 +1002,29 @@ static inline void vdin_set_view(struct vdin_dev_s *devp, struct vframe_s *vf) left_eye = &vf->left_eye; right_eye = &vf->right_eye; + memset(left_eye, 0, sizeof(struct vframe_view_s)); + memset(right_eye, 0, sizeof(struct vframe_view_s)); + switch (devp->parm.info.trans_fmt) { case TVIN_TFMT_3D_LRH_OLOR: case TVIN_TFMT_3D_LRH_OLER: - left_eye->start_x = 0; - left_eye->start_y = 0; - left_eye->width = devp->h_active >> 1; - left_eye->height = devp->v_active; - right_eye->start_x = devp->h_active >> 1; - right_eye->start_y = 0; - right_eye->width = devp->h_active >> 1; - right_eye->height = devp->v_active; + left_eye->width = devp->h_active >> 1; + left_eye->height = devp->v_active; + right_eye->start_x = devp->h_active >> 1; + right_eye->width = devp->h_active >> 1; + right_eye->height = devp->v_active; break; case TVIN_TFMT_3D_TB: - left_eye->start_x = 0; - left_eye->start_y = 0; - left_eye->width = devp->h_active; - left_eye->height = devp->v_active >> 1; - right_eye->start_x = 0; - right_eye->start_y = devp->v_active >> 1; - right_eye->width = devp->h_active; - right_eye->height = devp->v_active >> 1; + left_eye->width = devp->h_active; + left_eye->height = devp->v_active >> 1; + right_eye->start_y = devp->v_active >> 1; + right_eye->width = devp->h_active; + right_eye->height = devp->v_active >> 1; break; case TVIN_TFMT_3D_FP: { unsigned int vactive = 0; unsigned int vspace = 0; struct vf_entry *slave = NULL; - vspace = fmt_info->vs_front + fmt_info->vs_width + fmt_info->vs_bp; if ((devp->parm.info.fmt == @@ -1355,67 +1039,53 @@ static inline void vdin_set_view(struct vdin_dev_s *devp, struct vframe_s *vf) slave->vf.left_eye.start_x = 0; slave->vf.left_eye.start_y = vactive + vspace + vactive + vspace - 1; - slave->vf.left_eye.width = devp->h_active; - slave->vf.left_eye.height = vactive; + slave->vf.left_eye.width = devp->h_active; + slave->vf.left_eye.height = vactive; slave->vf.right_eye.start_x = 0; slave->vf.right_eye.start_y = vactive + vspace + vactive + vspace + vactive + vspace - 1; - slave->vf.right_eye.width = devp->h_active; + slave->vf.right_eye.width = devp->h_active; slave->vf.right_eye.height = vactive; } else vactive = (fmt_info->v_active - vspace) >> 1; - left_eye->start_x = 0; - left_eye->start_y = 0; - left_eye->width = devp->h_active; - left_eye->height = vactive; - right_eye->start_x = 0; - right_eye->start_y = vactive + vspace; - right_eye->width = devp->h_active; - right_eye->height = vactive; + left_eye->width = devp->h_active; + left_eye->height = vactive; + right_eye->start_y = vactive + vspace; + right_eye->width = devp->h_active; + right_eye->height = vactive; break; - } + } case TVIN_TFMT_3D_FA: { unsigned int vactive = 0; unsigned int vspace = 0; vspace = fmt_info->vs_front + fmt_info->vs_width + fmt_info->vs_bp; - vactive = (fmt_info->v_active - vspace + 1) >> 1; - - left_eye->start_x = 0; - left_eye->start_y = 0; - left_eye->width = devp->h_active; - left_eye->height = vactive; - right_eye->start_x = 0; + left_eye->width = devp->h_active; + left_eye->height = vactive; right_eye->start_y = vactive + vspace; - right_eye->width = devp->h_active; - right_eye->height = vactive; + right_eye->width = devp->h_active; + right_eye->height = vactive; break; } case TVIN_TFMT_3D_LA: { - left_eye->start_x = 0; - left_eye->start_y = 0; - left_eye->width = devp->h_active; - left_eye->height = (devp->v_active) >> 1; - right_eye->start_x = 0; - right_eye->start_y = 0; - right_eye->width = devp->h_active; - right_eye->height = (devp->v_active) >> 1; + left_eye->width = devp->h_active; + left_eye->height = (devp->v_active) >> 1; + right_eye->width = devp->h_active; + right_eye->height = (devp->v_active) >> 1; break; } default: - left_eye->start_x = 0; - left_eye->start_y = 0; - left_eye->width = 0; - left_eye->height = 0; - right_eye->start_x = 0; - right_eye->start_y = 0; - right_eye->width = 0; - right_eye->height = 0; break; } } + +/*function: + * get current field type + * set canvas addr + * disable hw when irq_max_count >= canvas_max_num + */ irqreturn_t vdin_isr_simple(int irq, void *dev_id) { struct vdin_dev_s *devp = (struct vdin_dev_s *)dev_id; @@ -1435,6 +1105,7 @@ irqreturn_t vdin_isr_simple(int irq, void *dev_id) vdin_get_meas_hcnt64(devp->addr_offset)) == -1) return IRQ_HANDLED; /* set canvas address */ + vdin_set_canvas_id(devp, devp->flags&VDIN_FLAG_RDMA_ENABLE, vdin_canvas_ids[devp->index][irq_max_count]); if (vdin_dbg_en) @@ -1447,19 +1118,6 @@ irqreturn_t vdin_isr_simple(int irq, void *dev_id) irq_max_count++; return IRQ_HANDLED; } -#if 0 -/*#ifdef CONFIG_AMLOGIC_LOCAL_DIMMING*/ -unsigned int vdin_ldim_max_global[100] = {0}; -static void vdin_backup_histgram_ldim(struct vframe_s *vf, - struct vdin_dev_s *devp) -{ - unsigned int i = 0; - - for (i = 0; i < 100; i++) - vdin_ldim_max_global[i] = vf->prop.hist.ldim_max[i]; - -} -#endif static void vdin_backup_histgram(struct vframe_s *vf, struct vdin_dev_s *devp) { @@ -1471,13 +1129,13 @@ static void vdin_backup_histgram(struct vframe_s *vf, struct vdin_dev_s *devp) for (i = 0; i < 64; i++) devp->parm.histgram[i] = vf->prop.hist.gamma[i]; } -/*as use the spin_lock, - *1--there is no sleep, - *2--it is better to shorter the time, - *3--it is better to shorter the time, - */ -#define VDIN_MEAS_24M_1MS 24000 +/* + *VDIN_FLAG_RDMA_ENABLE=1 + * provider_vf_put(devp->last_wr_vfe, devp->vfp); + *VDIN_FLAG_RDMA_ENABLE=0 + * provider_vf_put(curr_wr_vfe, devp->vfp); + */ irqreturn_t vdin_isr(int irq, void *dev_id) { ulong flags = 0; @@ -1492,16 +1150,9 @@ irqreturn_t vdin_isr(int irq, void *dev_id) unsigned int stamp = 0; struct tvin_state_machine_ops_s *sm_ops; int vdin2nr = 0; - unsigned int offset; + unsigned int offset, vf_drop_cnt; enum tvin_trans_fmt trans_fmt; struct tvin_sig_property_s *prop, *pre_prop; - /* unsigned long long total_time; */ - /* unsigned long long total_tmp; */ -/* unsigned int vdin0_sw_reset_flag = 0; */ -/* struct vframe_provider_s *p = NULL; */ -/* struct vframe_receiver_s *sub_recv = NULL; */ -/* char provider_name[] = "deinterlace"; */ -/* char provider_vdin0[] = "vdin0"; */ /* debug interrupt interval time * @@ -1510,48 +1161,21 @@ irqreturn_t vdin_isr(int irq, void *dev_id) */ /* ignore fake irq caused by sw reset*/ - if (vdin_reset_flag) { - vdin_reset_flag = 0; + if (devp->vdin_reset_flag) { + devp->vdin_reset_flag = 0; return IRQ_HANDLED; } + vf_drop_cnt = vdin_drop_cnt; /* avoid null pointer oops */ if (!devp || !devp->frontend) { - vdin_irq_flag = 1; + devp->vdin_irq_flag = 1; goto irq_handled; } offset = devp->addr_offset; -/* bug fixed by VLSI guys. */ -/* #if MESON_CPU_TYPE >= MESON_CPU_TYPE_MESONG9TV */ -/* p = vf_get_provider_by_name(provider_name); */ -/* sub_recv = vf_get_receiver(provider_vdin0); */ -/* if((devp->index == 0) && (p != NULL) && */ -/* ((0 != strncasecmp(sub_recv->name,"deinterlace", 11))|| */ -/* ((rd_bits(offset, VDIN_WR_CTRL, 25, 1) == 1)))) { */ -/* if(vdin0_sw_reset_flag != 1) */ -/* vdin0_sw_reset_flag = 1; */ -/* #ifdef CONFIG_AML_RDMA */ -/* rdma_write_reg_bits(devp->rdma_handle, */ -/* VIU_SW_RESET, 1, 23, 1); */ -/* rdma_write_reg_bits(devp->rdma_handle, */ -/* VIU_SW_RESET, 0, 23, 1); */ -/* #else */ -/* W_VCBUS_BIT(VIU_SW_RESET, 1, 23, 1); */ -/* W_VCBUS_BIT(VIU_SW_RESET, 0, 23, 1); */ -/* #endif */ -/* if(rd_bits(offset, VDIN_WR_CTRL, 23,1) != 0) */ -/* wr_bits(offset, VDIN_WR_CTRL, 0, 23, 1); */ -/* } else { */ -/* if (vdin0_sw_reset_flag != 0) */ -/* vdin0_sw_reset_flag = 0; */ -/* if (rd_bits(offset, VDIN_WR_CTRL, 23,1) != 1) */ -/* wr_bits(offset, VDIN_WR_CTRL, 1, 23, 1); */ -/* } */ -/* #endif */ - isr_log(devp->vfp); - irq_cnt++; + devp->irq_cnt++; /* debug interrupt interval time * * this code about system time must be outside of spinlock. @@ -1560,35 +1184,70 @@ irqreturn_t vdin_isr(int irq, void *dev_id) spin_lock_irqsave(&devp->isr_lock, flags); /* W_VCBUS_BIT(VDIN_MISC_CTRL, 0, 0, 2); */ - vdin_reset_flag = vdin_vsync_reset_mif(devp->index); + devp->vdin_reset_flag = vdin_vsync_reset_mif(devp->index); if ((devp->flags & VDIN_FLAG_DEC_STOP_ISR) && (!(isr_flag & VDIN_BYPASS_STOP_CHECK))) { vdin_hw_disable(offset); devp->flags &= ~VDIN_FLAG_DEC_STOP_ISR; - vdin_irq_flag = 2; + devp->vdin_irq_flag = 2; goto irq_handled; } stamp = vdin_get_meas_vstamp(offset); if (!devp->curr_wr_vfe) { devp->curr_wr_vfe = provider_vf_get(devp->vfp); + devp->curr_wr_vfe->vf.ready_jiffies64 = jiffies_64; /*save the first field stamp*/ devp->stamp = stamp; - vdin_irq_flag = 3; - + devp->vdin_irq_flag = 3; + vdin_drop_cnt++; goto irq_handled; } - if (devp->last_wr_vfe && (devp->flags&VDIN_FLAG_RDMA_ENABLE)) { - provider_vf_put(devp->last_wr_vfe, devp->vfp); + if (devp->last_wr_vfe && (devp->flags&VDIN_FLAG_RDMA_ENABLE) && + (devp->game_mode == false)) { + /*dolby vision metadata process*/ + if (dv_dbg_mask & DV_UPDATE_DATA_MODE_DELBY_WORK + && devp->dv.dv_config) { + /* prepare for dolby vision metadata addr */ + devp->dv.dv_cur_index = devp->last_wr_vfe->vf.index; + devp->dv.dv_next_index = devp->curr_wr_vfe->vf.index; + schedule_delayed_work(&devp->dv.dv_dwork, + dv_work_delby); + } else if (((dv_dbg_mask & DV_UPDATE_DATA_MODE_DELBY_WORK) == 0) + && devp->dv.dv_config) { + vdin_dolby_buffer_update(devp, + devp->last_wr_vfe->vf.index); + vdin_dolby_addr_update(devp, + devp->curr_wr_vfe->vf.index); + } else + devp->dv.dv_crc_check = true; + if ((devp->dv.dv_crc_check == true) || + (!(dv_dbg_mask & DV_CRC_CHECK))) + provider_vf_put(devp->last_wr_vfe, devp->vfp); + else { + devp->vdin_irq_flag = 15; + vdin_drop_cnt++; + goto irq_handled; + } + /*skip policy process*/ + if (devp->vfp->skip_vf_num > 0) + vdin_vf_disp_mode_update(devp->last_wr_vfe, devp->vfp); + devp->last_wr_vfe = NULL; - vf_notify_receiver(devp->name, + if (((devp->dv.dolby_input & (1 << devp->index)) || + (devp->dv.dv_flag && is_dolby_vision_enable())) && + (devp->dv.dv_config == true)) + vf_notify_receiver("dv_vdin", + VFRAME_EVENT_PROVIDER_VFRAME_READY, NULL); + else + vf_notify_receiver(devp->name, VFRAME_EVENT_PROVIDER_VFRAME_READY, NULL); } /*check vs is valid base on the time during continuous vs*/ if (vdin_check_cycle(devp) && (!(isr_flag & VDIN_BYPASS_CYC_CHECK)) && (!(devp->flags & VDIN_FLAG_SNOW_FLAG))) { - vdin_irq_flag = 4; - + devp->vdin_irq_flag = 4; + vdin_drop_cnt++; goto irq_handled; } @@ -1600,8 +1259,8 @@ irqreturn_t vdin_isr(int irq, void *dev_id) if (vdin_check_vs(devp) && (!(isr_flag & VDIN_BYPASS_VSYNC_CHECK)) && (!(devp->flags & VDIN_FLAG_SNOW_FLAG))) { - vdin_irq_flag = 5; - + devp->vdin_irq_flag = 5; + vdin_drop_cnt++; goto irq_handled; } sm_ops = devp->frontend->sm_ops; @@ -1614,7 +1273,8 @@ irqreturn_t vdin_isr(int irq, void *dev_id) if (((devp->parm.info.status != TVIN_SIG_STATUS_STABLE) || (state != TVIN_SM_STATUS_STABLE)) && (!(devp->flags & VDIN_FLAG_SNOW_FLAG))) { - vdin_irq_flag = 6; + devp->vdin_irq_flag = 6; + vdin_drop_cnt++; goto irq_handled; } @@ -1627,7 +1287,8 @@ irqreturn_t vdin_isr(int irq, void *dev_id) ((last_field_type & VIDTYPE_INTERLACE_BOTTOM) == VIDTYPE_INTERLACE_BOTTOM) ) { - vdin_irq_flag = 7; + devp->vdin_irq_flag = 7; + vdin_drop_cnt++; goto irq_handled; } curr_wr_vfe = devp->curr_wr_vfe; @@ -1637,14 +1298,49 @@ irqreturn_t vdin_isr(int irq, void *dev_id) if (devp->csc_cfg != 0) { prop = &devp->prop; pre_prop = &devp->pre_prop; - vdin_set_matrix(devp); + if ((prop->color_format != pre_prop->color_format) || + (prop->vdin_hdr_Flag != pre_prop->vdin_hdr_Flag) || + (prop->color_fmt_range != pre_prop->color_fmt_range)) + vdin_set_matrix(devp); + if (prop->dest_cfmt != pre_prop->dest_cfmt) { + vdin_set_bitdepth(devp); + vdin_source_bitdepth_reinit(devp); + vdin_set_wr_ctrl_vsync(devp, devp->addr_offset, + devp->format_convert, + devp->color_depth_mode, devp->source_bitdepth, + devp->flags&VDIN_FLAG_RDMA_ENABLE); + vdin_set_top(devp->addr_offset, devp->parm.port, + devp->prop.color_format, devp->h_active, + devp->bt_path); + } pre_prop->color_format = prop->color_format; pre_prop->vdin_hdr_Flag = prop->vdin_hdr_Flag; pre_prop->color_fmt_range = prop->color_fmt_range; + pre_prop->dest_cfmt = prop->dest_cfmt; } + /* change cutwindow */ + if ((devp->cutwindow_cfg != 0) && (devp->auto_cutwindow_en == 1)) { + prop = &devp->prop; + if (prop->pre_vs || prop->pre_ve) + devp->v_active += (prop->pre_vs + prop->pre_ve); + if (prop->pre_hs || prop->pre_he) + devp->h_active += (prop->pre_hs + prop->pre_he); + vdin_set_cutwin(devp); + prop->pre_vs = prop->vs; + prop->pre_ve = prop->ve; + prop->pre_hs = prop->hs; + prop->pre_he = prop->he; + devp->cutwindow_cfg = 0; + } + if ((devp->auto_cutwindow_en == 1) && + (devp->parm.port >= TVIN_PORT_CVBS0) && + (devp->parm.port <= TVIN_PORT_CVBS7)) + curr_wr_vf->width = devp->h_active; + decops = devp->frontend->dec_ops; if (decops->decode_isr(devp->frontend, devp->hcnt64) == TVIN_BUF_SKIP) { - vdin_irq_flag = 8; + devp->vdin_irq_flag = 8; + vdin_drop_cnt++; goto irq_handled; } if ((devp->parm.port >= TVIN_PORT_CVBS0) && @@ -1655,25 +1351,33 @@ irqreturn_t vdin_isr(int irq, void *dev_id) if (ignore_frames < max_ignore_frames) { ignore_frames++; - vdin_irq_flag = 12; - + devp->vdin_irq_flag = 12; + vdin_drop_cnt++; goto irq_handled; } if (sm_ops->check_frame_skip && sm_ops->check_frame_skip(devp->frontend)) { - vdin_irq_flag = 13; - + devp->vdin_irq_flag = 13; + vdin_drop_cnt++; + if (devp->flags&VDIN_FLAG_RDMA_ENABLE) + ignore_frames = 0; goto irq_handled; } next_wr_vfe = provider_vf_peek(devp->vfp); if (!next_wr_vfe) { - vdin_irq_flag = 14; - + devp->vdin_irq_flag = 14; + vdin_drop_cnt++; goto irq_handled; } - vdin2nr = vf_notify_receiver(devp->name, + if (((devp->dv.dolby_input & (1 << devp->index)) || + (devp->dv.dv_flag && is_dolby_vision_enable())) && + (devp->dv.dv_config == true)) + vdin2nr = vf_notify_receiver("dv_vdin", + VFRAME_EVENT_PROVIDER_QUREY_VDIN2NR, NULL); + else + vdin2nr = vf_notify_receiver(devp->name, VFRAME_EVENT_PROVIDER_QUREY_VDIN2NR, NULL); /*if vdin-nr,di must get * vdin current field type which di pre will read @@ -1699,7 +1403,7 @@ irqreturn_t vdin_isr(int irq, void *dev_id) vdin_set_drm_data(devp, curr_wr_vf); vdin_set_vframe_prop_info(curr_wr_vf, devp); vdin_backup_histgram(curr_wr_vf, devp); - #ifdef CONFIG_AMLOGIC_LOCAL_DIMMING + #ifdef CONFIG_AML_LOCAL_DIMMING /*vdin_backup_histgram_ldim(curr_wr_vf, devp);*/ #endif if ((devp->parm.port >= TVIN_PORT_HDMI0) && @@ -1707,14 +1411,15 @@ irqreturn_t vdin_isr(int irq, void *dev_id) curr_wr_vf->trans_fmt = devp->parm.info.trans_fmt; vdin_set_view(devp, curr_wr_vf); } -#if 0 +#if 1 vdin_calculate_duration(devp); -#endif +#else curr_wr_vf->duration = devp->duration; - /* put for receiver - * ppmgr had handled master and slave vf by itself, - * vdin do not to declare them respectively - * ppmgr put the vf that included master vf and slave vf +#endif + /* put for receiver + * ppmgr had handled master and slave vf by itself, + * vdin do not to declare them respectively + * ppmgr put the vf that included master vf and slave vf */ /*config height according to 3d mode dynamically*/ if (((devp->fmt_info_p->scan_mode == TVIN_SCAN_MODE_INTERLACED) && @@ -1729,45 +1434,85 @@ irqreturn_t vdin_isr(int irq, void *dev_id) (devp->flags & VDIN_FLAG_SNOW_FLAG)) curr_wr_vf->height = 480; curr_wr_vfe->flag |= VF_FLAG_NORMAL_FRAME; - if (devp->flags&VDIN_FLAG_RDMA_ENABLE) + if (devp->auto_ratio_en && (devp->parm.port >= TVIN_PORT_CVBS0) && + (devp->parm.port <= TVIN_PORT_CVBS7)) + vdin_set_display_ratio(devp, curr_wr_vf); + if (devp->flags&VDIN_FLAG_RDMA_ENABLE && (devp->game_mode == false)) { devp->last_wr_vfe = curr_wr_vfe; - else - provider_vf_put(curr_wr_vfe, devp->vfp); - + } else { + /*dolby vision metadata process*/ + if (dv_dbg_mask & DV_UPDATE_DATA_MODE_DELBY_WORK + && devp->dv.dv_config) { + /* prepare for dolby vision metadata addr */ + devp->dv.dv_cur_index = curr_wr_vfe->vf.index; + devp->dv.dv_next_index = next_wr_vfe->vf.index; + schedule_delayed_work(&devp->dv.dv_dwork, + dv_work_delby); + } else if (((dv_dbg_mask & DV_UPDATE_DATA_MODE_DELBY_WORK) == 0) + && devp->dv.dv_config) { + vdin_dolby_buffer_update(devp, curr_wr_vfe->vf.index); + vdin_dolby_addr_update(devp, next_wr_vfe->vf.index); + } else + devp->dv.dv_crc_check = true; + if ((devp->dv.dv_crc_check == true) || + (!(dv_dbg_mask & DV_CRC_CHECK))) + provider_vf_put(curr_wr_vfe, devp->vfp); + else { + devp->vdin_irq_flag = 15; + vdin_drop_cnt++; + goto irq_handled; + } + /*skip policy process*/ + if (devp->vfp->skip_vf_num > 0) + vdin_vf_disp_mode_update(curr_wr_vfe, devp->vfp); + } /* prepare for next input data */ next_wr_vfe = provider_vf_get(devp->vfp); - /* debug for video latency */ - next_wr_vfe->vf.ready_jiffies64 = jiffies_64; vdin_set_canvas_id(devp, (devp->flags&VDIN_FLAG_RDMA_ENABLE), - (next_wr_vfe->vf.canvas0Addr&0xff)); + (next_wr_vfe->vf.canvas0Addr&0xff)); /* prepare for chroma canvas*/ if ((devp->prop.dest_cfmt == TVIN_NV12) || (devp->prop.dest_cfmt == TVIN_NV21)) vdin_set_chma_canvas_id(devp, - (devp->flags&VDIN_FLAG_RDMA_ENABLE), - (next_wr_vfe->vf.canvas0Addr>>8)&0xff); + (devp->flags&VDIN_FLAG_RDMA_ENABLE), + (next_wr_vfe->vf.canvas0Addr>>8)&0xff); devp->curr_wr_vfe = next_wr_vfe; - if (!(devp->flags&VDIN_FLAG_RDMA_ENABLE)) - vf_notify_receiver(devp->name, - VFRAME_EVENT_PROVIDER_VFRAME_READY, NULL); + /* debug for video latency */ + next_wr_vfe->vf.ready_jiffies64 = jiffies_64; + if (!(devp->flags&VDIN_FLAG_RDMA_ENABLE) || (devp->game_mode == true)) { + if (((devp->dv.dolby_input & (1 << devp->index)) || + (devp->dv.dv_flag && is_dolby_vision_enable())) && + (devp->dv.dv_config == true)) + vf_notify_receiver("dv_vdin", + VFRAME_EVENT_PROVIDER_VFRAME_READY, NULL); + else + vf_notify_receiver(devp->name, + VFRAME_EVENT_PROVIDER_VFRAME_READY, NULL); + } irq_handled: + /*hdmi skip policy should adapt to all drop vframe case*/ + if ((devp->vfp->skip_vf_num > 0) && + (vf_drop_cnt < vdin_drop_cnt)) + vdin_vf_disp_mode_skip(devp->vfp); + spin_unlock_irqrestore(&devp->isr_lock, flags); #ifdef CONFIG_AML_RDMA if (devp->flags & VDIN_FLAG_RDMA_ENABLE) rdma_config(devp->rdma_handle, - (rdma_enable&1)?devp->rdma_irq:RDMA_TRIGGER_MANUAL); + (devp->rdma_enable&1) ? + devp->rdma_irq:RDMA_TRIGGER_MANUAL); #endif isr_log(devp->vfp); return IRQ_HANDLED; } /* - * there are too much logic in vdin_isr which is useless in camera&viu - * so vdin_v4l2_isr use to the sample v4l2 application such as camera,viu - */ +* there are too much logic in vdin_isr which is useless in camera&viu +*so vdin_v4l2_isr use to the sample v4l2 application such as camera,viu +*/ static unsigned short skip_ratio = 1; module_param(skip_ratio, ushort, 0664); MODULE_PARM_DESC(skip_ratio, @@ -1788,18 +1533,23 @@ irqreturn_t vdin_v4l2_isr(int irq, void *dev_id) if (!devp) return IRQ_HANDLED; - if (vdin_reset_flag1) { - vdin_reset_flag1 = 0; + if (devp->vdin_reset_flag) { + devp->vdin_reset_flag = 0; return IRQ_HANDLED; } + if (!(devp->flags & VDIN_FLAG_DEC_STARTED)) + return IRQ_HANDLED; isr_log(devp->vfp); - irq_cnt++; + devp->irq_cnt++; spin_lock_irqsave(&devp->isr_lock, flags); - vdin_reset_flag1 = vdin_vsync_reset_mif(devp->index); + devp->vdin_reset_flag = vdin_vsync_reset_mif(devp->index); offset = devp->addr_offset; if (devp) /* avoid null pointer oops */ stamp = vdin_get_meas_vstamp(offset); + /* if win_size changed for video only */ + if (!(devp->flags & VDIN_FLAG_V4L2_DEBUG)) + vdin_set_wr_mif(devp); if (!devp->curr_wr_vfe) { devp->curr_wr_vfe = provider_vf_get(devp->vfp); /*save the first field stamp*/ @@ -1923,37 +1673,37 @@ irq_handled: #ifdef CONFIG_AML_RDMA if (devp->flags & VDIN_FLAG_RDMA_ENABLE) rdma_config(devp->rdma_handle, - (rdma_enable&1)?devp->rdma_irq:RDMA_TRIGGER_MANUAL); + (devp->rdma_enable&1) ? + devp->rdma_irq:RDMA_TRIGGER_MANUAL); #endif isr_log(devp->vfp); return IRQ_HANDLED; } -static void vdin_sig_dwork(struct work_struct *work) + +static void vdin_dv_dwork(struct work_struct *work) { struct delayed_work *dwork = to_delayed_work(work); struct vdin_dev_s *devp = - container_of(dwork, struct vdin_dev_s, sig_dwork); - - struct tvin_info_s *pre_info; + container_of(dwork, struct vdin_dev_s, dv.dv_dwork); if (!devp || !devp->frontend) { pr_info("%s, dwork error !!!\n", __func__); return; } + if (devp->dv.dv_config) { + vdin_dolby_buffer_update(devp, devp->dv.dv_cur_index); + vdin_dolby_addr_update(devp, devp->dv.dv_next_index); + } - pre_info = &devp->pre_info; - - cancel_delayed_work(&devp->sig_dwork); - #if 0 - switch_set_state(&devp->sig_sdev, pre_info->status); - #endif - /* if (vdin_dbg_en) */ - pr_info("%s, dwork signal status: %d\n", - __func__, pre_info->status); + cancel_delayed_work(&devp->dv.dv_dwork); } +/*function:open device + * 1.request irq to open device configure vdinx + * 2.disable irq until vdin is configured completely + */ static int vdin_open(struct inode *inode, struct file *file) { struct vdin_dev_s *devp; @@ -1986,16 +1736,26 @@ static int vdin_open(struct inode *inode, struct file *file) ret = request_irq(devp->irq, vdin_isr, IRQF_SHARED, devp->irq_name, (void *)devp); } - /* disable irq until vdin is configured completely */ + devp->flags |= VDIN_FLAG_ISR_REQ; + /*disable irq until vdin is configured completely*/ disable_irq_nosync(devp->irq); - /* remove the hardware limit to vertical [0-max] */ + /*init queue*/ + init_waitqueue_head(&devp->queue); + + /* remove the hardware limit to vertical [0-max]*/ /* WRITE_VCBUS_REG(VPP_PREBLEND_VD1_V_START_END, 0x00000fff); */ if (vdin_dbg_en) pr_info("open device %s ok\n", dev_name(devp->dev)); return ret; } +/*function: + * close device + * a.vdin_stop_dec + * b.vdin_close_fe + * c.free irq + */ static int vdin_release(struct inode *inode, struct file *file) { struct vdin_dev_s *devp = file->private_data; @@ -2023,35 +1783,44 @@ static int vdin_release(struct inode *inode, struct file *file) devp->flags &= (~VDIN_FLAG_SNOW_FLAG); /* free irq */ - free_irq(devp->irq, (void *)devp); + if (devp->flags & VDIN_FLAG_ISR_REQ) + free_irq(devp->irq, (void *)devp); + devp->flags &= (~VDIN_FLAG_ISR_REQ); file->private_data = NULL; /* reset the hardware limit to vertical [0-1079] */ /* WRITE_VCBUS_REG(VPP_PREBLEND_VD1_V_START_END, 0x00000437); */ - if (vdin_dbg_en) + /*if (vdin_dbg_en)*/ pr_info("close device %s ok\n", dev_name(devp->dev)); return 0; } +/* vdin ioctl cmd: + * TVIN_IOC_OPEN /TVIN_IOC_CLOSE + * TVIN_IOC_START_DEC /TVIN_IOC_STOP_DEC + * TVIN_IOC_VF_REG /TVIN_IOC_VF_UNREG + * TVIN_IOC_G_SIG_INFO /TVIN_IOC_G_BUF_INFO + * TVIN_IOC_G_PARM + * TVIN_IOC_START_GET_BUF /TVIN_IOC_GET_BUF + * TVIN_IOC_PAUSE_DEC /TVIN_IOC_RESUME_DEC + * TVIN_IOC_FREEZE_VF /TVIN_IOC_UNFREEZE_VF + * TVIN_IOC_CALLMASTER_SET + * TVIN_IOC_SNOWON /TVIN_IOC_SNOWOFF + */ static long vdin_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { long ret = 0; + int callmaster_status; struct vdin_dev_s *devp = NULL; void __user *argp = (void __user *)arg; - if (_IOC_TYPE(cmd) != _TM_T) { - pr_err("%s invalid command: %u\n", __func__, cmd); - return -EFAULT; - } - /* Get the per-device structure that contains this cdev */ devp = file->private_data; switch (cmd) { case TVIN_IOC_OPEN: { struct tvin_parm_s parm = {0}; - mutex_lock(&devp->fe_lock); if (copy_from_user(&parm, argp, sizeof(struct tvin_parm_s))) { pr_err("TVIN_IOC_OPEN(%d) invalid parameter\n", @@ -2131,9 +1900,6 @@ static long vdin_ioctl(struct file *file, unsigned int cmd, unsigned long arg) fmt = devp->parm.info.fmt = parm.info.fmt; devp->fmt_info_p = (struct tvin_format_s *)tvin_get_fmt_info(fmt); - /* devp->fmt_info_p = - * tvin_get_fmt_info(devp->parm.info.fmt); - */ if (!devp->fmt_info_p) { pr_err("TVIN_IOC_START_DEC(%d) error, fmt is null\n", devp->index); @@ -2151,7 +1917,6 @@ static long vdin_ioctl(struct file *file, unsigned int cmd, unsigned long arg) } case TVIN_IOC_STOP_DEC: { struct tvin_parm_s *parm = &devp->parm; - mutex_lock(&devp->fe_lock); if (!(devp->flags & VDIN_FLAG_DEC_STARTED)) { pr_err("TVIN_IOC_STOP_DEC(%d) decode havn't started\n", @@ -2166,19 +1931,6 @@ static long vdin_ioctl(struct file *file, unsigned int cmd, unsigned long arg) } devp->flags |= VDIN_FLAG_DEC_STOP_ISR; vdin_stop_dec(devp); - /* - * if (devp->flags & VDIN_FLAG_FORCE_UNSTABLE) - * { - * set_foreign_affairs(FOREIGN_AFFAIRS_00); - * pr_info("video reset vpp.\n"); - * } - * delay_cnt = 7; - * while (get_foreign_affairs(FOREIGN_AFFAIRS_00) && delay_cnt) - * { - * mdelay(10); - * delay_cnt--; - * } - */ /* init flag */ devp->flags &= ~VDIN_FLAG_DEC_STOP_ISR; /* devp->flags &= ~VDIN_FLAG_FORCE_UNSTABLE; */ @@ -2219,7 +1971,6 @@ static long vdin_ioctl(struct file *file, unsigned int cmd, unsigned long arg) case TVIN_IOC_CLOSE: { struct tvin_parm_s *parm = &devp->parm; enum tvin_port_e port = parm->port; - mutex_lock(&devp->fe_lock); if (!(devp->flags & VDIN_FLAG_DEC_OPENED)) { pr_err("TVIN_IOC_CLOSE(%d) you have not opened port\n", @@ -2242,7 +1993,6 @@ static long vdin_ioctl(struct file *file, unsigned int cmd, unsigned long arg) } case TVIN_IOC_S_PARM: { struct tvin_parm_s parm = {0}; - if (copy_from_user(&parm, argp, sizeof(struct tvin_parm_s))) { ret = -EFAULT; break; @@ -2253,7 +2003,6 @@ static long vdin_ioctl(struct file *file, unsigned int cmd, unsigned long arg) } case TVIN_IOC_G_PARM: { struct tvin_parm_s parm; - memcpy(&parm, &devp->parm, sizeof(struct tvin_parm_s)); /* if (devp->flags & VDIN_FLAG_FORCE_UNSTABLE) * parm.info.status = TVIN_SIG_STATUS_UNSTABLE; @@ -2264,7 +2013,6 @@ static long vdin_ioctl(struct file *file, unsigned int cmd, unsigned long arg) } case TVIN_IOC_G_SIG_INFO: { struct tvin_info_s info; - memset(&info, 0, sizeof(struct tvin_info_s)); mutex_lock(&devp->fe_lock); /* if port is not opened, ignore this command */ @@ -2274,10 +2022,6 @@ static long vdin_ioctl(struct file *file, unsigned int cmd, unsigned long arg) break; } memcpy(&info, &devp->parm.info, sizeof(struct tvin_info_s)); - /* if (devp->flags & VDIN_FLAG_FORCE_UNSTABLE) - * info.status = TVIN_SIG_STATUS_UNSTABLE; - */ - if (info.status != TVIN_SIG_STATUS_STABLE) info.fps = 0; @@ -2410,12 +2154,16 @@ static long vdin_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { unsigned long ret; - arg = (unsigned long)compat_ptr(arg); ret = vdin_ioctl(file, cmd, arg); return ret; } #endif + +/*based on parameters: + * mem_start, mem_size + * vm_pgoff, vm_page_prot + */ static int vdin_mmap(struct file *file, struct vm_area_struct *vma) { struct vdin_dev_s *devp = file->private_data; @@ -2449,6 +2197,17 @@ static int vdin_mmap(struct file *file, struct vm_area_struct *vma) return 0; } +static unsigned int vdin_poll(struct file *file, poll_table *wait) +{ + struct vdin_dev_s *devp = file->private_data; + unsigned int mask = 0; + + poll_wait(file, &devp->queue, wait); + mask = (POLLIN | POLLRDNORM); + + return mask; +} + static const struct file_operations vdin_fops = { .owner = THIS_MODULE, .open = vdin_open, @@ -2458,6 +2217,7 @@ static const struct file_operations vdin_fops = { .compat_ioctl = vdin_compat_ioctl, #endif .mmap = vdin_mmap, + .poll = vdin_poll, }; @@ -2467,7 +2227,6 @@ static int vdin_add_cdev(struct cdev *cdevp, { int ret; dev_t devno = MKDEV(MAJOR(vdin_devno), minor); - cdev_init(cdevp, fops); cdevp->owner = THIS_MODULE; ret = cdev_add(cdevp, devno, 1); @@ -2477,7 +2236,6 @@ static int vdin_add_cdev(struct cdev *cdevp, static struct device *vdin_create_device(struct device *parent, int minor) { dev_t devno = MKDEV(MAJOR(vdin_devno), minor); - return device_create(vdin_clsp, parent, devno, NULL, "%s%d", VDIN_DEV_NAME, minor); } @@ -2485,28 +2243,24 @@ static struct device *vdin_create_device(struct device *parent, int minor) static void vdin_delete_device(int minor) { dev_t devno = MKDEV(MAJOR(vdin_devno), minor); - device_destroy(vdin_clsp, devno); } - -static struct resource memobj; -static unsigned long mem_start, mem_end; -static unsigned int use_reserved_mem; static int vdin_drv_probe(struct platform_device *pdev) { int ret = 0; struct vdin_dev_s *vdevp; struct resource *res; - unsigned int bit_mode = 8; + unsigned int urgent_en = 0; + unsigned int bit_mode = VDIN_WR_COLOR_DEPTH_8BIT; /* const void *name; */ /* int offset, size; */ /* struct device_node *of_node = pdev->dev.of_node; */ /* malloc vdev */ - vdevp = kmalloc(sizeof(struct vdin_dev_s), GFP_KERNEL); - if (!vdevp) - goto fail_kmalloc_vdev; - memset(vdevp, 0, sizeof(struct vdin_dev_s)); + vdevp = kzalloc(sizeof(struct vdin_dev_s), GFP_KERNEL); + if (!vdevp) { + goto fail_kzalloc_vdev; + } if (pdev->dev.of_node) { ret = of_property_read_u32(pdev->dev.of_node, "vdin_id", &(vdevp->index)); @@ -2540,66 +2294,11 @@ static int vdin_drv_probe(struct platform_device *pdev) pr_err("%s: fail to create vdin attribute files.\n", __func__); goto fail_create_dev_file; } - /* get memory address from resource */ -#if 0 - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -#elif 0 - res = &memobj; - ret = find_reserve_block(pdev->dev.of_node->name, 0); - if (ret < 0) { - name = of_get_property(of_node, "share-memory-name", NULL); - if (!name) { - pr_err("\nvdin memory resource undefined1.\n"); - ret = -EFAULT; - goto fail_get_resource_mem; - } else { - ret = find_reserve_block_by_name((char *)name); - if (ret < 0) { - pr_err("\nvdin memory resource undefined2.\n"); - ret = -EFAULT; - goto fail_get_resource_mem; - } - name = of_get_property(of_node, - "share-memory-offset", NULL); - if (name) - offset = of_read_ulong(name, 1); - else { - pr_err("\nvdin memory resource undefined3.\n"); - ret = -EFAULT; - goto fail_get_resource_mem; - } - name = of_get_property(of_node, - "share-memory-size", NULL); - if (name) - size = of_read_ulong(name, 1); - else { - pr_err("\nvdin memory resource undefined4.\n"); - ret = -EFAULT; - goto fail_get_resource_mem; - } - res->start = - (phys_addr_t)get_reserve_block_addr(ret)+offset; - res->end = res->start + size-1; - } - } else { - res->start = (phys_addr_t)get_reserve_block_addr(ret); - res->end = res->start + - (phys_addr_t)get_reserve_block_size(ret)-1; - } -#else - res = &memobj; ret = of_reserved_mem_device_init(&pdev->dev); if (ret == 0) pr_info("\n vdin memory resource done.\n"); else pr_info("\n vdin memory resource undefined!!\n"); -#endif -/* if (!res) { */ -/* pr_err("%s: can't get mem resource !!!!!!!!!!\n", __func__); */ -/* ret = -ENXIO; */ -/* goto fail_get_resource_mem; */ -/* } */ -/* */ #ifdef CONFIG_CMA if (!use_reserved_mem) { ret = of_property_read_u32(pdev->dev.of_node, @@ -2608,7 +2307,7 @@ static int vdin_drv_probe(struct platform_device *pdev) pr_err("don't find match flag_cma\n"); vdevp->cma_config_flag = 0; } - if (vdevp->cma_config_flag == 1) { + if (vdevp->cma_config_flag & 0x1) { ret = of_property_read_u32(pdev->dev.of_node, "cma_size", &(vdevp->cma_mem_size)); @@ -2616,7 +2315,7 @@ static int vdin_drv_probe(struct platform_device *pdev) pr_err("don't find match cma_size\n"); else vdevp->cma_mem_size *= SZ_1M; - } else if (vdevp->cma_config_flag == 0) + } else vdevp->cma_mem_size = dma_get_cma_size_int_byte(&pdev->dev); vdevp->this_pdev = pdev; @@ -2627,32 +2326,15 @@ static int vdin_drv_probe(struct platform_device *pdev) } #endif use_reserved_mem = 0; + /*use reserved mem*/ if (vdevp->cma_config_en != 1) { vdevp->mem_start = mem_start; - vdevp->mem_size = mem_end - mem_start + 1; - pr_info("vdin%d mem_start = 0x%x, mem_size = 0x%x\n", + vdevp->mem_size = mem_end - mem_start + 1; + pr_info("vdin%d mem_start = 0x%lx, mem_size = 0x%x\n", vdevp->index, vdevp->mem_start, vdevp->mem_size); } /* get irq from resource */ - #if 0/* def CONFIG_USE_OF */ - if (pdev->dev.of_node) { - ret = of_property_read_u32(pdev->dev.of_node, - "interrupts", &(res->start)); - if (ret) { - pr_err("don't find match irq\n"); - goto fail_get_resource_irq; - } - ret = of_property_read_u32(pdev->dev.of_node, - "rdma-irq", &(vdevp->rdma_irq)); - if (ret) { - pr_err("don't find match rdma irq, disable rdma\n"); - vdevp->rdma_irq = 0; - } - res->end = res->start; - res->flags = IORESOURCE_IRQ; - } - #else res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); if (!res) { pr_err("%s: can't get irq resource\n", __func__); @@ -2665,29 +2347,37 @@ static int vdin_drv_probe(struct platform_device *pdev) pr_err("don't find match rdma irq, disable rdma\n"); vdevp->rdma_irq = 0; } - /* vdin0 for tv */ - if (vdevp->index == 0) { - ret = of_property_read_u32(pdev->dev.of_node, - "tv_bit_mode", &bit_mode); - if (ret) - pr_info("no bit mode found, set 8bit as default\n"); - vdevp->color_depth_support = bit_mode; - vdevp->color_depth_config = 0; - } - if (vdevp->color_depth_support&VDIN_WR_COLOR_DEPTH_10BIT_FULL_PCAK_MODE) - vdevp->color_depth_mode = 1; - else - vdevp->color_depth_mode = 0; - #endif vdevp->irq = res->start; snprintf(vdevp->irq_name, sizeof(vdevp->irq_name), "vdin%d-irq", vdevp->index); pr_info("vdin%d irq: %d rdma irq: %d\n", vdevp->index, vdevp->irq, vdevp->rdma_irq); + + /*set color_depth_mode*/ + ret = of_property_read_u32(pdev->dev.of_node, + "tv_bit_mode", &bit_mode); + if (ret) + pr_info("no bit mode found, set 8bit as default\n"); + + vdevp->color_depth_support = bit_mode; + vdevp->color_depth_config = 0; + + if (vdevp->color_depth_support&VDIN_WR_COLOR_DEPTH_10BIT_FULL_PCAK_MODE) + vdevp->color_depth_mode = 1; + else + vdevp->color_depth_mode = 0; + + /*vdin urgent en*/ + ret = of_property_read_u32(pdev->dev.of_node, + "urgent_en", &urgent_en); + if (ret) { + vdevp->urgent_en = 0; + pr_info("no urgent_en found\n"); + } else + vdevp->urgent_en = urgent_en; /* init vdin parameters */ vdevp->flags = VDIN_FLAG_NULL; vdevp->flags &= (~VDIN_FLAG_FS_OPENED); - mutex_init(&vdevp->mm_lock); mutex_init(&vdevp->fe_lock); spin_lock_init(&vdevp->isr_lock); vdevp->frontend = NULL; @@ -2696,27 +2386,31 @@ static int vdin_drv_probe(struct platform_device *pdev) if (is_meson_gxbb_cpu() && vdevp->index) vdin_addr_offset[vdevp->index] = 0x70; vdevp->addr_offset = vdin_addr_offset[vdevp->index]; - vdevp->flags = 0; - /*mif reset patch for vdin wr ram bug on gxtvbb*/ if (is_meson_gxtvbb_cpu()) enable_reset = 1; else enable_reset = 0; - + /* 1: gxtvbb vdin out full range, */ + /* 0: >=txl vdin out limit range, */ + if (get_cpu_type() == MESON_CPU_MAJOR_ID_GXTVBB) + vdevp->color_range_mode = 1; + else + vdevp->color_range_mode = 0; /* create vf pool */ vdevp->vfp = vf_pool_alloc(VDIN_CANVAS_MAX_CNT); if (vdevp->vfp == NULL) { pr_err("%s: fail to alloc vf pool.\n", __func__); goto fail_alloc_vf_pool; } - - /* init vframe provider */ /* @todo provider name */ sprintf(vdevp->name, "%s%d", PROVIDER_NAME, vdevp->index); vf_provider_init(&vdevp->vprov, vdevp->name, &vdin_vf_ops, vdevp->vfp); + + vf_provider_init(&vdevp->dv.vprov_dv, "dv_vdin", + &vdin_vf_ops, vdevp->vfp); /* @todo canvas_config_mode */ if (canvas_config_mode == 0 || canvas_config_mode == 1) vdin_canvas_init(vdevp); @@ -2779,15 +2473,21 @@ static int vdin_drv_probe(struct platform_device *pdev) } /*disable vdin hardware*/ vdin_enable_module(vdevp->addr_offset, false); + /*enable auto cutwindow for atv*/ + if (vdevp->index == 0) { + vdevp->auto_cutwindow_en = 1; + vdevp->auto_ratio_en = 1; + #ifdef CONFIG_CMA + vdevp->cma_mem_mode = 1; + #endif + } + vdevp->rdma_enable = 1; + /*set vdin_dev_s size*/ + vdevp->vdin_dev_ssize = sizeof(struct vdin_dev_s); + vdevp->game_mode = game_mode; + vdevp->canvas_config_mode = canvas_config_mode; + INIT_DELAYED_WORK(&vdevp->dv.dv_dwork, vdin_dv_dwork); - vdevp->sig_wq = create_singlethread_workqueue(vdevp->name); - INIT_DELAYED_WORK(&vdevp->sig_dwork, vdin_sig_dwork); - #if 0 - vdevp->sig_sdev.name = vdevp->name; - ret = switch_dev_register(&vdevp->sig_sdev); - if (ret < 0) - pr_err("[vdin] %d: register sdev error.\n", vdevp->index); - #endif pr_info("%s: driver initialized ok\n", __func__); return 0; @@ -2799,20 +2499,24 @@ fail_create_device: cdev_del(&vdevp->cdev); fail_add_cdev: kfree(vdevp); -fail_kmalloc_vdev: +fail_kzalloc_vdev: return ret; } +/*this function is used for removing driver + * free the vframe pool + * remove device files + * delet vdinx device + * free drvdata + */ static int vdin_drv_remove(struct platform_device *pdev) { struct vdin_dev_s *vdevp; - vdevp = platform_get_drvdata(pdev); #ifdef CONFIG_AML_RDMA rdma_unregister(vdevp->rdma_handle); #endif - mutex_destroy(&vdevp->mm_lock); mutex_destroy(&vdevp->fe_lock); vf_pool_free(vdevp->vfp); @@ -2824,7 +2528,6 @@ static int vdin_drv_remove(struct platform_device *pdev) /* free drvdata */ dev_set_drvdata(vdevp->dev, NULL); platform_set_drvdata(pdev, NULL); - kfree(vdevp); pr_info("%s: driver removed ok\n", __func__); return 0; @@ -2848,6 +2551,7 @@ static int vdin_drv_suspend(struct platform_device *pdev, pm_message_t state) #endif cpumask_copy(&vdinirq_mask, mask); } + vdevp->flags |= VDIN_FLAG_SUSPEND; vdin_enable_module(vdevp->addr_offset, false); pr_info("%s ok.\n", __func__); return 0; @@ -2867,6 +2571,7 @@ static int vdin_drv_resume(struct platform_device *pdev) irq_set_affinity(vdevp->irq, &vdinirq_mask); } + vdevp->flags &= (~VDIN_FLAG_SUSPEND); pr_info("%s ok.\n", __func__); return 0; } @@ -2877,8 +2582,10 @@ static void vdin_drv_shutdown(struct platform_device *pdev) struct vdin_dev_s *vdevp; vdevp = platform_get_drvdata(pdev); + vdevp->flags |= VDIN_FLAG_SM_DISABLE; vdin_enable_module(vdevp->addr_offset, false); pr_info("%s ok.\n", __func__); + return; } static const struct of_device_id vdin_dt_match[] = { @@ -2902,7 +2609,6 @@ static struct platform_driver vdin_driver = { /* extern int vdin_reg_v4l2(struct vdin_v4l2_ops_s *v4l2_ops); */ /* extern void vdin_unreg_v4l2(void); */ - static int __init vdin_drv_init(void) { int ret = 0; @@ -2920,19 +2626,20 @@ static int __init vdin_drv_init(void) pr_err("%s: failed to create class\n", __func__); goto fail_class_create; } - +#ifdef DEBUG_SUPPORT ret = vdin_create_class_files(vdin_clsp); if (ret != 0) { pr_err("%s: failed to create class !!\n", __func__); goto fail_pdrv_register; } +#endif ret = platform_driver_register(&vdin_driver); if (ret != 0) { pr_err("%s: failed to register driver\n", __func__); goto fail_pdrv_register; } - /* register vdin for v4l2 interface */ + /*register vdin for v4l2 interface*/ if (vdin_reg_v4l2(&vdin_4v4l2_ops)) pr_err("[vdin] %s: register vdin v4l2 error.\n", __func__); pr_info("%s: vdin driver init done\n", __func__); @@ -2949,7 +2656,9 @@ fail_alloc_cdev_region: static void __exit vdin_drv_exit(void) { vdin_unreg_v4l2(); +#ifdef DEBUG_SUPPORT vdin_remove_class_files(vdin_clsp); +#endif class_destroy(vdin_clsp); unregister_chrdev_region(vdin_devno, VDIN_MAX_DEVS); platform_driver_unregister(&vdin_driver); @@ -2986,6 +2695,7 @@ static int __init vdin_mem_setup(struct reserved_mem *rmem) return 0; } + module_init(vdin_drv_init); module_exit(vdin_drv_exit); @@ -2996,170 +2706,3 @@ MODULE_VERSION(VDIN_VER); MODULE_DESCRIPTION("AMLOGIC VDIN Driver"); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Xu Lin "); - -#ifdef CONFIG_TVIN_VDIN_CTRL -int vdin_ctrl_open_fe(int no, int port) -{ - int ret = 0; - struct vdin_dev_s *devp = vdin_devp[no]; - - if (IS_ERR(devp)) { - pr_err("[vdin]%s vdin%d has't registered,please register.\n", - __func__, no); - return -1; - } - if (devp->flags & VDIN_FLAG_DEC_STARTED) { - pr_err("%s: port 0x%x, decode started already.\n", - __func__, port); - ret = -EBUSY; - } - - devp->flags |= VDIN_FLAG_FS_OPENED; - /* request irq */ - snprintf(devp->irq_name, sizeof(devp->irq_name), - "vdin%d-irq", devp->index); - if (work_mode_simple) { - pr_info("vdin work in simple mode\n"); - ret = request_irq(devp->irq, vdin_isr_simple, IRQF_SHARED, - devp->irq_name, (void *)devp); - } else { - pr_info("vdin work in normal mode\n"); - ret = request_irq(devp->irq, vdin_isr, IRQF_SHARED, - devp->irq_name, (void *)devp); - } - - /* disable irq until vdin is configured completely */ - disable_irq_nosync(devp->irq); - /* remove the hardware limit to vertical [0-max]*/ - /* aml_write_vcbus(VPP_PREBLEND_VD1_V_START_END, 0x00000fff); */ - pr_info("open device %s ok\n", dev_name(devp->dev)); - vdin_open_fe(port, 0, devp); - devp->parm.port = port; - devp->parm.info.fmt = TVIN_SIG_FMT_NULL; - return 0; -} - -int vdin_ctrl_close_fe(int no) -{ - struct vdin_dev_s *devp; - - devp = vdin_devp[no]; - del_timer_sync(&devp->timer); - - /* close fe */ - if (devp->frontend->dec_ops->close) - devp->frontend->dec_ops->close(devp->frontend); - /* free the memory allocated in start tvin service */ - if (devp->parm.info.fmt >= TVIN_SIG_FMT_MAX) - kfree(devp->fmt_info_p); - devp->flags &= (~VDIN_FLAG_DEC_OPENED); - devp->flags &= (~VDIN_FLAG_DEC_STARTED); - /* free irq */ - free_irq(devp->irq, (void *)devp); - return 0; -} - - -int vdin_ctrl_start_fe(int no, struct vdin_parm_s *para) -{ - struct tvin_frontend_s *fe; - int ret = 0; - struct vdin_dev_s *devp = vdin_devp[no]; - - if (IS_ERR(devp)) { - pr_err("[vdin]%s vdin%d has't registered,please register.\n", - __func__, no); - return -1; - } - if (devp->flags & VDIN_FLAG_DEC_STARTED) { - pr_err("%s: port 0x%x, decode started already.\n", - __func__, para->port); - ret = -EBUSY; - } - - devp->parm.port = para->port; - devp->parm.info.fmt = para->fmt; - /* add for camera random resolution */ - if (para->fmt >= TVIN_SIG_FMT_MAX) { - devp->fmt_info_p = kmalloc(sizeof(struct tvin_format_s), - GFP_KERNEL); - if (!devp->fmt_info_p) - return -ENOMEM; - devp->fmt_info_p->hs_bp = para->hs_bp; - devp->fmt_info_p->vs_bp = para->vs_bp; - devp->fmt_info_p->hs_pol = para->hsync_phase; - devp->fmt_info_p->vs_pol = para->vsync_phase; - devp->fmt_info_p->h_active = para->h_active; - devp->fmt_info_p->v_active = para->v_active; - devp->fmt_info_p->scan_mode = para->scan_mode; - devp->fmt_info_p->duration = 96000/para->frame_rate; - devp->fmt_info_p->pixel_clk = - para->h_active*para->v_active*para->frame_rate; - devp->fmt_info_p->pixel_clk /= 10000; - } else { - devp->fmt_info_p = (struct tvin_format_s *) - tvin_get_fmt_info(devp->parm.info.fmt); - } - if (!devp->fmt_info_p) { - pr_err("%s(%d): error, fmt is null!!!\n", __func__, no); - return -1; - } - fe = tvin_get_frontend(para->port, 0); - if (fe) { - fe->private_data = para; - fe->port = para->port; - devp->frontend = fe; - - } else { - pr_err("%s(%d): not supported port 0x%x\n", - __func__, no, para->port); - return -1; - } - /* disable cut window? */ - devp->parm.cutwin.he = 0; - devp->parm.cutwin.hs = 0; - devp->parm.cutwin.ve = 0; - devp->parm.cutwin.vs = 0; - /*add for viu loop back scaler down*/ - if (para->port == TVIN_PORT_VIU) { - devp->scaler4w = para->reserved & 0xffff; - devp->scaler4h = para->reserved >> 16; - } -/* #ifdef CONFIG_ARCH_MESON6 */ -/* switch_mod_gate_by_name("vdin", 1); */ -/* #endif */ - vdin_start_dec(devp); - devp->flags = VDIN_FLAG_DEC_OPENED; - devp->flags |= VDIN_FLAG_DEC_STARTED; - return 0; -} - -int vdin_ctrl_stop_fe(int no) -{ - struct vdin_dev_s *devp; - - devp = vdin_devp[no]; - if (!(devp->flags&VDIN_FLAG_DEC_STARTED)) { - pr_err("%s:decode hasn't started.\n", __func__); - return -EBUSY; - } - devp->flags |= VDIN_FLAG_DEC_STOP_ISR; - vdin_stop_dec(devp); - - devp->flags &= (~VDIN_FLAG_DEC_STARTED); - - return 0; -} - -enum tvin_sig_fmt_e vdin_ctrl_get_fmt(int no) -{ - struct vdin_dev_s *devp; - - devp = vdin_devp[no]; - if (devp->frontend && devp->frontend->sm_ops) - return devp->frontend->sm_ops->get_fmt(devp->frontend); - - return TVIN_SIG_FMT_NULL; - -} -#endif diff --git a/drivers/amlogic/media/vin/tvin/vdin/vdin_drv.h b/drivers/amlogic/media/vin/tvin/vdin/vdin_drv.h index b236cd565bea..c3e66536821f 100644 --- a/drivers/amlogic/media/vin/tvin/vdin/vdin_drv.h +++ b/drivers/amlogic/media/vin/tvin/vdin/vdin_drv.h @@ -20,7 +20,6 @@ /* Standard Linux Headers */ #include -#include #include #include #include @@ -28,9 +27,6 @@ #include #include #include -#if 0 /*todo: instead switch in linux 4.4?*/ -#include -#endif #include /* Amlogic Headers */ @@ -45,12 +41,11 @@ #endif /* Local Headers */ -#include "../tvin_global.h" #include "../tvin_frontend.h" #include "vdin_vf.h" #include "vdin_regs.h" -#define VDIN_VER "Ref.2016/10/14" +#define VDIN_VER "Ref.2017/011/17" /*the counter of vdin*/ #define VDIN_MAX_DEVS 2 @@ -78,12 +73,18 @@ #define VDIN_FLAG_SNOW_FLAG 0x00004000 /*flag for disable vdin sm*/ #define VDIN_FLAG_SM_DISABLE 0x00008000 +/*flag for vdin suspend state*/ +#define VDIN_FLAG_SUSPEND 0x00010000 +/*flag for vdin-v4l2 debug*/ +#define VDIN_FLAG_V4L2_DEBUG 0x00020000 +/*flag for isr req&free*/ +#define VDIN_FLAG_ISR_REQ 0x00040000 /*values of vdin isr bypass check flag */ #define VDIN_BYPASS_STOP_CHECK 0x00000001 #define VDIN_BYPASS_CYC_CHECK 0x00000002 #define VDIN_BYPASS_VSYNC_CHECK 0x00000004 #define VDIN_BYPASS_VGA_CHECK 0x00000008 - +#define VDIN_CANVAS_MAX_CNT 9 /*flag for flush vdin buff*/ #define VDIN_FLAG_BLACK_SCREEN_ON 1 @@ -100,191 +101,216 @@ /*TXL new add*/ #define VDIN_WR_COLOR_DEPTH_10BIT_FULL_PCAK_MODE (1 << 4) + static inline const char *vdin_fmt_convert_str( enum vdin_format_convert_e fmt_cvt) { switch (fmt_cvt) { case VDIN_FORMAT_CONVERT_YUV_YUV422: return "FMT_CONVERT_YUV_YUV422"; + break; case VDIN_FORMAT_CONVERT_YUV_YUV444: return "FMT_CONVERT_YUV_YUV444"; + break; case VDIN_FORMAT_CONVERT_YUV_RGB: return "FMT_CONVERT_YUV_RGB"; + break; case VDIN_FORMAT_CONVERT_RGB_YUV422: return "FMT_CONVERT_RGB_YUV422"; + break; case VDIN_FORMAT_CONVERT_RGB_YUV444: return "FMT_CONVERT_RGB_YUV444"; + break; case VDIN_FORMAT_CONVERT_RGB_RGB: return "FMT_CONVERT_RGB_RGB"; + break; case VDIN_FORMAT_CONVERT_YUV_NV12: return "VDIN_FORMAT_CONVERT_YUV_NV12"; + break; case VDIN_FORMAT_CONVERT_YUV_NV21: return "VDIN_FORMAT_CONVERT_YUV_NV21"; + break; case VDIN_FORMAT_CONVERT_RGB_NV12: return "VDIN_FORMAT_CONVERT_RGB_NV12"; + break; case VDIN_FORMAT_CONVERT_RGB_NV21: return "VDIN_FORMAT_CONVERT_RGB_NV21"; + break; default: return "FMT_CONVERT_NULL"; + break; } } /*******for debug **********/ struct vdin_debug_s { - struct tvin_cutwin_s cutwin; - unsigned short scaler4h;/* for vscaler */ - unsigned short scaler4w;/* for hscaler */ - unsigned short dest_cfmt;/* for color fmt conversion */ + struct tvin_cutwin_s cutwin; + unsigned short scaler4h;/* for vscaler */ + unsigned short scaler4w;/* for hscaler */ + unsigned short dest_cfmt;/* for color fmt conversion */ +}; +struct vdin_dv_s { + struct vframe_provider_s vprov_dv; + struct delayed_work dv_dwork; + unsigned int dv_cur_index; + unsigned int dv_next_index; + unsigned int dolby_input; + dma_addr_t dv_dma_paddr; + void *dv_dma_vaddr; + unsigned int dv_flag_cnt;/*cnt for no dv input*/ + bool dv_flag; + bool dv_config; + bool dv_crc_check;/*0:fail;1:ok*/ }; struct vdin_dev_s { - unsigned int index; - unsigned int vdin_max_pixelclk; - dev_t devt; - struct cdev cdev; - struct device *dev; + struct cdev cdev; + struct device *dev; + struct tvin_parm_s parm; + struct tvin_format_s *fmt_info_p; + struct vf_pool *vfp; + struct tvin_frontend_s *frontend; + struct tvin_sig_property_s pre_prop; + struct tvin_sig_property_s prop; + struct vframe_provider_s vprov; + struct vdin_dv_s dv; - char name[15]; - /* bit0 TVIN_PARM_FLAG_CAP bit31: TVIN_PARM_FLAG_WORK_ON */ - unsigned int flags; - - - unsigned int mem_start; - unsigned int mem_size; - - /* start address of captured frame data [8 bits] in memory */ - /* for Component input, frame data [8 bits] order is - * Y0Cb0Y1Cr0��Y2nCb2nY2n+1Cr2n�� - */ - /* for VGA input, frame data [8 bits] order is - * R0G0B0��RnGnBn�� - */ - unsigned int cap_addr; - unsigned int cap_size; - - unsigned int h_active; - unsigned int v_active; - enum vdin_format_convert_e format_convert; - - enum vframe_source_type_e source_type; - enum vframe_source_mode_e source_mode; - unsigned int source_bitdepth; - unsigned int *canvas_ids; - unsigned int canvas_h; - unsigned int canvas_w; - unsigned int canvas_max_size; - unsigned int canvas_max_num; - struct vf_entry *curr_wr_vfe; - struct vf_entry *last_wr_vfe; - unsigned int curr_field_type; - - unsigned int irq; - unsigned int rdma_irq; - char irq_name[12]; - /* address offset(vdin0/vdin1/...) */ - unsigned int addr_offset; - unsigned int vga_clr_cnt; - unsigned int vs_cnt_valid; - unsigned int vs_cnt_ignore; - struct tvin_parm_s parm; - struct tvin_format_s *fmt_info_p; - struct vf_pool *vfp; - - struct tvin_frontend_s *frontend; - struct tvin_sig_property_s pre_prop; - struct tvin_sig_property_s prop; - struct vframe_provider_s vprov; /* 0:from gpio A,1:from csi2 , 2:gpio B*/ - enum bt_path_e bt_path; + enum bt_path_e bt_path; + struct timer_list timer; + spinlock_t isr_lock; + struct mutex fe_lock; + struct clk *msr_clk; + unsigned int msr_clk_val; + struct vdin_debug_s debug; + enum vdin_format_convert_e format_convert; + unsigned int source_bitdepth; - struct timer_list timer; - spinlock_t dec_lock; - struct tasklet_struct isr_tasklet; - spinlock_t isr_lock; - struct mutex mm_lock; /* lock for mmap */ - struct mutex fe_lock; + struct vf_entry *curr_wr_vfe; + struct vf_entry *last_wr_vfe; + unsigned int curr_field_type; - unsigned int unstable_flag; - unsigned int dec_enable; - unsigned int abnormal_cnt; - /* bool stamp_valid; use vfe replace tell the first frame */ - unsigned int stamp; - unsigned int hcnt64; - unsigned int cycle; - unsigned int hcnt64_tag; - unsigned int cycle_tag; - unsigned int start_time;/* ms vdin start time */ - bool send2di; - int rdma_handle; - struct clk *msr_clk; - unsigned int msr_clk_val; + char name[15]; + /* bit0 TVIN_PARM_FLAG_CAP bit31: TVIN_PARM_FLAG_WORK_ON */ + unsigned int flags; + unsigned int index; + unsigned int vdin_max_pixelclk; - /* signal event */ - struct delayed_work sig_dwork; - struct workqueue_struct *sig_wq; - #if 0 - struct switch_dev sig_sdev; - #endif - struct tvin_info_s pre_info; + unsigned long mem_start; + unsigned int mem_size; + unsigned long vfmem_start[VDIN_CANVAS_MAX_CNT]; + struct page *vfvenc_pages[VDIN_CANVAS_MAX_CNT]; + unsigned int vfmem_size; + unsigned int vfmem_max_cnt; - struct vdin_debug_s debug; - unsigned int cma_config_en; - /*cma_config_flag:1:share with codec_mm;0:cma alone*/ - unsigned int cma_config_flag; + unsigned int h_active; + unsigned int v_active; + unsigned int canvas_h; + unsigned int canvas_w; + unsigned int canvas_active_w; + unsigned int canvas_alin_w; + unsigned int canvas_max_size; + unsigned int canvas_max_num; + + unsigned int irq; + unsigned int rdma_irq; + char irq_name[12]; + /* address offset(vdin0/vdin1/...) */ + unsigned int addr_offset; + unsigned int vs_cnt_valid; + unsigned int vs_cnt_ignore; + + unsigned int unstable_flag; + unsigned int abnormal_cnt; + unsigned int stamp; + unsigned int hcnt64; + unsigned int cycle; + unsigned int hcnt64_tag; + unsigned int cycle_tag; + unsigned int start_time;/* ms vdin start time */ + int rdma_handle; + + bool cma_config_en; + /*cma_config_flag: + *bit0: (1:share with codec_mm;0:cma alone) + *bit8: (1:discontinuous alloc way;0:continuous alloc way) + */ + unsigned int cma_config_flag; #ifdef CONFIG_CMA struct platform_device *this_pdev; - struct page *venc_pages; - unsigned int cma_mem_size;/*BYTE*/ - unsigned int cma_mem_alloc; + struct page *venc_pages; + unsigned int cma_mem_size;/*BYTE*/ + unsigned int cma_mem_alloc; + /*cma_mem_mode:0:according to input size and output fmt; + **1:according to input size and output fmt force as YUV444 + */ + unsigned int cma_mem_mode; + unsigned int force_yuv444_malloc; #endif /* bit0: enable/disable; bit4: luma range info */ - unsigned int csc_cfg; + bool csc_cfg; /* duration of current timing */ - unsigned int duration; + unsigned int duration; /* color-depth for vdin write */ - /* vdin write mem color depth support: - * bit0:support 8bit - * bit1:support 9bit - * bit2:support 10bit - * bit3:support 12bit - * bit4:support yuv422 10bit full pack mode (from txl new add) + /*vdin write mem color depth support: + *bit0:support 8bit + *bit1:support 9bit + *bit2:support 10bit + *bit3:support 12bit + *bit4:support yuv422 10bit full pack mode (from txl new add) */ - unsigned int color_depth_support; - /* color depth config - * 0:auto config as frontend - * 8:force config as 8bit - * 10:force config as 10bit - * 12:force config as 12bit + unsigned int color_depth_support; + /*color depth config + *0:auto config as frontend + *8:force config as 8bit + *10:force config as 10bit + *12:force config as 12bit */ - unsigned int color_depth_config; + unsigned int color_depth_config; /* new add from txl:color depth mode for 10bit - * 1: full pack mode;config 10bit as 10bit - * 0: config 10bit as 12bit + *1: full pack mode;config 10bit as 10bit + *0: config 10bit as 12bit */ - unsigned int color_depth_mode; + unsigned int color_depth_mode; + /* cutwindow config */ + bool cutwindow_cfg; + bool auto_cutwindow_en; + /* + *1:vdin out limit range + *0:vdin out full range + */ + unsigned int color_range_mode; + /*auto detect av/atv input ratio*/ + unsigned int auto_ratio_en; + bool game_mode;/*1:game mode for hdmi*/ + unsigned int rdma_enable; + unsigned int canvas_config_mode; + bool prehsc_en; + bool vshrk_en; + bool urgent_en; + bool black_bar_enable; + bool hist_bar_enable; + /*use frame rate to cal duraton*/ + unsigned int use_frame_rate; + unsigned int irq_cnt; + unsigned int rdma_irq_cnt; + unsigned int vdin_irq_flag; + unsigned int vdin_reset_flag; + unsigned int vdin_dev_ssize; + wait_queue_head_t queue; }; - - -#ifdef CONFIG_TVIN_VDIN_CTRL -int vdin_ctrl_open_fe(int no, int port); -int vdin_ctrl_close_fe(int no); -int vdin_ctrl_start_fe(int no, struct vdin_parm_s *para); -int vdin_ctrl_stop_fe(int no); -enum tvin_sig_fmt_e vdin_ctrl_get_fmt(int no); -#endif -extern bool enable_reset; -extern unsigned int max_buf_num; -extern unsigned int vdin_ldim_max_global[100]; extern struct vframe_provider_s *vf_get_provider_by_name( const char *provider_name); - +extern bool enable_reset; +extern unsigned int dolby_size_byte; +extern unsigned int dv_dbg_mask; +extern char *vf_get_receiver_name(const char *provider_name); extern int start_tvin_service(int no, struct vdin_parm_s *para); extern int stop_tvin_service(int no); extern int vdin_reg_v4l2(struct vdin_v4l2_ops_s *v4l2_ops); extern void vdin_unreg_v4l2(void); - extern int vdin_create_class_files(struct class *vdin_clsp); extern void vdin_remove_class_files(struct class *vdin_clsp); extern int vdin_create_device_files(struct device *dev); @@ -307,5 +333,6 @@ extern void vdin_vf_reg(struct vdin_dev_s *devp); extern void vdin_vf_unreg(struct vdin_dev_s *devp); extern void vdin_pause_dec(struct vdin_dev_s *devp); extern void vdin_resume_dec(struct vdin_dev_s *devp); +extern bool is_dolby_vision_enable(void); #endif /* __TVIN_VDIN_DRV_H */ diff --git a/drivers/amlogic/media/vin/tvin/vdin/vdin_regs.h b/drivers/amlogic/media/vin/tvin/vdin/vdin_regs.h index 1f6006b11620..7873e4bc9eea 100644 --- a/drivers/amlogic/media/vin/tvin/vdin/vdin_regs.h +++ b/drivers/amlogic/media/vin/tvin/vdin/vdin_regs.h @@ -18,11 +18,12 @@ #ifndef __VDIN_REGS_H #define __VDIN_REGS_H - /* mmc */ #define VPU_VDIN_ASYNC_HOLD_CTRL 0x2743 #define VPU_VDISP_ASYNC_HOLD_CTRL 0x2744 #define VPU_VPUARB2_ASYNC_HOLD_CTRL 0x2745 +#define VPU_ARB_URG_CTRL 0x2747 +#define VPU_WRARB_MODE_L2C1 0x27a2 #define VPU_ARB_DBG_STAT_L1C2 0x27b6 #define VDIN_DET_IDLE_BIT 8 #define VDIN_DET_IDLE_WIDTH 4 @@ -60,6 +61,8 @@ /* vpp */ #define VPP_VDO_MEAS_CTRL 0x1da8 +#define VPP_POSTBLEND_VD1_H_START_END 0x1d1c +#define VPP_POSTBLEND_VD1_V_START_END 0x1d1d /* VDIN0 8'h00 - 8'h7f */ /* VDIN1 8'h80 - 8'hef */ @@ -180,7 +183,7 @@ * is not sync with external signal */ /* Bit 24, decimation de enable */ -/* Bit 23:20, decimation phase +/* Bit 23:20, decimation phase, * which counter value use to decimate, */ /* Bit 19:16, decimation number, 0: not decimation, @@ -333,7 +336,6 @@ #define VDIN_MATRIX_PROBE_POS ((0x122a))/* + 0xd0100000) */ #define VDIN_CHROMA_ADDR_PORT ((0x122b))/* + 0xd0100000) */ #define VDIN_CHROMA_DATA_PORT ((0x122c))/* + 0xd0100000) */ -/* */ #define VDIN_CM_BRI_CON_CTRL ((0x122d))/* + 0xd0100000) */ /* Bit 17 clk_cyc_cnt_clr, if true, clear this register */ /* Bit 16 if true, use vpu clock to count one line, @@ -544,7 +546,7 @@ /* Bit 31:29 Reserved */ /* Bit 28:16 blkbar_row_th1. //threshold of the top blackbar */ /* Bit 15:13 Reserved */ -/* bit 12:0 blkbar_row_th2 //threshold of the bottom blackbar */ +/* bit 12:0 blkbar_row_th2 //threshold of the bottom blackbar*/ #define VDIN_BLKBAR_ROW_TH1_TH2 ((0x1264))/* + 0xd0100000) */ /* Readonly */ /* Bit 31:29 Reserved */ @@ -608,8 +610,8 @@ /* Bit 28:16 input window H start */ /* Bit 12:0 input window H end */ #define VDIN_WIN_H_START_END ((0x126d))/* + 0xd0100000) */ -/* Bit 28:16 input window H start */ -/* Bit 12:0 input window V start */ +/* Bit 28:16 input window V start */ +/* Bit 12:0 input window V end */ #define VDIN_WIN_V_START_END ((0x126e))/* + 0xd0100000) */ /* Bit 23:16 vdi8 asfifo_ctrl */ /* Bit 15:8 vdi7 asfifo_ctrl */ @@ -629,6 +631,20 @@ /* Bit 5:0, vdi9_asfifo_cnt */ #define VDIN_COM_STATUS3 ((0x1273))/* + 0xd0100000) */ +/* dolby vdin regs */ +#define VDIN_DOLBY_DSC_CTRL0 0x1275 +/*((0x1275 << 2) + 0xff900000)*/ +#define VDIN_DOLBY_DSC_CTRL1 0x1276 +#define VDIN_DOLBY_DSC_CTRL2 0x1277 +#define VDIN_DOLBY_DSC_CTRL3 0x1278 +#define VDIN_DOLBY_AXI_CTRL0 0x1279 +#define VDIN_DOLBY_AXI_CTRL1 0x127a +#define VDIN_DOLBY_AXI_CTRL2 0x127b +#define VDIN_DOLBY_AXI_CTRL3 0x127c +#define VDIN_DOLBY_DSC_STATUS0 0x127d +#define VDIN_DOLBY_DSC_STATUS1 0x127e +#define VDIN_DOLBY_DSC_STATUS2 0x127f +#define VDIN_DOLBY_DSC_STATUS3 0x121d @@ -637,13 +653,13 @@ /* #define VDIN_COM_CTRL0 0x1202 */ /* used by other modules,indicates that MPEG input. - * 0: mpeg source to NR directly, - * 1: mpeg source pass through here + *0: mpeg source to NR directly, + *1: mpeg source pass through here */ #define MPEG_TO_VDIN_SEL_BIT 31 #define MPEG_TO_VDIN_SEL_WID 1 /* indicates MPEG field ID,written by software. - * 0: EVEN FIELD 1: ODD FIELD + *0: EVEN FIELD 1: ODD FIELD */ #define MPEG_FLD_BIT 30 #define MPEG_FLD_WID 1 @@ -667,21 +683,16 @@ /* 00: component0_in 01: component1_in 10: component2_in */ #define COMP0_OUT_SWT_BIT 6 #define COMP0_OUT_SWT_WID 2 - - #define INPUT_WIN_SEL_EN_BIT 5 #define INPUT_WIN_SEL_EN_WID 1 - - /* 0: no data input 1: common data input */ #define COMMON_DATA_IN_EN_BIT 4 #define COMMON_DATA_IN_EN_WID 1 /* 1: MPEG, 2: 656, 3: TVFE, 4: CVD2, 5: HDMI_Rx,6: DVIN otherwise: NULL - *7: loopback from VIU1, 8: MIPI csi2 in meson6 - */ +*7: loopback from VIU1, 8: MIPI csi2 in meson6 +*/ #define VDIN_SEL_BIT 0 #define VDIN_SEL_WID 4 - /* #define VDIN_ACTIVE_MAX_PIX_CNT_STATUS 0x1203 */ /* ~field_hold & prehsc input active max pixel * every line output of window @@ -820,8 +831,9 @@ #define WIDTHM1O_WID 13 /* #define VDIN_SC_MISC_CTRL 0x120b */ -/* signed value for short line output - */ +/* signed value for short line output */ +#define PRE_HSCL_MODE_BIT 17 +#define PRE_HSCL_MODE_WID 4 #define INIT_PIX_IN_PTR_BIT 8 #define INIT_PIX_IN_PTR_WID 7 #define INIT_PIX_IN_PTR_MSK 0x0000007f @@ -832,7 +844,7 @@ #define HSCL_EN_WID 1 /* hscaler: fine scale down */ #define SHORT_LN_OUT_EN_BIT 5 #define SHORT_LN_OUT_EN_WID 1 -/* when decimation timing located in between 2 input pixels, +/*when decimation timing located in between 2 input pixels, * decimate the nearest one */ #define HSCL_NEAREST_EN_BIT 4 @@ -852,8 +864,7 @@ #define HSCL_PHASE_STEP_FRA_WID 24 /* #define VDIN_HSC_INI_CTRL 0x120d */ -/* repeatedly decimation of pixel #0 of each line? - */ +/* repeatedly decimation of pixel #0 of each line? */ #define HSCL_RPT_P0_NUM_BIT 29 #define HSCL_RPT_P0_NUM_WID 2 /* if rev>rpt_p0+1, then start decimation upon ini_phase? */ @@ -866,7 +877,6 @@ /* #define VDIN_COM_STATUS2 0x120e */ /* Read only */ - #define VDI7_FIFO_OVFL_BIT 23 /* vdi7 fifo overflow */ #define VDI7_FIFO_OVFL_WID 1 #define VDI7_ASFIFO_CNT_BIT 16 /* vdi7_asfifo_cnt */ @@ -881,8 +891,6 @@ #define VDI5_ASFIFO_CNT_BIT 0 /* vdi5_asfifo_cnt */ #define VDI5_ASFIFO_CNT_WID 6 - - /* #define VDIN_ASFIFO_CTRL2 0x120f */ #define ASFIFO_DECIMATION_SYNC_WITH_DE_BIT 25 #define ASFIFO_DECIMATION_SYNC_WITH_DE_WID 1 @@ -914,7 +922,6 @@ /* write 1 & then 0 to reset */ #define ASFIFO5_SOFT_RST_WID 1 - /* #define VDIN_MATRIX_CTRL 0x1210 */ #define VDIN_MATRIX0_BYPASS_BIT 9/* 1:bypass 0:pass */ #define VDIN_MATRIX0_BYPASS_WID 1 @@ -1017,17 +1024,38 @@ #define VDIN_INTF_WIDTHM1_BIT 0 #define VDIN_INTF_WIDTHM1_WID 13 +/* #define VDIN_LFIFO_URG_CTRL 0x121e */ +/*Bit 15 default== 0, urgent_ctrl_en + *Bit 14 default== 0, urgent_wr, if true for write buffer + *Bit 13 default== 0, out_inv_en + *Bit 12 default == 0, urgent_ini_value + *Bit 11:6 default == 0, up_th up threshold + *Bit 5:0 default == 0, dn_th dn threshold + */ +#define VDIN_LFIFO_URG_CTRL_EN_BIT 15 +#define VDIN_LFIFO_URG_CTRL_EN_WID 1 +#define VDIN_LFIFO_URG_WR_EN_BIT 14 +#define VDIN_LFIFO_URG_WR_EN_WID 1 +#define VDIN_LFIFO_OUT_INV_EN_BIT 13 +#define VDIN_LFIFO_OUT_INV_EN_WID 1 +#define VDIN_LFIFO_URG_INI_BIT 12 +#define VDIN_LFIFO_URG_INI_WID 1 +#define VDIN_LFIFO_URG_UP_TH_BIT 6 +#define VDIN_LFIFO_URG_UP_TH_WID 6 +#define VDIN_LFIFO_URG_DN_TH_BIT 0 +#define VDIN_LFIFO_URG_DN_TH_WID 6 + /* #define VDIN_WR_CTRL2 0x121f */ -/*1: enable WR 10 bit mode, 0: disable WR 10 bit mode */ +/*1: enable WR 10 bit mode, 0: disable WR 10 bit mode*/ #define VDIN_WR_10BIT_MODE_BIT 19 #define VDIN_WR_10BIT_MODE_WID 1 /* data_ext_en 1:send out data if req was interrupt by soft reset */ /* 0:normal mode */ #define VDIN_WR_DATA_EXT_EN_BIT 18 #define VDIN_WR_DATA_EXT_EN_WID 1 -/* 0: 1 word in 1burst, 1: 2 words in 1burst; - * 10: 4 words in 1burst; 11: reserved +/*0: 1 word in 1burst, 1: 2 words in 1burst; + *10: 4 words in 1burst; 11: reserved */ #define VDIN_WR_BURST_MODE_BIT 12 #define VDIN_WR_BURST_MODE_WID 4 @@ -1093,8 +1121,6 @@ #define WR_CANVAS_BIT 0 #define WR_CANVAS_WID 8 - - /* #define VDIN_WR_H_START_END 0x1221 */ #define HORIZONTAL_REVERSE_BIT 29/* if true horizontal reverse */ @@ -1132,7 +1158,11 @@ /* #define VDIN_SCIN_HEIGHTM1 0x1225 */ /* Bit 12:0, scaler input height minus 1 */ #define SCALER_INPUT_HEIGHT_BIT 0 -#define SCALER_INPUT_HEIGHT_WID 12 +#define SCALER_INPUT_HEIGHT_WID 13 + +/* Bit 28:16, vshrk input height minus 1 */ +#define VSHRK_INPUT_HEIGHT_BIT 16 +#define VSHRK_INPUT_HEIGHT_WID 13 /* #define `define VDIN_DUMMY_DATA 0x1226 */ #define DUMMY_COMPONENT0_BIT 16 @@ -1549,7 +1579,6 @@ #define MEAS_VS_TOTAL_CNT_LO_BIT 0 /* vsync_total_counter[31:0] */ #define MEAS_VS_TOTAL_CNT_LO_WID 32 - /* 1st/2nd/3rd/4th hs range according to VDIN_MEAS_HS_INDEX */ /* #define VDIN_MEAS_HS_RANGE 0x125d */ #define MEAS_HS_RANGE_CNT_START_BIT 16 @@ -1557,24 +1586,19 @@ #define MEAS_HS_RANGE_CNT_END_BIT 0 #define MEAS_HS_RANGE_CNT_END_WID 13 - /* hs count as per 1st/2nd/3rd/4th hs range according to VDIN_MEAS_HS_INDEX */ /* #define VDIN_MEAS_HS_COUNT 0x125e // read only */ #define MEAS_HS_CNT_BIT 0 #define MEAS_HS_CNT_WID 24 - - /* #define VDIN_BLKBAR_CTRL1 0x125f */ #define BLKBAR_WHITE_EN_BIT 8 #define BLKBAR_WHITE_EN_WID 1 #define BLKBAR_WHITE_LVL_BIT 0 #define BLKBAR_WHITE_LVL_WID 8 - /* #define VDIN_BLKBAR_CTRL0 0x1260 */ - /* threshold to judge a black point */ #define BLKBAR_BLK_LVL_BIT 24 #define BLKBAR_BLK_LVL_WID 8 @@ -1586,7 +1610,7 @@ #define BLKBAR_COMP_SEL_BIT 5 #define BLKBAR_COMP_SEL_WID 3 /* sw statistic of black pixels of each block, - * 1: search once, 0: search continuously till the exact edge + *1: search once, 0: search continuously till the exact edge */ #define BLKBAR_SW_STAT_EN_BIT 4 #define BLKBAR_SW_STAT_EN_WID 1 @@ -1678,15 +1702,12 @@ #define INPUT_WIN_H_END_BIT 0 #define INPUT_WIN_H_END_WID 13 - - /* #define VDIN_WIN_V_START_END 0x126e */ #define INPUT_WIN_V_START_BIT 16 #define INPUT_WIN_V_START_WID 13 #define INPUT_WIN_V_END_BIT 0 #define INPUT_WIN_V_END_WID 13 - /* Bit 15:8 vdi7 asfifo_ctrl */ /* Bit 7:0 vdi6 asfifo_ctrl */ /* #define VDIN_ASFIFO_CTRL3 0x126f */ @@ -1699,6 +1720,13 @@ #define VDI6_ASFIFO_CTRL_BIT 0 #define VDI6_ASFIFO_CTRL_WID 8 +#define VDIN_VSHRK_EN_BIT 27 +#define VDIN_VSHRK_EN_WID 1 +#define VDIN_VSHRK_LPF_MODE_BIT 24 +#define VDIN_VSHRK_LPF_MODE_WID 1 +#define VDIN_VSHRK_MODE_BIT 25 +#define VDIN_VSHRK_MODE_WID 2 + /* Bit 3:2 vshrk_clk2_ctrl */ /* Bit 1:0 vshrk_clk1_ctrl */ /* #define VDIN_COM_GCLK_CTRL2 ((0x1270 << 2) + 0xd0100000) */ @@ -1713,7 +1741,34 @@ /* Bit 5:0, vdi9_asfifo_cnt */ /* #define VDIN_COM_STATUS3 ((0x1273 << 2) + 0xd0100000) */ +#define VDIN_FORCEGOLINE_EN_BIT 28 +#define VDIN_WRREQUEST_EN_BT 8 +#define VDIN_WRCTRLREG_PAUSE_BIT 10 +/*#define VDIN_INTF_WIDTHM1*/ +#define VDIN_FIX_NONSTDVSYNC_BIT 24 +#define VDIN_FIX_NONSTDVSYNC_WID 2 + +/*#define VPU_ARB_URG_CTRL*/ +#define VDIN_LFF_URG_CTRL_BIT 8 +#define VDIN_LFF_URG_CTRL_WID 1 +#define VPP_OFF_URG_CTRL_BIT 6 +#define VPP_OFF_URG_CTRL_WID 1 + +/*#define VDIN_COM_CTRL0*/ +#define VDIN_COMMONINPUT_EN_BIT 4 +#define VDIN_COMMONINPUT_EN_WID 1 + +/*#define VDIN_WR_CTRL*/ +#define VDIN0_VCP_WR_EN_BIT 25 +#define VDIN0_VCP_WR_EN_WID 1 +#define VDIN0_DISABLE_CLOCKGATE_BIT 29 +#define VDIN0_DISABLE_CLOCKGATE_WID 1 +/*#define VDIN1_WR_CTRL*/ +#define VDIN1_VCP_WR_EN_BIT 8 +#define VDIN1_VCP_WR_EN_WID 1 +#define VDIN1_DISABLE_CLOCKGATE_BIT 29 +#define VDIN1_DISABLE_CLOCKGATE_WID 1 #endif /* __VDIN_REGS_H */ diff --git a/drivers/amlogic/media/vin/tvin/vdin/vdin_sm.c b/drivers/amlogic/media/vin/tvin/vdin/vdin_sm.c index f6e9a6de88bc..ac2e430feea4 100644 --- a/drivers/amlogic/media/vin/tvin/vdin/vdin_sm.c +++ b/drivers/amlogic/media/vin/tvin/vdin/vdin_sm.c @@ -31,41 +31,26 @@ #include "vdin_ctl.h" #include "vdin_drv.h" - /* Stay in TVIN_SIG_STATE_NOSIG for some * cycles => be sure TVIN_SIG_STATE_NOSIG */ -#define NOSIG_MAX_CNT 8 +#define NOSIG_MAX_CNT 8 /* Stay in TVIN_SIG_STATE_UNSTABLE for some * cycles => be sure TVIN_SIG_STATE_UNSTABLE */ -#define UNSTABLE_MAX_CNT 2/* 4 */ +#define UNSTABLE_MAX_CNT 2/* 4 */ /* Have signal for some cycles => exit TVIN_SIG_STATE_NOSIG */ -#define EXIT_NOSIG_MAX_CNT 2/* 1 */ +#define EXIT_NOSIG_MAX_CNT 2/* 1 */ /* No signal for some cycles => back to TVAFE_STATE_NOSIG */ -#define BACK_NOSIG_MAX_CNT 24 /* 8 */ +#define BACK_NOSIG_MAX_CNT 24 /* 8 */ /* Signal unstable for some cycles => exit TVAFE_STATE_STABLE */ -#define EXIT_STABLE_MAX_CNT 1 +#define EXIT_STABLE_MAX_CNT 1 /* Signal stable for some cycles => back to TVAFE_STATE_STABLE */ - /* must >=500ms,for new api function */ -#define BACK_STABLE_MAX_CNT 50 - -#define EXIT_PRESTABLE_MAX_CNT 50 - +/* must >=500ms,for new api function */ +#define BACK_STABLE_MAX_CNT 50 +#define EXIT_PRESTABLE_MAX_CNT 50 static struct tvin_sm_s sm_dev[VDIN_MAX_DEVS]; -#if 0 -/* TVIN_SIG_STATUS_NOSIG; */ -static enum tvin_sm_status_e state = TVIN_SM_STATUS_NULL; - -static unsigned int state_cnt; /* STATE_NOSIG, STATE_UNSTABLE */ -static unsigned int exit_nosig_cnt; /* STATE_NOSIG */ -static unsigned int back_nosig_cnt; /* STATE_UNSTABLE */ -static unsigned int back_stable_cnt; /* STATE_UNSTABLE */ -static unsigned int exit_prestable_cnt; /* STATE_PRESTABLE */ -#endif -static bool sm_debug_enable = true; - static int sm_print_nosig; static int sm_print_notsup; static int sm_print_unstable; @@ -74,96 +59,87 @@ static int sm_print_fmt_chg; static int sm_atv_prestable_fmt; static int sm_print_prestable; +static bool sm_debug_enable = true; module_param(sm_debug_enable, bool, 0664); MODULE_PARM_DESC(sm_debug_enable, "enable/disable state machine debug message"); -#if 1 + static int back_nosig_max_cnt = BACK_NOSIG_MAX_CNT; -module_param(back_nosig_max_cnt, int, 0664); -MODULE_PARM_DESC(back_nosig_max_cnt, - "unstable enter nosignal state max count"); - static int atv_unstable_in_cnt = 45; -module_param(atv_unstable_in_cnt, int, 0664); -MODULE_PARM_DESC(atv_unstable_in_cnt, "atv_unstable_in_cnt"); - static int atv_unstable_out_cnt = 50; -module_param(atv_unstable_out_cnt, int, 0664); -MODULE_PARM_DESC(atv_unstable_out_cnt, "atv_unstable_out_cnt"); - -static int hdmi_unstable_out_cnt = 20; -module_param(hdmi_unstable_out_cnt, int, 0664); -MODULE_PARM_DESC(hdmi_unstable_out_cnt, "hdmi_unstable_out_cnt"); - +static int hdmi_unstable_out_cnt = 1; static int hdmi_stable_out_cnt = 1;/* 25; */ -module_param(hdmi_stable_out_cnt, int, 0664); -MODULE_PARM_DESC(hdmi_stable_out_cnt, "hdmi_stable_out_cnt"); - /* new add in gxtvbb@20160523,reason: *gxtvbb add atv snow config,the config will affect signal detect. *if atv_stable_out_cnt < 100,the signal state will change *after swich source to atv or after atv search */ static int atv_stable_out_cnt = 100; -module_param(atv_stable_out_cnt, int, 0664); -MODULE_PARM_DESC(atv_stable_out_cnt, "atv_stable_out_cnt"); - /* new add in gxtvbb@20160613,reason: *gxtvbb add atv snow config,the config will affect signal detect. *ensure after fmt change,the new fmt can be detect in time! */ static int atv_stable_fmt_check_cnt = 10; -module_param(atv_stable_fmt_check_cnt, int, 0664); -MODULE_PARM_DESC(atv_stable_fmt_check_cnt, "atv_stable_fmt_check_cnt"); - /* new add in gxtvbb@20160613,reason: * ensure vdin fmt can update when fmt is changed in menu */ static int atv_stable_fmt_check_enable; - /* new add in gxtvbb@20160523,reason: *gxtvbb add atv snow config,the config will affect signal detect. *ensure after prestable into stable,the state is really stable! */ static int atv_prestable_out_cnt = 100; +static int other_stable_out_cnt = EXIT_STABLE_MAX_CNT; +static int other_unstable_out_cnt = BACK_STABLE_MAX_CNT; +static int other_unstable_in_cnt = UNSTABLE_MAX_CNT; +static int nosig_in_cnt = NOSIG_MAX_CNT; +static int nosig2_unstable_cnt = EXIT_NOSIG_MAX_CNT; + +#ifdef DEBUG_SUPPORT +module_param(back_nosig_max_cnt, int, 0664); +MODULE_PARM_DESC(back_nosig_max_cnt, + "unstable enter nosignal state max count"); + +module_param(atv_unstable_in_cnt, int, 0664); +MODULE_PARM_DESC(atv_unstable_in_cnt, "atv_unstable_in_cnt"); + +module_param(atv_unstable_out_cnt, int, 0664); +MODULE_PARM_DESC(atv_unstable_out_cnt, "atv_unstable_out_cnt"); + +module_param(hdmi_unstable_out_cnt, int, 0664); +MODULE_PARM_DESC(hdmi_unstable_out_cnt, "hdmi_unstable_out_cnt"); + +module_param(hdmi_stable_out_cnt, int, 0664); +MODULE_PARM_DESC(hdmi_stable_out_cnt, "hdmi_stable_out_cnt"); + +module_param(atv_stable_out_cnt, int, 0664); +MODULE_PARM_DESC(atv_stable_out_cnt, "atv_stable_out_cnt"); + +module_param(atv_stable_fmt_check_cnt, int, 0664); +MODULE_PARM_DESC(atv_stable_fmt_check_cnt, "atv_stable_fmt_check_cnt"); + module_param(atv_prestable_out_cnt, int, 0664); MODULE_PARM_DESC(atv_prestable_out_cnt, "atv_prestable_out_cnt"); -static int other_stable_out_cnt = EXIT_STABLE_MAX_CNT; module_param(other_stable_out_cnt, int, 0664); MODULE_PARM_DESC(other_stable_out_cnt, "other_stable_out_cnt"); -static int other_unstable_out_cnt = BACK_STABLE_MAX_CNT; module_param(other_unstable_out_cnt, int, 0664); MODULE_PARM_DESC(other_unstable_out_cnt, "other_unstable_out_cnt"); -static int other_unstable_in_cnt = UNSTABLE_MAX_CNT; module_param(other_unstable_in_cnt, int, 0664); MODULE_PARM_DESC(other_unstable_in_cnt, "other_unstable_in_cnt"); -static int comp_pre2_stable_cnt = EXIT_PRESTABLE_MAX_CNT; -module_param(comp_pre2_stable_cnt, int, 0664); -MODULE_PARM_DESC(comp_pre2_stable_cnt, "comp_pre2_stable_cnt"); - -static int nosig_in_cnt = NOSIG_MAX_CNT; module_param(nosig_in_cnt, int, 0664); MODULE_PARM_DESC(nosig_in_cnt, "nosig_in_cnt"); -static int nosig2_unstable_cnt = EXIT_NOSIG_MAX_CNT; module_param(nosig2_unstable_cnt, int, 0664); MODULE_PARM_DESC(nosig2_unstable_cnt, "nosig2_unstable_cnt"); - -/* - * void tvin_smr_init_counter(void) - * { - * state_cnt = 0; - * exit_nosig_cnt = 0; - * back_nosig_cnt = 0; - * back_stable_cnt = 0; - * exit_prestable_cnt = 0; - * } - */ #endif + +static int signal_status = TVIN_SIG_STATUS_NULL; +module_param(signal_status, int, 0664); +MODULE_PARM_DESC(signal_status, "signal_status"); /* * check hdmirx color format */ @@ -172,6 +148,7 @@ static void hdmirx_color_fmt_handler(struct vdin_dev_s *devp) struct tvin_state_machine_ops_s *sm_ops; enum tvin_port_e port = TVIN_PORT_NULL; enum tvin_color_fmt_e cur_color_fmt, pre_color_fmt; + enum tvin_color_fmt_e cur_dest_color_fmt, pre_dest_color_fmt; struct tvin_sig_property_s *prop, *pre_prop; unsigned int vdin_hdr_flag, pre_vdin_hdr_flag; unsigned int vdin_fmt_range, pre_vdin_fmt_range; @@ -198,6 +175,9 @@ static void hdmirx_color_fmt_handler(struct vdin_dev_s *devp) cur_color_fmt = prop->color_format; pre_color_fmt = pre_prop->color_format; + cur_dest_color_fmt = prop->dest_cfmt; + pre_dest_color_fmt = pre_prop->dest_cfmt; + vdin_hdr_flag = prop->vdin_hdr_Flag; pre_vdin_hdr_flag = pre_prop->vdin_hdr_Flag; @@ -206,12 +186,14 @@ static void hdmirx_color_fmt_handler(struct vdin_dev_s *devp) if ((cur_color_fmt != pre_color_fmt) || (vdin_hdr_flag != pre_vdin_hdr_flag) || - (vdin_fmt_range != pre_vdin_fmt_range) - ) { - pr_info("[smr.%d] color fmt(%d->%d),csc_cfg:0x%x\n", - devp->index, - pre_color_fmt, cur_color_fmt, - devp->csc_cfg); + (vdin_fmt_range != pre_vdin_fmt_range) || + (cur_dest_color_fmt != pre_dest_color_fmt)) { + pr_info("[smr.%d] cur color fmt(%d->%d), hdr_flag(%d->%d), dest color fmt(%d->%d), csc_cfg:0x%x\n", + devp->index, + pre_color_fmt, cur_color_fmt, + pre_vdin_hdr_flag, vdin_hdr_flag, + pre_dest_color_fmt, cur_dest_color_fmt, + devp->csc_cfg); vdin_get_format_convert(devp); devp->csc_cfg = 1; } else @@ -219,6 +201,48 @@ static void hdmirx_color_fmt_handler(struct vdin_dev_s *devp) } } +/* check auto de to adjust vdin cutwindow */ +void vdin_auto_de_handler(struct vdin_dev_s *devp) +{ + struct tvin_state_machine_ops_s *sm_ops; + struct tvin_sig_property_s *prop; + unsigned int cur_vs, cur_ve, pre_vs, pre_ve; + unsigned int cur_hs, cur_he, pre_hs, pre_he; + + if (!devp) { + return; + } else if (!devp->frontend) { + sm_dev[devp->index].state = TVIN_SM_STATUS_NULL; + return; + } + if (devp->auto_cutwindow_en == 0) + return; + prop = &devp->prop; + sm_ops = devp->frontend->sm_ops; + if ((devp->flags & VDIN_FLAG_DEC_STARTED) && + (sm_ops->get_sig_property)) { + sm_ops->get_sig_property(devp->frontend, prop); + cur_vs = prop->vs; + cur_ve = prop->ve; + cur_hs = prop->hs; + cur_he = prop->he; + pre_vs = prop->pre_vs; + pre_ve = prop->pre_ve; + pre_hs = prop->pre_hs; + pre_he = prop->pre_he; + if ((pre_vs != cur_vs) || (pre_ve != cur_ve) || + (pre_hs != cur_hs) || (pre_he != cur_he)) { + pr_info("[smr.%d] pre_vs(%d->%d),pre_ve(%d->%d),pre_hs(%d->%d),pre_he(%d->%d),cutwindow_cfg:0x%x\n", + devp->index, pre_vs, cur_vs, pre_ve, cur_ve, + pre_hs, cur_hs, pre_he, cur_he, + devp->cutwindow_cfg); + devp->cutwindow_cfg = 1; + } else { + devp->cutwindow_cfg = 0; + } + } +} + void tvin_smr_init_counter(int index) { sm_dev[index].state_cnt = 0; @@ -228,6 +252,16 @@ void tvin_smr_init_counter(int index) sm_dev[index].exit_prestable_cnt = 0; } +static void hdmirx_dv_check(struct vdin_dev_s *devp, + struct tvin_sig_property_s *prop) +{ + /*check hdmiin dolby input*/ + if (prop->dolby_vision != devp->dv.dv_flag) { + tvin_smr_init(devp->index); + devp->dv.dv_flag = prop->dolby_vision; + } +} + /* * tvin state machine routine * @@ -235,7 +269,7 @@ void tvin_smr_init_counter(int index) void tvin_smr(struct vdin_dev_s *devp) { struct tvin_state_machine_ops_s *sm_ops; - struct tvin_info_s *info, *pre_info; + struct tvin_info_s *info; enum tvin_port_e port = TVIN_PORT_NULL; unsigned int unstb_in; struct tvin_sm_s *sm_p; @@ -249,34 +283,32 @@ void tvin_smr(struct vdin_dev_s *devp) return; } - if (devp->flags & VDIN_FLAG_SM_DISABLE) + if ((devp->flags & VDIN_FLAG_SM_DISABLE) || + (devp->flags & VDIN_FLAG_SUSPEND)) return; + sm_p = &sm_dev[devp->index]; fe = devp->frontend; sm_ops = devp->frontend->sm_ops; info = &devp->parm.info; - pre_info = &devp->pre_info; port = devp->parm.port; prop = &devp->prop; pre_prop = &devp->pre_prop; + hdmirx_dv_check(devp, prop); + switch (sm_p->state) { case TVIN_SM_STATUS_NOSIG: ++sm_p->state_cnt; - #ifdef CONFIG_AMLOGIC_MEDIA_TVAFE - if (port == TVIN_PORT_CVBS3) - tvafe_snow_config_clamp(1); - #endif + /*if ((port == TVIN_PORT_CVBS3) && + * (devp->flags & VDIN_FLAG_SNOW_FLAG)) + * tvafe_snow_config_clamp(1); + */ if (sm_ops->nosig(devp->frontend)) { sm_p->exit_nosig_cnt = 0; if (sm_p->state_cnt >= nosig_in_cnt) { sm_p->state_cnt = nosig_in_cnt; info->status = TVIN_SIG_STATUS_NOSIG; - if (pre_info->status != info->status) { - pre_info->status = info->status; - queue_delayed_work(devp->sig_wq, - &devp->sig_dwork, 0); - } info->fmt = TVIN_SIG_FMT_NULL; if (sm_debug_enable && !sm_print_nosig) { pr_info("[smr.%d] no signal\n", @@ -308,11 +340,6 @@ void tvin_smr(struct vdin_dev_s *devp) tvin_smr_init_counter(devp->index); sm_p->state = TVIN_SM_STATUS_NOSIG; info->status = TVIN_SIG_STATUS_NOSIG; - if (pre_info->status != info->status) { - pre_info->status = info->status; - queue_delayed_work(devp->sig_wq, - &devp->sig_dwork, 0); - } info->fmt = TVIN_SIG_FMT_NULL; if (sm_debug_enable) pr_info("[smr.%d] unstable --> no signal\n", @@ -326,7 +353,8 @@ void tvin_smr(struct vdin_dev_s *devp) sm_p->back_stable_cnt = 0; if (((port == TVIN_PORT_CVBS3) || (port == TVIN_PORT_CVBS0)) && - devp->unstable_flag) + devp->unstable_flag && + (devp->flags & VDIN_FLAG_SNOW_FLAG)) /* UNSTABLE_ATV_MAX_CNT; */ unstb_in = sm_p->atv_unstable_in_cnt; else @@ -334,11 +362,6 @@ void tvin_smr(struct vdin_dev_s *devp) if (sm_p->state_cnt >= unstb_in) { sm_p->state_cnt = unstb_in; info->status = TVIN_SIG_STATUS_UNSTABLE; - if (pre_info->status != info->status) { - pre_info->status = info->status; - queue_delayed_work(devp->sig_wq, - &devp->sig_dwork, 0); - } info->fmt = TVIN_SIG_FMT_NULL; if (sm_debug_enable && !sm_print_unstable) { @@ -350,8 +373,9 @@ void tvin_smr(struct vdin_dev_s *devp) } } else { ++sm_p->back_stable_cnt; - if ((port == TVIN_PORT_CVBS3) || - (port == TVIN_PORT_CVBS0)) + if (((port == TVIN_PORT_CVBS3) || + (port == TVIN_PORT_CVBS0)) && + (devp->flags & VDIN_FLAG_SNOW_FLAG)) unstb_in = sm_p->atv_unstable_out_cnt; else if ((port >= TVIN_PORT_HDMI0) && (port <= TVIN_PORT_HDMI7)) @@ -368,25 +392,21 @@ void tvin_smr(struct vdin_dev_s *devp) sm_ops->get_fmt(fe); sm_ops->get_sig_property(fe, prop); + info->cfmt = prop->color_format; memcpy(pre_prop, prop, sizeof(struct tvin_sig_property_s)); devp->parm.info.trans_fmt = prop->trans_fmt; - devp->parm.info.reserved = - prop->dvi_info & 0xf; + devp->parm.info.is_dvi = + prop->dvi_info; devp->parm.info.fps = - prop->dvi_info >> 4; + prop->fps; } } else info->fmt = TVIN_SIG_FMT_NULL; if (info->fmt == TVIN_SIG_FMT_NULL) { /* remove unsupport status */ info->status = TVIN_SIG_STATUS_UNSTABLE; - if (pre_info->status != info->status) { - pre_info->status = info->status; - queue_delayed_work(devp->sig_wq, - &devp->sig_dwork, 0); - } if (sm_debug_enable && !sm_print_notsup) { pr_info("[smr.%d] unstable --> not support\n", @@ -418,12 +438,11 @@ void tvin_smr(struct vdin_dev_s *devp) case TVIN_SM_STATUS_PRESTABLE: { bool nosig = false, fmt_changed = false; unsigned int prestable_out_cnt = 0; - devp->unstable_flag = true; - #ifdef CONFIG_AMLOGIC_MEDIA_TVAFE - if (port == TVIN_PORT_CVBS3) - tvafe_snow_config_clamp(0); - #endif + /*if ((port == TVIN_PORT_CVBS3) && + * (devp->flags & VDIN_FLAG_SNOW_FLAG)) + * tvafe_snow_config_clamp(0); + */ if (sm_ops->nosig(devp->frontend)) { nosig = true; if (sm_debug_enable && !(sm_print_prestable&0x1)) { @@ -444,7 +463,8 @@ void tvin_smr(struct vdin_dev_s *devp) if (nosig || fmt_changed) { ++sm_p->state_cnt; - if (port == TVIN_PORT_CVBS3) + if ((port == TVIN_PORT_CVBS3) && + (devp->flags & VDIN_FLAG_SNOW_FLAG)) prestable_out_cnt = atv_prestable_out_cnt; else prestable_out_cnt = other_stable_out_cnt; @@ -463,21 +483,18 @@ void tvin_smr(struct vdin_dev_s *devp) } else { sm_p->state_cnt = 0; - if (port == TVIN_PORT_CVBS3) { + if ((port == TVIN_PORT_CVBS3) && + (devp->flags & VDIN_FLAG_SNOW_FLAG)) { ++sm_p->exit_prestable_cnt; if (sm_p->exit_prestable_cnt < atv_prestable_out_cnt) break; - sm_p->exit_prestable_cnt = 0; + else + sm_p->exit_prestable_cnt = 0; } sm_p->state = TVIN_SM_STATUS_STABLE; info->status = TVIN_SIG_STATUS_STABLE; - if (pre_info->status != info->status) { - pre_info->status = info->status; - queue_delayed_work(devp->sig_wq, - &devp->sig_dwork, 0); - } if (sm_debug_enable) pr_info("[smr.%d] %ums prestable --> stable\n", devp->index, @@ -492,8 +509,8 @@ void tvin_smr(struct vdin_dev_s *devp) bool nosig = false, fmt_changed = false; unsigned int stable_out_cnt = 0; unsigned int stable_fmt = 0; - devp->unstable_flag = true; + if (sm_ops->nosig(devp->frontend)) { nosig = true; if (sm_debug_enable && !sm_print_fmt_nosig) { @@ -511,6 +528,13 @@ void tvin_smr(struct vdin_dev_s *devp) sm_print_fmt_chg = 1; } } + /* dynamic adjust cutwindow for atv test */ + if ((port >= TVIN_PORT_CVBS0) && + (port <= TVIN_PORT_CVBS7)) + vdin_auto_de_handler(devp); + if ((port >= TVIN_PORT_CVBS0) && (port <= TVIN_PORT_CVBS7) && + devp->auto_ratio_en && sm_ops->get_sig_property) + sm_ops->get_sig_property(devp->frontend, prop); /* hdmirx_color_fmt_handler(devp); */ #if 0 if (sm_ops->pll_lock(devp->frontend)) { @@ -524,8 +548,9 @@ void tvin_smr(struct vdin_dev_s *devp) if (nosig || fmt_changed /* || !pll_lock */) { ++sm_p->state_cnt; - if ((port == TVIN_PORT_CVBS3) || - (port == TVIN_PORT_CVBS0)) + if (((port == TVIN_PORT_CVBS3) || + (port == TVIN_PORT_CVBS0)) && + (devp->flags & VDIN_FLAG_SNOW_FLAG)) stable_out_cnt = sm_p->atv_stable_out_cnt; else if ((port >= TVIN_PORT_HDMI0) && (port <= TVIN_PORT_HDMI7)) @@ -534,7 +559,8 @@ void tvin_smr(struct vdin_dev_s *devp) stable_out_cnt = other_stable_out_cnt; /*add for atv snow*/ if ((sm_p->state_cnt >= atv_stable_fmt_check_cnt) && - (port == TVIN_PORT_CVBS3)) + (port == TVIN_PORT_CVBS3) && + (devp->flags & VDIN_FLAG_SNOW_FLAG)) atv_stable_fmt_check_enable = 1; if (sm_p->state_cnt >= stable_out_cnt) { tvin_smr_init_counter(devp->index); @@ -554,6 +580,7 @@ void tvin_smr(struct vdin_dev_s *devp) /*add for atv snow*/ if ((port == TVIN_PORT_CVBS3) && atv_stable_fmt_check_enable && + (devp->flags & VDIN_FLAG_SNOW_FLAG) && (sm_ops->get_fmt && sm_ops->get_sig_property)) { sm_p->state_cnt = 0; stable_fmt = @@ -565,10 +592,10 @@ void tvin_smr(struct vdin_dev_s *devp) sizeof(struct tvin_sig_property_s)); devp->parm.info.trans_fmt = prop->trans_fmt; - devp->parm.info.reserved = - prop->dvi_info & 0xf; + devp->parm.info.is_dvi = + prop->dvi_info; devp->parm.info.fps = - prop->dvi_info >> 4; + prop->fps; info->fmt = stable_fmt; atv_stable_fmt_check_enable = 0; if (sm_debug_enable) @@ -589,6 +616,11 @@ void tvin_smr(struct vdin_dev_s *devp) sm_p->state = TVIN_SM_STATUS_NOSIG; break; } + if (sm_p->sig_status != info->status) { + sm_p->sig_status = info->status; + wake_up(&devp->queue); + } + signal_status = sm_p->sig_status; } /* @@ -598,6 +630,7 @@ void tvin_smr(struct vdin_dev_s *devp) void tvin_smr_init(int index) { + sm_dev[index].sig_status = TVIN_SIG_STATUS_NULL; sm_dev[index].state = TVIN_SM_STATUS_NULL; sm_dev[index].atv_stable_out_cnt = atv_stable_out_cnt; sm_dev[index].atv_unstable_in_cnt = atv_unstable_in_cnt; diff --git a/drivers/amlogic/media/vin/tvin/vdin/vdin_sm.h b/drivers/amlogic/media/vin/tvin/vdin/vdin_sm.h index 1dbf882344e7..5b289bfdeb3d 100644 --- a/drivers/amlogic/media/vin/tvin/vdin/vdin_sm.h +++ b/drivers/amlogic/media/vin/tvin/vdin/vdin_sm.h @@ -35,6 +35,7 @@ enum tvin_sm_status_e { TVIN_SM_STATUS_STABLE, }; struct tvin_sm_s { + enum tvin_sig_status_e sig_status; enum tvin_sm_status_e state; unsigned int state_cnt; /* STATE_NOSIG, STATE_UNSTABLE */ unsigned int exit_nosig_cnt; /* STATE_NOSIG */ diff --git a/drivers/amlogic/media/vin/tvin/vdin/vdin_v4l2.c b/drivers/amlogic/media/vin/tvin/vdin/vdin_v4l2.c index 43ea4af3c409..2d9956b5a044 100644 --- a/drivers/amlogic/media/vin/tvin/vdin/vdin_v4l2.c +++ b/drivers/amlogic/media/vin/tvin/vdin/vdin_v4l2.c @@ -61,10 +61,16 @@ struct vdin_v4l2_ops_s *get_vdin_v4l2_ops() { if ((ops.start_tvin_service != NULL) && (ops.stop_tvin_service != NULL)) return &ops; - return NULL; + else { + /* pr_err("[vdin..]%s: vdin v4l2 operation + * haven't registered.",__func__); + */ + return NULL; + } } EXPORT_SYMBOL(get_vdin_v4l2_ops); +/*Converts commands into strings */ const char *cam_cmd_to_str(enum cam_command_e cmd) { switch (cmd) { diff --git a/drivers/amlogic/media/vin/tvin/vdin/vdin_vf.c b/drivers/amlogic/media/vin/tvin/vdin/vdin_vf.c index 166e946a6b45..5a245157b979 100644 --- a/drivers/amlogic/media/vin/tvin/vdin/vdin_vf.c +++ b/drivers/amlogic/media/vin/tvin/vdin/vdin_vf.c @@ -33,7 +33,7 @@ /* Local Headers */ #include "vdin_vf.h" - +#include "vdin_ctl.h" static bool vf_log_enable = true; static bool vf_log_fe = true; static bool vf_log_be = true; @@ -47,7 +47,6 @@ MODULE_PARM_DESC(vf_log_fe, "enable/disable vframe manager log frontend"); module_param(vf_log_be, bool, 0664); MODULE_PARM_DESC(vf_log_be, "enable/disable vframe manager log backen"); - #ifdef VF_LOG_EN void vf_log_init(struct vf_pool *p) { @@ -146,8 +145,8 @@ void vf_log_print(struct vf_pool *p) { unsigned int i = 0, j = 0, k = 0; int len = 0; - char buf1[100]; - char buf2[100]; + char buf1[VF_LOG_PRINT_MAX_LEN]; + char buf2[VF_LOG_PRINT_MAX_LEN]; struct vf_log_s *log = &p->log; pr_info("%-10s %-10s %-10s %-10s %-10s %-10s %5s\n", @@ -316,6 +315,8 @@ struct vf_pool *vf_pool_alloc(int size) spin_lock_init(&p->wt_lock); spin_lock_init(&p->fz_lock); spin_lock_init(&p->tmp_lock); + spin_lock_init(&p->log_lock); + spin_lock_init(&p->dv_lock); /* initialize list head */ INIT_LIST_HEAD(&p->wr_list); INIT_LIST_HEAD(&p->rd_list); @@ -380,6 +381,7 @@ int vf_pool_init(struct vf_pool *p, int size) p->tmp_list_size = 0; /* initialize provider write list */ for (i = 0; i < size; i++) { + p->dv_buf_size[i] = 0; master = vf_get_master(p, i); if (master == NULL) { log_state = false; @@ -403,9 +405,18 @@ int vf_pool_init(struct vf_pool *p, int size) slave->status = VF_STATUS_SL; } atomic_set(&p->buffer_cnt, 0); + for (i = 0; i < VFRAME_DISP_MAX_NUM; i++) { + if (p->skip_vf_num == 0) + p->disp_mode[i] = VFRAME_DISP_MODE_NULL; + else + p->disp_mode[i] = VFRAME_DISP_MODE_UNKNOWN; + p->disp_index[i] = 0; + } #ifdef VF_LOG_EN + spin_lock_irqsave(&p->log_lock, flags); vf_log_init(p); vf_log(p, VF_OPERATION_INIT, log_state); + spin_unlock_irqrestore(&p->log_lock, flags); #endif return 0; } @@ -414,8 +425,12 @@ int vf_pool_init(struct vf_pool *p, int size) /* free the vframe pool of the vfp */ void vf_pool_free(struct vf_pool *p) { + unsigned long flags; + if (p) { + spin_lock_irqsave(&p->log_lock, flags); vf_log(p, VF_OPERATION_FREE, true); + spin_unlock_irqrestore(&p->log_lock, flags); /* if (p->master) */ kfree(p->master); /* if (p->slave) */ @@ -453,8 +468,8 @@ static inline void vf_pool_put(struct vf_entry *vfe, struct list_head *head) list_add(&vfe->list, head); } /* - *move all vf_entrys in tmp list to writable list - */ +*move all vf_entrys in tmp list to writable list +*/ void recycle_tmp_vfs(struct vf_pool *p) { struct vf_entry *pos = NULL, *tmp = NULL; @@ -469,8 +484,8 @@ void recycle_tmp_vfs(struct vf_pool *p) spin_unlock_irqrestore(&p->tmp_lock, flags); } /* - *put vf_entry to tmp list - */ +*put vf_entry to tmp list +*/ void tmp_vf_put(struct vf_entry *vfe, struct vf_pool *p) { unsigned long flags; @@ -481,8 +496,8 @@ void tmp_vf_put(struct vf_entry *vfe, struct vf_pool *p) spin_unlock_irqrestore(&p->tmp_lock, flags); } /* - *move all vf_entry in tmp list to readable list - */ +*move all vf_entry in tmp list to readable list +*/ void tmp_to_rd(struct vf_pool *p) { struct vf_entry *pos = NULL, *tmp = NULL; @@ -504,10 +519,12 @@ struct vf_entry *provider_vf_peek(struct vf_pool *p) spin_lock_irqsave(&p->wr_lock, flags); vfe = vf_pool_peek(&p->wr_list); spin_unlock_irqrestore(&p->wr_lock, flags); + spin_lock_irqsave(&p->log_lock, flags); if (!vfe) vf_log(p, VF_OPERATION_FPEEK, false); else vf_log(p, VF_OPERATION_FPEEK, true); + spin_unlock_irqrestore(&p->log_lock, flags); return vfe; } @@ -521,12 +538,16 @@ struct vf_entry *provider_vf_get(struct vf_pool *p) vfe = vf_pool_get(&p->wr_list); spin_unlock_irqrestore(&p->wr_lock, flags); if (!vfe) { + spin_lock_irqsave(&p->log_lock, flags); vf_log(p, VF_OPERATION_FGET, false); + spin_unlock_irqrestore(&p->log_lock, flags); return NULL; } + spin_lock_irqsave(&p->log_lock, flags); p->wr_list_size--; vfe->status = VF_STATUS_WM; vf_log(p, VF_OPERATION_FGET, true); + spin_unlock_irqrestore(&p->log_lock, flags); return vfe; } @@ -539,7 +560,9 @@ void provider_vf_put(struct vf_entry *vfe, struct vf_pool *p) vf_pool_put(vfe, &p->rd_list); p->rd_list_size++; spin_unlock_irqrestore(&p->rd_lock, flags); + spin_lock_irqsave(&p->log_lock, flags); vf_log(p, VF_OPERATION_FPUT, true); + spin_unlock_irqrestore(&p->log_lock, flags); } /* receiver peek to read */ @@ -558,10 +581,12 @@ struct vf_entry *receiver_vf_peek(struct vf_pool *p) spin_lock_irqsave(&p->rd_lock, flags); vfe = vf_pool_peek(&p->rd_list); spin_unlock_irqrestore(&p->rd_lock, flags); + spin_lock_irqsave(&p->log_lock, flags); if (!vfe) vf_log(p, VF_OPERATION_BPEEK, false); else vf_log(p, VF_OPERATION_BPEEK, true); + spin_unlock_irqrestore(&p->log_lock, flags); if (!vfe) return NULL; return vfe; @@ -572,6 +597,7 @@ struct vf_entry *receiver_vf_get(struct vf_pool *p) { struct vf_entry *vfe; unsigned long flags; + /*get the vframe from the frozen list*/ if (p->pool_flag & VDIN_VF_POOL_FREEZE) { spin_lock_irqsave(&p->fz_lock, flags); @@ -587,7 +613,9 @@ struct vf_entry *receiver_vf_get(struct vf_pool *p) spin_lock_irqsave(&p->rd_lock, flags); if (list_empty(&p->rd_list)) { spin_unlock_irqrestore(&p->rd_lock, flags); + spin_lock_irqsave(&p->log_lock, flags); vf_log(p, VF_OPERATION_BGET, false); + spin_unlock_irqrestore(&p->log_lock, flags); return NULL; } @@ -595,12 +623,13 @@ struct vf_entry *receiver_vf_get(struct vf_pool *p) p->rd_list_size--; spin_unlock_irqrestore(&p->rd_lock, flags); vfe->status = VF_STATUS_RM; - + spin_lock_irqsave(&p->log_lock, flags); vf_log(p, VF_OPERATION_BGET, true); + spin_unlock_irqrestore(&p->log_lock, flags); return vfe; } /*check vf point,0:nornal;1:bad*/ -unsigned int check_vf_put(struct vframe_s *vf, struct vf_pool *p) +static unsigned int check_vf_put(struct vframe_s *vf, struct vf_pool *p) { struct vf_entry *master; unsigned int i; @@ -626,11 +655,12 @@ void receiver_vf_put(struct vframe_s *vf, struct vf_pool *p) return; master = vf_get_master(p, vf->index); if (master == NULL) { + spin_lock_irqsave(&p->log_lock, flags); vf_log(p, VF_OPERATION_BPUT, false); + spin_unlock_irqrestore(&p->log_lock, flags); return; } - /* - * keep the frozen frame in rd list&recycle the + /*keep the frozen frame in rd list&recycle the * frame which not in fz list when unfreeze */ if (master->flag & VF_FLAG_FREEZED_FRAME) { @@ -652,7 +682,9 @@ void receiver_vf_put(struct vframe_s *vf, struct vf_pool *p) vf_pool_put(master, &p->wr_list); p->wr_list_size++; spin_unlock_irqrestore(&p->wr_lock, flags); + spin_lock_irqsave(&p->log_lock, flags); vf_log(p, VF_OPERATION_BPUT, true); + spin_unlock_irqrestore(&p->log_lock, flags); } else { spin_lock_irqsave(&p->wt_lock, flags); list_for_each_entry_safe(pos, tmp, &p->wt_list, list) { @@ -675,7 +707,9 @@ void receiver_vf_put(struct vframe_s *vf, struct vf_pool *p) slave = vf_get_slave(p, vf->index); if (slave == NULL) { spin_unlock_irqrestore(&p->wt_lock, flags); + spin_lock_irqsave(&p->log_lock, flags); vf_log(p, VF_OPERATION_BPUT, false); + spin_unlock_irqrestore(&p->log_lock, flags); return; } /* if found associated entry in wait list */ @@ -692,7 +726,9 @@ void receiver_vf_put(struct vframe_s *vf, struct vf_pool *p) p->wr_list_size++; spin_unlock_irqrestore(&p->wr_lock, flags); slave->status = VF_STATUS_SL; + spin_lock_irqsave(&p->log_lock, flags); vf_log(p, VF_OPERATION_BPUT, true); + spin_unlock_irqrestore(&p->log_lock, flags); } else { /* if not found associated entry in wait list */ @@ -712,7 +748,9 @@ void receiver_vf_put(struct vframe_s *vf, struct vf_pool *p) list_add(&master->list, &p->wt_list); } spin_unlock_irqrestore(&p->wt_lock, flags); + spin_lock_irqsave(&p->log_lock, flags); vf_log(p, VF_OPERATION_BPUT, true); + spin_unlock_irqrestore(&p->log_lock, flags); } } atomic_dec(&p->buffer_cnt); @@ -755,6 +793,13 @@ void vdin_vf_put(struct vframe_s *vf, void *op_arg) return; p = (struct vf_pool *)op_arg; receiver_vf_put(vf, p); + /*clean dv-buf-size*/ + if (vf && (dv_dbg_mask & DV_CLEAN_UP_MEM)) { + p->dv_buf_size[vf->index] = 0; + if (p->dv_buf_ori[vf->index]) + memset(p->dv_buf_ori[vf->index], 0, dolby_size_byte); + + } } int vdin_vf_states(struct vframe_states *vf_ste, void *op_arg) { @@ -771,9 +816,9 @@ int vdin_vf_states(struct vframe_states *vf_ste, void *op_arg) } /* - * hold the buffer from rd list,if rd list is not enough, - * get buffer from wr list - */ +*hold the buffer from rd list,if rd list is not enough, +*get buffer from wr list +*/ void vdin_vf_freeze(struct vf_pool *p, unsigned int num) { struct vf_entry *vfe, *tmp; @@ -843,7 +888,7 @@ void vdin_vf_unfreeze(struct vf_pool *p) spin_unlock_irqrestore(&p->fz_lock, flags); } } - +/*dump vframe state*/ void vdin_dump_vf_state(struct vf_pool *p) { unsigned long flags; @@ -852,42 +897,78 @@ void vdin_dump_vf_state(struct vf_pool *p) pr_info("buffers in writeable list:\n"); spin_lock_irqsave(&p->wr_lock, flags); list_for_each_entry_safe(pos, tmp, &p->wr_list, list) { - pr_info("\t index: %2u,status %u, canvas index0: 0x%x,", + pr_info("index: %2u,status %u, canvas index0: 0x%x,", pos->vf.index, pos->status, pos->vf.canvas0Addr); - pr_info("index1: 0x%x, vframe type: 0x%x.\n", + pr_info("\t canvas index1: 0x%x, vframe type: 0x%x.\n", pos->vf.canvas1Addr, pos->vf.type); + pr_info("\t ratio_control(0x%x).\n", pos->vf.ratio_control); } spin_unlock_irqrestore(&p->wr_lock, flags); pr_info("buffer in readable list:\n"); spin_lock_irqsave(&p->rd_lock, flags); list_for_each_entry_safe(pos, tmp, &p->rd_list, list) { - pr_info("\t index: %u,status %u, canvas index0: 0x%x,", + pr_info("index: %u,status %u, canvas index0: 0x%x,", pos->vf.index, pos->status, pos->vf.canvas0Addr); - pr_info("index1: 0x%x, vframe type: 0x%x.\n", + pr_info("\t canvas index1: 0x%x, vframe type: 0x%x.\n", pos->vf.canvas1Addr, pos->vf.type); + pr_info("\t ratio_control(0x%x).\n", pos->vf.ratio_control); } spin_unlock_irqrestore(&p->rd_lock, flags); pr_info("buffer in waiting list:\n"); spin_lock_irqsave(&p->wt_lock, flags); list_for_each_entry_safe(pos, tmp, &p->wt_list, list) { - pr_info("\t index: %u, status %u, canvas index0: 0x%x,", + pr_info("index: %u, status %u, canvas index0: 0x%x,", pos->vf.index, pos->status, pos->vf.canvas0Addr); - pr_info("index1: 0x%x, vframe type: 0x%x.\n", + pr_info("\t canvas index1: 0x%x, vframe type: 0x%x.\n", pos->vf.canvas1Addr, pos->vf.type); + pr_info("\t ratio_control(0x%x).\n", pos->vf.ratio_control); } spin_unlock_irqrestore(&p->wt_lock, flags); pr_info("buffer in temp list:\n"); spin_lock_irqsave(&p->tmp_lock, flags); list_for_each_entry_safe(pos, tmp, &p->tmp_list, list) { - pr_info("\t index: %u, status %u, canvas index0: 0x%x,", + pr_info("index: %u, status %u, canvas index0: 0x%x,", pos->vf.index, pos->status, pos->vf.canvas0Addr); - pr_info("index1: 0x%x, vframe type: 0x%x.\n", + pr_info("\t canvas index1: 0x%x, vframe type: 0x%x.\n", pos->vf.canvas1Addr, pos->vf.type); + pr_info("\t ratio_control(0x%x).\n", pos->vf.ratio_control); } spin_unlock_irqrestore(&p->tmp_lock, flags); pr_info("buffer get count %d.\n", atomic_read(&p->buffer_cnt)); } +/*update the vframe disp_mode + * a.VFRAME_DISP_MODE_UNKNOWN + * b. VFRAME_DISP_MODE_OK + */ +void vdin_vf_disp_mode_update(struct vf_entry *vfe, struct vf_pool *p) +{ + unsigned int i; + + for (i = p->skip_vf_num; (i > 0) && (i < VFRAME_DISP_MAX_NUM); i--) + p->disp_index[i] = p->disp_index[i - 1]; + p->disp_index[0]++; + if (p->disp_index[0] >= VFRAME_DISP_MAX_NUM) + p->disp_index[0] = 0; + vfe->vf.index_disp = p->disp_index[0]; + + p->disp_mode[p->disp_index[p->skip_vf_num]] = VFRAME_DISP_MODE_OK; + for (i = p->skip_vf_num - 1; (i >= 0) && (i < VFRAME_DISP_MAX_NUM); i--) + p->disp_mode[p->disp_index[i]] = VFRAME_DISP_MODE_UNKNOWN; +} +/*disp mode skip + *skip_vf_num + * 2:last last vframe, 1:last vframe + * 0:current vframe + */ +void vdin_vf_disp_mode_skip(struct vf_pool *p) +{ + unsigned int i; + + for (i = p->skip_vf_num - 1; (i >= 0) && (i < VFRAME_DISP_MAX_NUM); i--) + p->disp_mode[i] = VFRAME_DISP_MODE_SKIP; +} + diff --git a/drivers/amlogic/media/vin/tvin/vdin/vdin_vf.h b/drivers/amlogic/media/vin/tvin/vdin/vdin_vf.h index a6dbc9aa8c76..a4466f2ac381 100644 --- a/drivers/amlogic/media/vin/tvin/vdin/vdin_vf.h +++ b/drivers/amlogic/media/vin/tvin/vdin/vdin_vf.h @@ -19,13 +19,10 @@ #define __VDIN_VF_H /* Standard Linux Headers */ -#include #include #include -#include /* Amlogic Linux Headers */ -#include #include #define VF_LOG_EN @@ -37,6 +34,16 @@ /* only log backend opertations */ #define VF_LOG_BE +#define VDIN_DV_MAX_NUM 9 + +#define VF_FLAG_NORMAL_FRAME 0x00000001 +#define VF_FLAG_FREEZED_FRAME 0x00000002 +#define VFRAME_DISP_MAX_NUM 10 +#define VDIN_VF_POOL_FREEZE 0x00000001 +#define ISR_LOG_EN + +#define VF_LOG_PRINT_MAX_LEN 100 + enum vf_operation_e { VF_OPERATION_INIT = 0, VF_OPERATION_FPEEK, @@ -84,9 +91,8 @@ struct vf_log_s { #endif -#define ISR_LOG_EN #ifdef ISR_LOG_EN -#define ISR_LOG_LEN 2000 +#define ISR_LOG_LEN 2000 struct isr_log_s { struct timeval isr_time[ISR_LOG_LEN]; unsigned int log_cur; @@ -94,9 +100,6 @@ struct isr_log_s { }; #endif -#define VF_FLAG_NORMAL_FRAME 0x00000001 -#define VF_FLAG_FREEZED_FRAME 0x00000002 - struct vf_entry { struct vframe_s vf; @@ -105,28 +108,28 @@ struct vf_entry { unsigned int flag; }; -#define VDIN_VF_POOL_FREEZE 0x00000001 struct vf_pool { unsigned int pool_flag; unsigned int max_size, size; struct vf_entry *master; struct vf_entry *slave; struct list_head wr_list; /* vf_entry */ - spinlock_t wr_lock; - unsigned int wr_list_size; + spinlock_t wr_lock; + unsigned int wr_list_size; struct list_head *wr_next; struct list_head rd_list; /* vf_entry */ - spinlock_t rd_lock; - unsigned int rd_list_size; + spinlock_t rd_lock; + unsigned int rd_list_size; struct list_head wt_list; /* vframe_s */ - spinlock_t wt_lock; - unsigned int fz_list_size; + spinlock_t wt_lock; + unsigned int fz_list_size; struct list_head fz_list; - spinlock_t fz_lock; - unsigned int tmp_list_size; + spinlock_t fz_lock; + unsigned int tmp_list_size; struct list_head tmp_list; spinlock_t tmp_lock; - spinlock_t lock; + spinlock_t log_lock; + spinlock_t dv_lock;/*dolby vision lock*/ #ifdef VF_LOG_EN struct vf_log_s log; #endif @@ -134,7 +137,17 @@ struct vf_pool { struct isr_log_s isr_log; #endif atomic_t buffer_cnt; + unsigned int dv_buf_mem[VDIN_DV_MAX_NUM]; + void *dv_buf_vmem[VDIN_DV_MAX_NUM]; + unsigned int dv_buf_size[VDIN_DV_MAX_NUM]; + char *dv_buf[VDIN_DV_MAX_NUM]; + char *dv_buf_ori[VDIN_DV_MAX_NUM]; + unsigned int disp_index[VFRAME_DISP_MAX_NUM]; + unsigned int skip_vf_num;/*skip pre vframe num*/ + enum vframe_disp_mode_e disp_mode[VFRAME_DISP_MAX_NUM]; }; +extern unsigned int dolby_size_byte; +extern unsigned int dv_dbg_mask; extern void vf_log_init(struct vf_pool *p); extern void vf_log_print(struct vf_pool *p); @@ -162,6 +175,7 @@ extern struct vf_entry *receiver_vf_peek(struct vf_pool *p); extern struct vf_entry *receiver_vf_get(struct vf_pool *p); extern void receiver_vf_put(struct vframe_s *vf, struct vf_pool *p); + extern struct vframe_s *vdin_vf_peek(void *op_arg); extern struct vframe_s *vdin_vf_get(void *op_arg); extern void vdin_vf_put(struct vframe_s *vf, void *op_arg); @@ -171,5 +185,8 @@ extern void vdin_vf_freeze(struct vf_pool *p, unsigned int hold_num); extern void vdin_vf_unfreeze(struct vf_pool *p); extern void vdin_dump_vf_state(struct vf_pool *p); + +extern void vdin_vf_disp_mode_update(struct vf_entry *vfe, struct vf_pool *p); +extern void vdin_vf_disp_mode_skip(struct vf_pool *p); #endif /* __VDIN_VF_H */ diff --git a/include/linux/amlogic/media/frame_provider/tvin/tvin.h b/include/linux/amlogic/media/frame_provider/tvin/tvin.h index 0f0d786abd33..ecd3df219d03 100644 --- a/include/linux/amlogic/media/frame_provider/tvin/tvin.h +++ b/include/linux/amlogic/media/frame_provider/tvin/tvin.h @@ -330,7 +330,9 @@ enum tvin_sig_fmt_e { TVIN_SIG_FMT_HDMI_RESERVE11 = 0x44b, TVIN_SIG_FMT_HDMI_720X480P_60HZ_FRAME_PACKING = 0x44c, TVIN_SIG_FMT_HDMI_720X576P_50HZ_FRAME_PACKING = 0x44d, - TVIN_SIG_FMT_HDMI_MAX = 0x44e, + TVIN_SIG_FMT_HDMI_640X480P_72HZ = 0x44e, + TVIN_SIG_FMT_HDMI_640X480P_75HZ = 0x44f, + TVIN_SIG_FMT_HDMI_MAX = 0x450, TVIN_SIG_FMT_HDMI_THRESHOLD = 0x600, /* Video Formats */ TVIN_SIG_FMT_CVBS_NTSC_M = 0x601, @@ -340,7 +342,8 @@ enum tvin_sig_fmt_e { TVIN_SIG_FMT_CVBS_PAL_60 = 0x605, TVIN_SIG_FMT_CVBS_PAL_CN = 0x606, TVIN_SIG_FMT_CVBS_SECAM = 0x607, - TVIN_SIG_FMT_CVBS_MAX = 0x608, + TVIN_SIG_FMT_CVBS_NTSC_50 = 0x608, + TVIN_SIG_FMT_CVBS_MAX = 0x609, TVIN_SIG_FMT_CVBS_THRESHOLD = 0x800, /* 656 Formats */ TVIN_SIG_FMT_BT656IN_576I_50HZ = 0x801, @@ -460,7 +463,7 @@ struct tvin_info_s { enum tvin_sig_status_e status; enum tvin_color_fmt_e cfmt; unsigned int fps; - unsigned int reserved; + unsigned int is_dvi; }; struct tvin_buf_info_s { @@ -871,6 +874,14 @@ struct tvafe_pin_mux_s { *adc pll ctl, atv demod & tvafe use the same adc module * module index: atv demod:0x01; tvafe:0x2 */ -extern void adc_set_pll_cntl(bool on, unsigned int module_sel); +/* extern void adc_set_pll_cntl(bool on, unsigned int module_sel);*/ + +struct dfe_adcpll_para { + unsigned int adcpllctl; + unsigned int demodctl; + unsigned int atsc; +}; +extern int adc_set_pll_cntl(bool on, unsigned int module_sel, void *pDtvPara); +extern void tvafe_set_ddemod_default(void);/* add for dtv demod*/ #endif diff --git a/include/linux/amlogic/media/frame_provider/tvin/tvin_v4l2.h b/include/linux/amlogic/media/frame_provider/tvin/tvin_v4l2.h index 954f4a27cf88..493bc9a22051 100644 --- a/include/linux/amlogic/media/frame_provider/tvin/tvin_v4l2.h +++ b/include/linux/amlogic/media/frame_provider/tvin/tvin_v4l2.h @@ -800,9 +800,9 @@ struct vdin_parm_s { enum bt_path_e bt_path; /* 0:from gpio,1:from csi2 */ unsigned char hsync_phase; /* 1: inverted 0: original */ unsigned char vsync_phase; /* 1: inverted 0: origianl */ - unsigned short hs_bp; /* the horizontal start postion of bt656 window */ - unsigned short vs_bp; /* the vertical start postion of bt656 window */ - unsigned short fid_check_cnt; /* vs check hs timeout cnt */ + unsigned short hs_bp;/* the horizontal start postion of bt656 window */ + unsigned short vs_bp;/* the vertical start postion of bt656 window */ + unsigned short fid_check_cnt; /* vs check hs timeout cnt */ /*for isp tell different frontends such as bt656/mipi */ enum tvin_port_e isp_fe_port; /*for vdin cfmt convert & scale&skip */ diff --git a/include/linux/amlogic/media/vfm/vframe_provider.h b/include/linux/amlogic/media/vfm/vframe_provider.h index 081571e0437f..6ec13d81577b 100644 --- a/include/linux/amlogic/media/vfm/vframe_provider.h +++ b/include/linux/amlogic/media/vfm/vframe_provider.h @@ -49,6 +49,7 @@ struct provider_aux_req_s { char *aux_buf; int aux_size; int dv_enhance_exist; + int low_latency; }; struct provider_disp_mode_req_s { /*input*/