};
vdac {
- compatible = "amlogic, vdac-tl1";
+ compatible = "amlogic, vdac-tm2";
status = "okay";
};
vdin1_cma_reserved:linux,vdin1_cma {
compatible = "shared-dma-pool";
reusable;
- /* 1920x1080x2x4 =16 M */
- size = <0x1400000>;
+ /*keystone need 4 buffers,each has 1920*1080*3
+ *for keystone, change to 0x1800000(24M)
+ */
+ size = <0x1400000>;/*20M*/
alignment = <0x400000>;
};
vdin1_cma_reserved:linux,vdin1_cma {
compatible = "shared-dma-pool";
reusable;
- /* 1920x1080x2x4 =16 M */
- size = <0x1400000>;
+ /*keystone need 4 buffers,each has 1920*1080*3
+ *for keystone, change to 0x1800000(24M)
+ */
+ size = <0x1400000>;/*20M*/
alignment = <0x400000>;
};
};
vdac {
- compatible = "amlogic, vdac-tl1";
+ compatible = "amlogic, vdac-tm2";
status = "okay";
};
#define HHI_SYS_PLL_CNTL5 0x308 /* 0xc2 offset in datasheet */
#define HHI_SYS_PLL_CNTL6 0x30c /* 0xc3 offset in datasheet */
+#if 0/*tl1 no*/
#define HHI_HDMI_PLL_CNTL 0x320 /* 0xc8 offset in datasheet */
#define HHI_HDMI_PLL_CNTL2 0x324 /* 0xc9 offset in datasheet */
#define HHI_HDMI_PLL_CNTL3 0x328 /* 0xca offset in datasheet */
#define HHI_HDMI_PLL_CNTL4 0x32C /* 0xcb offset in datasheet */
#define HHI_HDMI_PLL_CNTL5 0x330 /* 0xcc offset in datasheet */
+#endif
#define HHI_VID_LOCK_CLK_CNTL 0x3c8 /* 0xf2 offset in datasheet1 */
#define HHI_BT656_CLK_CNTL 0x3d4 /* 0xf5 offset in datasheet1 */
#define HHI_SPICC_CLK_CNTL 0x3dc /* 0xf7 offset in datasheet1 */
#include <linux/stat.h>
#include <linux/errno.h>
#include <linux/uaccess.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
/* #include <linux/amlogic/aml_common.h> */
#include <linux/ctype.h>/* for parse_para_pq */
#include <linux/vmalloc.h>
static int vdj_mode_flg;
struct am_vdj_mode_s vdj_mode_s;
-void __iomem *amvecm_hiu_reg_base;/* = *ioremap(0xc883c000, 0x2000); */
+/*void __iomem *amvecm_hiu_reg_base;*//* = *ioremap(0xc883c000, 0x2000); */
static int debug_amvecm;
module_param(debug_amvecm, int, 0664);
sel = VLOCK_SUPPORT;
} else if (!strncmp(parm[0], "enable", 6)) {
vecm_latch_flag |= FLAG_VLOCK_EN;
+ vlock_set_en(true);
} else if (!strncmp(parm[0], "disable", 7)) {
vecm_latch_flag |= FLAG_VLOCK_DIS;
} else if (!strncmp(parm[0], "status", 6)) {
vlock_log_stop();
} else if (!strncmp(parm[0], "log_print", 9)) {
vlock_log_print();
+ } else if (!strncmp(parm[0], "phase", 5)) {
+ if (kstrtol(parm[1], 10, &val) < 0)
+ return -EINVAL;
+ vlock_set_phase(val);
+ } else if (!strncmp(parm[0], "phlock_en", 9)) {
+ if (kstrtol(parm[1], 10, &val) < 0)
+ return -EINVAL;
+ vlock_set_phase_en(val);
} else {
- pr_info("unsupport cmd!!\n");
+ pr_info("----cmd list -----\n");
+ pr_info("vlock_mode val\n");
+ pr_info("vlock_en val\n");
+ pr_info("vlock_debug val\n");
+ pr_info("vlock_adapt val\n");
+ pr_info("vlock_dis_cnt_limit val\n");
+ pr_info("vlock_delta_limit val\n");
+ pr_info("vlock_dynamic_adjust val\n");
+ pr_info("vlock_line_limit val\n");
+ pr_info("vlock_dis_cnt_no_vf_limit val\n");
+ pr_info("vlock_line_limit val\n");
+ pr_info("vlock_support val\n");
+ pr_info("enable\n");
+ pr_info("disable\n");
+ pr_info("status\n");
+ pr_info("dump_reg\n");
+ pr_info("log_start\n");
+ pr_info("log_stop\n");
+ pr_info("log_print\n");
+ pr_info("phase persent\n");
+ pr_info("phlock_en val\n");
}
if (sel < VLOCK_PARAM_MAX)
vlock_param_set(temp_val, sel);
#endif
.poll = amvecm_poll,
};
+
+static const struct vecm_match_data_s vecm_dt_xxx = {
+ .vlk_support = true,
+ .vlk_new_fsm = 0,
+ .vlk_hwver = vlock_hw_org,
+ .vlk_phlock_en = false,
+};
+
+static const struct vecm_match_data_s vecm_dt_tl1 = {
+ .vlk_support = true,
+ .vlk_new_fsm = 1,
+ .vlk_hwver = vlock_hw_ver2,
+ .vlk_phlock_en = true,
+};
+
+static const struct of_device_id aml_vecm_dt_match[] = {
+ {
+ .compatible = "amlogic, vecm",
+ .data = &vecm_dt_xxx,
+ },
+ {
+ .compatible = "amlogic, vecm-tl1",
+ .data = &vecm_dt_tl1,
+ },
+ {},
+};
+
static void aml_vecm_dt_parse(struct platform_device *pdev)
{
struct device_node *node;
unsigned int val;
int ret;
+ const struct of_device_id *of_id;
+ struct vecm_match_data_s *matchdata;
node = pdev->dev.of_node;
/* get integer value */
pr_info("Can't find tx_op_color_primary.\n");
else
tx_op_color_primary = val;
+
+ /*get compatible matched device, to get chip related data*/
+ of_id = of_match_device(aml_vecm_dt_match, &pdev->dev);
+ if (of_id != NULL) {
+ pr_info("%s", of_id->compatible);
+ matchdata = (struct vecm_match_data_s *)of_id->data;
+ } else {
+ matchdata = (struct vecm_match_data_s *)&vecm_dt_xxx;
+ pr_info("unable to get matched device\n");
+ }
+ vlock_dt_match_init(matchdata);
+
/*vlock param config*/
vlock_param_config(node);
}
if (is_meson_g12a_cpu() || is_meson_g12b_cpu())
sdr_mode = 2;
- /*config vlock mode*/
- /*todo:txlx & g9tv support auto pll,*/
- /*but support not good,need vlsi support optimize*/
- vlock_mode = VLOCK_MODE_MANUAL_PLL;
- if (is_meson_gxtvbb_cpu() ||
- is_meson_txl_cpu() || is_meson_txlx_cpu()
- || is_meson_txhd_cpu())
- vlock_en = 1;
- else
- vlock_en = 0;
+ vlock_status_init();
hdr_init(&amvecm_dev.hdr_d);
aml_vecm_dt_parse(pdev);
#endif
}
-static const struct of_device_id aml_vecm_dt_match[] = {
- {
- .compatible = "amlogic, vecm",
- },
- {},
-};
-
static struct platform_driver aml_vecm_driver = {
.driver = {
.name = "aml_vecm",
static int __init aml_vecm_init(void)
{
- unsigned int hiu_reg_base;
+ /*unsigned int hiu_reg_base;*/
pr_info("%s:module init\n", __func__);
+ #if 0
/* remap the hiu bus */
if (is_meson_txlx_cpu() || is_meson_txhd_cpu() ||
- is_meson_g12a_cpu() || is_meson_g12b_cpu())
+ is_meson_g12a_cpu() || is_meson_g12b_cpu()
+ || is_meson_tl1_cpu())
hiu_reg_base = 0xff63c000;
else
hiu_reg_base = 0xc883c000;
amvecm_hiu_reg_base = ioremap(hiu_reg_base, 0x2000);
+ #endif
if (platform_driver_register(&aml_vecm_driver)) {
pr_err("failed to register bl driver module\n");
return -ENODEV;
static void __exit aml_vecm_exit(void)
{
pr_info("%s:module exit\n", __func__);
- iounmap(amvecm_hiu_reg_base);
+ /*iounmap(amvecm_hiu_reg_base);*/
platform_driver_unregister(&aml_vecm_driver);
}
{0x3000, 0xE3f50f10 },
{0x3001, 0x41E3c3c },
{0x3002, 0x6000000 },
- {0x3003, 0x20680680 },
- {0x3004, 0x280280 },
+ {0x3003, 0x20709709/*0x20680680 */},
+ {0x3004, 0x00709709/*0x280280 */},
{0x3005, 0x8020000 },
{0x3006, 0x0008000 },
{0x3007, 0x0000000 },
{0x3008, 0x0000000 },
- {0x3009, 0x0008000 },
+ {0x3009, 0x6000000/*0x0008000 */},
{0x300a, 0x8000000 },
{0x300b, 0x000a000 },
{0x300c, 0xa000000 },
{0x3001, 0x04053c32 },
{0x3002, 0x06000000 },
{0x3003, 0x20780780 },
- {0x3004, 0x00000000 },
+ {0x3004, 0x00680680 },
{0x3005, 0x00080000 },
{0x3006, 0x00070000 },
{0x3007, 0x00000000 },
{0x3009, 0x00100000 },
{0x300a, 0x00600000 },
{0x300b, 0x00100000 },
- {0x300c, 0x00000000 },
+ {0x300c, 0x00600000 },
{0x300d, 0x00004000 },
{0x3010, 0x20001000 },
{0x3016, 0x0003de00 },
- {0x3017, 0x00001080 },
+ {0x3017, 0x00001010 },
{0x301d, 0x30501080 },
{0x301e, 0x00000007 },
{0x301f, 0x06000000 }
};
+#define VLOCK_PHASE_REG_SIZE 9
+static struct vlock_regs_s vlock_pll_phase_setting[VLOCK_PHASE_REG_SIZE] = {
+ {0x3004, 0x00620680},
+ {0x3009, 0x06000000},
+ {0x300a, 0x00600000},
+ {0x300b, 0x06000000},
+ {0x300c, 0x00600000},
+
+ {0x3025, 0x00002000},
+ {0x3027, 0x00022002},
+ {0x3028, 0x00001000},
+ {0x302a, 0x00022002},
+};
+
#endif
#define VPU_VLOCK_GCLK_EN 0x301e
#define VPU_VLOCK_LOOP1_ACCUM_LMT 0x301f
#define VPU_VLOCK_RO_M_INT_FRAC 0x3020
+#define VPU_VLOCK_RO_LCK_FRM 0x3024
#define XVYCC_VD1_RGB_CTRST 0x3170
/*ve dither*/
#define VPP_VE_DITHER_CTRL 0x3120
+/* TL1 */
+/*offset 0x1000*/
+#define HHI_TCON_PLL_CNTL0 0x20
+#define HHI_TCON_PLL_CNTL1 0x21
+#define HHI_HDMI_PLL_VLOCK_CNTL 0xd1
+
/* for pll bug */
-#define HHI_HDMI_PLL_CNTL 0x10c8
-#define HHI_HDMI_PLL_CNTL2 0x10c9
-#define HHI_VID_LOCK_CLK_CNTL 0x10f2
-#define HHI_HDMI_PLL_CNTL6 0x10cd
+
+#define HHI_HDMI_PLL_CNTL 0xc8
+#define HHI_HDMI_PLL_CNTL2 0xc9
+#define HHI_VID_LOCK_CLK_CNTL 0xf2
+#define HHI_HDMI_PLL_CNTL6 0xcd
+
/* for vlock enc mode adjust begin */
#define ENCL_VIDEO_MAX_LNCNT 0x1cbb
#define ENCL_VIDEO_MAX_PXCNT 0x1cb0
#define ENCT_MAX_LINE_SWITCH_POINT 0x1c88
/* for vlock enc mode adjust end */
-#define HHI_VID_LOCK_CLK_CNTL 0x10f2
-
#define VDIN_MEAS_VS_COUNT_LO 0x125c
+/*for vlock*/
/*after GXL new add CNTL1,same with CNTL2 on G9TV/GXTVBB*/
-#define HHI_HDMI_PLL_CNTL1 0x10c9
+#define HHI_HDMI_PLL_CNTL1 0xc9
/*after GXL CNTL5[bit3] is same with CNTL6[bit20] on G9TV/GXTVBB*/
-#define HHI_HDMI_PLL_CNTL5 0x10cd
+#define HHI_HDMI_PLL_CNTL5 0xcd
/* #define VI_HIST_CTRL 0x2e00 */
#include "amcm.h"
/* video lock */
-/* 0:enc;1:pll;
- * 2:manual pll;
- * 3:manual_enc mode(only support lvds/vx1)
+/* 0:off;
+ * 1:auto enc;
+ * 2:auto pll;
+ * 4:manual pll;
+ * 8:manual_enc mode(only support lvds/vx1)
*/
-unsigned int vlock_mode = VLOCK_MODE_MANUAL_PLL;
+enum VLOCK_MD vlock_mode = VLOCK_MODE_MANUAL_PLL;
unsigned int vlock_en = 1;
/*
*0:only support 50->50;60->60;24->24;30->30;
static signed int vlock_line_limit = 3;
static unsigned int vlock_enc_adj_limit;
/* 0x3009 default setting for 2 line(1080p-output) is 0x8000 */
-static unsigned int vlock_capture_limit = 0x8000;
+static unsigned int vlock_capture_limit = 0x10000/*0x8000*/;
static unsigned int vlock_debug;
static unsigned int vlock_dynamic_adjust = 1;
static unsigned int vlock_log_last_ovcnt;
static unsigned int vlock_log_delta_m;
static unsigned int vlock_log_delta_en;
+static unsigned int hhi_pll_reg_m;
+static unsigned int hhi_pll_reg_frac;
+
+static struct stvlock_sig_sts vlock;
+
+/*static unsigned int hhi_pll_reg_vlock_ctl;*/
module_param(vlock_log_size, uint, 0664);
MODULE_PARM_DESC(vlock_log_size, "\n vlock_log_size\n");
module_param(vlock_log_cnt, uint, 0664);
int amvecm_hiu_reg_read(unsigned int reg, unsigned int *val)
{
- *val = readl(amvecm_hiu_reg_base+((reg - 0x1000)<<2));
+ /**val = readl(amvecm_hiu_reg_base+((reg - 0x1000)<<2));*/
+ *val = aml_read_hiubus(reg);
+ /*pr_info("vlock rd hiu reg:0x%x,0x%x\n", (reg - 0x1000), *val);*/
return 0;
}
int amvecm_hiu_reg_write(unsigned int reg, unsigned int val)
{
- writel(val, (amvecm_hiu_reg_base+((reg - 0x1000)<<2)));
+ /*writel(val, (amvecm_hiu_reg_base+((reg - 0x1000)<<2)));*/
+ /*pr_info("vlock rd hiu reg:0x%x,0x%x\n", (reg - 0x1000), val);*/
+ aml_write_hiubus(reg, val);
return 0;
}
static int amvecm_hiu_reg_write_bits(unsigned int reg, unsigned int value,
return 0;
}
+u32 vlock_get_panel_pll_m(void)
+{
+ u32 val;
+
+ amvecm_hiu_reg_read(hhi_pll_reg_m, &val);
+ return val;
+}
+
+void vlock_set_panel_pll_m(u32 val)
+{
+ amvecm_hiu_reg_write(hhi_pll_reg_m, val);
+}
+
+u32 vlock_get_panel_pll_frac(void)
+{
+ u32 val;
+
+ amvecm_hiu_reg_read(hhi_pll_reg_frac, &val);
+ return val;
+}
+
+void vlock_set_panel_pll_frac(u32 val)
+{
+ amvecm_hiu_reg_write(hhi_pll_reg_frac, val);
+}
+
+
+/*returen 1: use phase lock*/
+int phase_lock_check(void)
+{
+ unsigned int ret = 0;
+
+ ret = READ_VPP_REG_BITS(VPU_VLOCK_RO_LCK_FRM, 17, 1);
+ return ret;
+}
static unsigned int vlock_check_input_hz(struct vframe_s *vf)
{
return ret_hz;
}
-static unsigned int vlock_check_output_hz(unsigned int sync_duration_num)
+static unsigned int vlock_check_output_hz(unsigned int sync_duration_num,
+ unsigned int sync_duration_den)
{
unsigned int ret_hz = 0;
+ unsigned int tempHz;
+
+ tempHz = (sync_duration_num*100)/sync_duration_den;
- switch (sync_duration_num) {
- case 24:
+ switch (tempHz) {
+ case 2400:
ret_hz = 24;
break;
- case 30:
+ case 3000:
ret_hz = 30;
break;
- case 50:
+ case 5000:
ret_hz = 50;
break;
- case 60:
+ case 6000:
ret_hz = 60;
break;
- case 100:
+ case 10000:
ret_hz = 100;
break;
- case 120:
+ case 12000:
ret_hz = 120;
break;
default:
ret_hz = 0;
break;
}
+
+ if ((ret_hz == 0) && (vlock_debug & VLOCK_DEBUG_INFO))
+ pr_info("sync_duration_num:%d\n", sync_duration_num);
+
return ret_hz;
}
/*vlock is support eq_after gxbb,but which is useful only for tv chip
{
unsigned int tmp_value;
- amvecm_hiu_reg_read(HHI_HDMI_PLL_CNTL6, &tmp_value);
-
if (is_meson_gxtvbb_cpu()) {
if (vlock_mode & VLOCK_MODE_MANUAL_PLL) {
+ amvecm_hiu_reg_read(HHI_HDMI_PLL_CNTL6, &tmp_value);
amvecm_hiu_reg_write_bits(HHI_HDMI_PLL_CNTL6, 0, 20, 1);
/*vlsi suggest config:don't enable load signal,
*on gxtvbb this load signal will effect SSG,
else
amvecm_hiu_reg_write_bits(HHI_HDMI_PLL_CNTL5,
enable, 3, 1);
+ } else if (vlock.dtdata->vlk_hwver >= vlock_hw_ver2) {
+ /*reset*/
+ if (!(vlock_mode & VLOCK_MODE_MANUAL_PLL)) {
+ /*reset*/
+ /*WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 1, 5, 1);*/
+ /*WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 0, 5, 1);*/
+ }
+
+ if (!enable) {
+ /*amvecm_hiu_reg_write_bits(*/
+ /* HHI_HDMI_PLL_VLOCK_CNTL, 0, 0, 3);*/
+
+ /*WRITE_VPP_REG(VPU_VLOCK_CTRL, 0);*/
+ }
}
+
+ if (vlock_debug & VLOCK_DEBUG_INFO)
+ pr_info(">>>[%s] (%d)\n", __func__, enable);
}
static void vlock_hw_reinit(struct vlock_regs_s *vlock_regs, unsigned int len)
{
return;
for (i = 0; i < len; i++)
WRITE_VPP_REG(vlock_regs[i].addr, vlock_regs[i].val);
+
+ if (vlock_debug & VLOCK_DEBUG_INFO)
+ pr_info("[%s]\n", __func__);
}
static void vlock_setting(struct vframe_s *vf,
unsigned int input_hz, unsigned int output_hz)
{
- unsigned int freq_hz = 0, hiu_reg_value_2_addr = HHI_HDMI_PLL_CNTL2;
+ unsigned int freq_hz = 0;
unsigned int reg_value = 0, hiu_reg_value, hiu_reg_value_2;
- unsigned int hiu_m_val, hiu_frac_val, temp_value;
+ unsigned int hiu_m_val = 0, hiu_frac_val = 0, temp_value;
+ if (vlock_debug & VLOCK_DEBUG_INFO) {
+ pr_info(">>>[%s]\n", __func__);
+ pr_info("inputHz:%d,outputHz:%d\n", input_hz, output_hz);
+ pr_info("type_original:0x%x\n", vf->type_original);
+ }
amvecm_hiu_reg_write(HHI_VID_LOCK_CLK_CNTL, 0x80);
- if ((vlock_mode & (VLOCK_MODE_AUTO_ENC |
- VLOCK_MODE_MANUAL_ENC |
- VLOCK_MODE_MANUAL_SOFT_ENC))) {
+ if (IS_ENC_MODE(vlock_mode)) {
/*init default config for enc mode*/
vlock_hw_reinit(vlock_enc_setting, VLOCK_DEFAULT_REG_SIZE);
/*vlock line limit*/
- WRITE_VPP_REG(VPU_VLOCK_OUTPUT0_CAPT_LMT, vlock_capture_limit);
+ /*WRITE_VPP_REG(VPU_VLOCK_OUTPUT0_CAPT_LMT,*/
+ /* vlock_capture_limit);*/
+
/* VLOCK_CNTL_EN disable */
vlock_enable(0);
/* disable to adjust pll */
}
/* enable to adjust enc */
WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 1, 30, 1);
- /*clear accum1 value*/
- WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 1, 2, 1);
- /*clear accum0 value*/
- WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 1, 5, 1);
+ if (get_cpu_type() < MESON_CPU_MAJOR_ID_TL1) {
+ /*clear accum1 value*/
+ WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 1, 2, 1);
+ /*clear accum0 value*/
+ WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 1, 5, 1);
+ }
/*@20180314 new add*/
/*
*set input & output freq
*bit8~15:output freq
*/
if ((vf->type_original & VIDTYPE_TYPEMASK) &&
- !(vlock_mode & VLOCK_MODE_MANUAL_SOFT_ENC))
- input_hz = input_hz >> 1;
+ !(vlock_mode & VLOCK_MODE_MANUAL_SOFT_ENC)) {
+ /*tl1 fix i problem*/
+ if (get_cpu_type() < MESON_CPU_MAJOR_ID_TL1)
+ input_hz = input_hz >> 1;
+ else
+ WRITE_VPP_REG_BITS(VPU_VLOCK_MISC_CTRL,
+ 1, 28, 1);
+ }
freq_hz = input_hz | (output_hz << 8);
WRITE_VPP_REG_BITS(VPU_VLOCK_MISC_CTRL, freq_hz, 0, 16);
/*
WRITE_VPP_REG_BITS(VPU_VLOCK_MISC_CTRL,
input_hz, 16, 8);
temp_value = READ_VPP_REG(enc_max_line_addr);
- WRITE_VPP_REG_BITS(VPU_VLOCK_OROW_OCOL_MAX, temp_value, 0, 14);
+ WRITE_VPP_REG_BITS(VPU_VLOCK_OROW_OCOL_MAX,
+ temp_value + 1, 0, 14);
temp_value = READ_VPP_REG(enc_max_pixel_addr);
- WRITE_VPP_REG_BITS(VPU_VLOCK_OROW_OCOL_MAX, temp_value, 16, 14);
+ WRITE_VPP_REG_BITS(VPU_VLOCK_OROW_OCOL_MAX,
+ temp_value + 1, 16, 14);
WRITE_VPP_REG_BITS(VPU_VLOCK_ADJ_EN_SYNC_CTRL,
vlock_latch_en_cnt, 8, 8);
- WRITE_VPP_REG_BITS(enc_video_mode_addr, 0, 15, 1);
+ WRITE_VPP_REG_BITS(enc_video_mode_addr, 1, 15, 1);
}
if ((vlock_mode & (VLOCK_MODE_AUTO_PLL |
VLOCK_MODE_MANUAL_PLL))) {
*bit0~7:input freq
*bit8~15:output freq
*/
- if (vf->type_original & VIDTYPE_TYPEMASK)
- input_hz = input_hz >> 1;
+ if (vf->type_original & VIDTYPE_TYPEMASK) {
+ if (get_cpu_type() < MESON_CPU_MAJOR_ID_TL1)
+ input_hz = input_hz >> 1;
+ else
+ WRITE_VPP_REG_BITS(VPU_VLOCK_MISC_CTRL,
+ 1, 28, 1);
+ } else {
+ if (cpu_after_eq(MESON_CPU_MAJOR_ID_TL1))
+ WRITE_VPP_REG_BITS(VPU_VLOCK_MISC_CTRL,
+ 0, 28, 1);
+ }
freq_hz = input_hz | (output_hz << 8);
WRITE_VPP_REG_BITS(VPU_VLOCK_MISC_CTRL, freq_hz, 0, 16);
/*
/*set PLL M_INT;PLL M_frac*/
/* WRITE_VPP_REG_BITS(VPU_VLOCK_MX4096, */
/* READ_CBUS_REG_BITS(HHI_HDMI_PLL_CNTL,0,9),12,9); */
- amvecm_hiu_reg_read(HHI_HDMI_PLL_CNTL, &hiu_reg_value);
- amvecm_hiu_reg_read(hiu_reg_value_2_addr,
- &hiu_reg_value_2);
- if (cpu_after_eq(MESON_CPU_MAJOR_ID_GXTVBB)) {
+ /*amvecm_hiu_reg_read(hhi_pll_reg_m, &hiu_reg_value);*/
+ /*amvecm_hiu_reg_read(hhi_pll_reg_frac,*/
+ /* &hiu_reg_value_2);*/
+ hiu_reg_value = vlock_get_panel_pll_m();
+ hiu_reg_value_2 = vlock_get_panel_pll_frac();
+
+ if (vlock_debug & VLOCK_DEBUG_INFO) {
+ pr_info("hhi_pll_reg_m:0x%x\n", hiu_reg_value);
+ pr_info("hhi_pll_reg_frac:0x%x\n", hiu_reg_value_2);
+ }
+
+ if (cpu_after_eq(MESON_CPU_MAJOR_ID_TL1)) {
+ hiu_m_val = hiu_reg_value & 0xff;
+ /*discard low 5 bits*/
+ hiu_frac_val = (hiu_reg_value_2 >> 5) & 0xfff;
+ reg_value = (hiu_m_val << 12) + hiu_frac_val;
+ } else if (cpu_after_eq(MESON_CPU_MAJOR_ID_GXTVBB)) {
hiu_m_val = hiu_reg_value & 0x1FF;
hiu_frac_val = hiu_reg_value_2 & 0x3FF;
if (hiu_reg_value_2 & 0x800) {
}
reg_value = (hiu_m_val << 12)
+ (hiu_frac_val << 2);
+ } else {
+ pr_info("err: m f value\n");
+ }
+ if (vlock_debug & VLOCK_DEBUG_INFO) {
+ pr_info("hiu_m_val=0x%x\n", hiu_m_val);
+ pr_info("hiu_frac_val=0x%x\n", hiu_frac_val);
}
WRITE_VPP_REG_BITS(VPU_VLOCK_MX4096, reg_value, 0, 21);
/*vlock_pll_adj_limit = (reg_value * 0x8000) >> 24;*/
/* enable to adjust pll */
WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 1, 29, 1);
}
+
+ /*initial phase lock setting*/
+ if (vlock.dtdata->vlk_phlock_en) {
+ vlock_hw_reinit(vlock_pll_phase_setting, VLOCK_PHASE_REG_SIZE);
+ /*disable pll lock*/
+ /*WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 0, 3, 1);*/
+
+ /*enable pll mode and enc mode phase lock*/
+ WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 3, 0, 2);
+
+ /*reset*/
+ WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 1, 2, 1);
+ WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 1, 5, 1);
+ }
+
/* vlock module output goes to which module */
switch (READ_VPP_REG_BITS(VPU_VIU_VENC_MUX_CTRL, 0, 2)) {
case 0:/* ENCL */
else if (vf->source_type == VFRAME_SOURCE_TYPE_HDMI)
/* Input Vsync source select from hdmi-rx */
WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 1, 16, 3);
+
+ /*enable vlock*/
WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 1, 31, 1);
}
void vlock_vmode_check(void)
{
const struct vinfo_s *vinfo;
- unsigned int t0, t1, hiu_reg_addr;
+ unsigned int t0, t1;
if (vlock_en == 0)
return;
- if (get_cpu_type() >= MESON_CPU_MAJOR_ID_GXL)
- hiu_reg_addr = HHI_HDMI_PLL_CNTL1;
- else
- hiu_reg_addr = HHI_HDMI_PLL_CNTL2;
+
vinfo = get_current_vinfo();
vlock_vmode_changed = 0;
if ((vlock_vmode_change_status == VOUT_EVENT_MODE_CHANGE) ||
(pre_hiu_reg_m == 0)) {
if (vlock_mode & (VLOCK_MODE_MANUAL_PLL |
VLOCK_MODE_AUTO_PLL)) {
- amvecm_hiu_reg_read(hiu_reg_addr, &t0);
- amvecm_hiu_reg_read(HHI_HDMI_PLL_CNTL, &t1);
- pre_hiu_reg_frac = t0 & 0xfff;
- pre_hiu_reg_m = t1 & 0x1ff;
+ /*amvecm_hiu_reg_read(hhi_pll_reg_frac, &t0);*/
+ /*amvecm_hiu_reg_read(hhi_pll_reg_m, &t1);*/
+ t0 = vlock_get_panel_pll_m();
+ t1 = vlock_get_panel_pll_frac();
+ if (cpu_after_eq(MESON_CPU_MAJOR_ID_TL1)) {
+ pre_hiu_reg_frac = (t0 >> 5) & 0xfff;
+ pre_hiu_reg_m = t1 & 0xff;
+ } else {
+ pre_hiu_reg_frac = t0 & 0xfff;
+ pre_hiu_reg_m = t1 & 0x1ff;
+ }
}
if ((vlock_mode & (VLOCK_MODE_MANUAL_ENC |
VLOCK_MODE_AUTO_ENC |
VLOCK_MODE_MANUAL_SOFT_ENC))) {
+ #if 0
switch (READ_VPP_REG_BITS(VPU_VIU_VENC_MUX_CTRL,
0, 2)) {
case 0:
ENCL_MAX_LINE_SWITCH_POINT;
break;
}
+ #endif
pre_enc_max_line = READ_VPP_REG(enc_max_line_addr);
pre_enc_max_pixel = READ_VPP_REG(enc_max_pixel_addr);
vlock_capture_limit = ((1 << 12) * vlock_line_limit) /
static void vlock_disable_step1(void)
{
unsigned int m_reg_value, tmp_value, enc_max_line, enc_max_pixel;
- unsigned int hiu_reg_addr;
/* VLOCK_CNTL_EN disable */
vlock_enable(0);
if ((vlock_mode & (VLOCK_MODE_MANUAL_PLL |
VLOCK_MODE_AUTO_PLL |
VLOCK_MODE_MANUAL_SOFT_ENC))) {
- if (get_cpu_type() >= MESON_CPU_MAJOR_ID_GXL)
- hiu_reg_addr = HHI_HDMI_PLL_CNTL1;
- else
- hiu_reg_addr = HHI_HDMI_PLL_CNTL2;
- amvecm_hiu_reg_read(hiu_reg_addr, &tmp_value);
- m_reg_value = tmp_value & 0xfff;
- if (m_reg_value != pre_hiu_reg_frac) {
- tmp_value = (tmp_value & 0xfffff000) |
- (pre_hiu_reg_frac & 0xfff);
- amvecm_hiu_reg_write(hiu_reg_addr, tmp_value);
- }
- amvecm_hiu_reg_read(HHI_HDMI_PLL_CNTL, &tmp_value);
- m_reg_value = tmp_value & 0x1ff;
- if ((m_reg_value != pre_hiu_reg_m) &&
- (pre_hiu_reg_m != 0)) {
- tmp_value = (tmp_value & 0xfffffe00) |
- (pre_hiu_reg_m & 0x1ff);
- amvecm_hiu_reg_write(HHI_HDMI_PLL_CNTL, tmp_value);
+ if (vlock.dtdata->vlk_hwver >= vlock_hw_ver2) {
+ #if 0
+ amvecm_hiu_reg_read(hhi_pll_reg_frac,
+ &tmp_value);
+ m_reg_value = (tmp_value >> 5) & 0xfff;
+ if (m_reg_value != pre_hiu_reg_frac) {
+ tmp_value = (tmp_value & 0xfffff000) |
+ (pre_hiu_reg_frac & 0xfff);
+ amvecm_hiu_reg_write(hhi_pll_reg_frac,
+ tmp_value);
+ pr_info("restore f value=0x%x\n", tmp_value);
+ }
+ amvecm_hiu_reg_read(hhi_pll_reg_m, &tmp_value);
+ m_reg_value = tmp_value & 0xff;
+ if ((m_reg_value != pre_hiu_reg_m) &&
+ (pre_hiu_reg_m != 0)) {
+ tmp_value = (tmp_value & 0xffffff00) |
+ (pre_hiu_reg_m & 0xff);
+ amvecm_hiu_reg_write(hhi_pll_reg_m, tmp_value);
+ pr_info("restore m value=0x%x\n", tmp_value);
+ }
+ #endif
+
+ #if 1
+ /*restore the orginal pll setting*/
+ /*amvecm_hiu_reg_read(hhi_pll_reg_m, &tmp_value);*/
+ tmp_value = vlock_get_panel_pll_m();
+ m_reg_value = tmp_value & 0xff;
+ if (m_reg_value != (vlock.val_m & 0xff))
+ vlock_set_panel_pll_m(vlock.val_m);
+ /*amvecm_hiu_reg_write(hhi_pll_reg_m,*/
+ /* vlock.val_m);*/
+
+ /*amvecm_hiu_reg_read(hhi_pll_reg_frac, &tmp_value);*/
+ tmp_value = vlock_get_panel_pll_frac();
+ m_reg_value = tmp_value & 0x1ffff;
+ if (m_reg_value != (vlock.val_frac & 0xfff))
+ vlock_set_panel_pll_frac(vlock.val_frac);
+ /*amvecm_hiu_reg_write(hhi_pll_reg_frac,*/
+ /* vlock.val_frac);*/
+ pr_info("restore orignal m,f value\n");
+ #endif
+ } else {
+ /*amvecm_hiu_reg_read(hhi_pll_reg_frac, &tmp_value);*/
+ tmp_value = vlock_get_panel_pll_frac();
+ m_reg_value = tmp_value & 0xfff;
+ if (m_reg_value != pre_hiu_reg_frac) {
+ tmp_value = (tmp_value & 0xfffff000) |
+ (pre_hiu_reg_frac & 0xfff);
+ /*amvecm_hiu_reg_write(hhi_pll_reg_frac,*/
+ /* tmp_value);*/
+ vlock_set_panel_pll_frac(tmp_value);
+ }
+ /*amvecm_hiu_reg_read(hhi_pll_reg_m, &tmp_value);*/
+ tmp_value = vlock_get_panel_pll_m();
+ m_reg_value = tmp_value & 0x1ff;
+ if ((m_reg_value != pre_hiu_reg_m) &&
+ (pre_hiu_reg_m != 0)) {
+ tmp_value = (tmp_value & 0xfffffe00) |
+ (pre_hiu_reg_m & 0x1ff);
+ /*amvecm_hiu_reg_write(hhi_pll_reg_m, */
+ /*tmp_value);*/
+ vlock_set_panel_pll_m(tmp_value);
+ }
}
}
if ((vlock_mode & (VLOCK_MODE_MANUAL_ENC |
}
vlock_pll_stable_cnt = 0;
vlock_enc_stable_flag = 0;
+ if (vlock_debug & VLOCK_DEBUG_INFO)
+ pr_info(">>>[%s]\n", __func__);
}
-static void vlock_disable_step2(void)
+static bool vlock_disable_step2(void)
{
unsigned int temp_val;
+ bool ret = false;
+
/* need delay to disable follow regs(vlsi suggest!!!) */
if (vlock_dis_cnt > 0)
vlock_dis_cnt--;
- if (vlock_dis_cnt == 0) {
+ else if (vlock_dis_cnt == 0) {
+ if (vlock.dtdata->vlk_hwver >= vlock_hw_ver2) {
+ amvecm_hiu_reg_write_bits(
+ HHI_HDMI_PLL_VLOCK_CNTL, 0x4, 0, 3);
+ amvecm_hiu_reg_write_bits(
+ HHI_HDMI_PLL_VLOCK_CNTL, 0x0, 0, 3);
+ }
+
/* disable to adjust pll */
WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 0, 29, 1);
/* CFG_VID_LOCK_ADJ_EN disable */
/* disable vid_lock_en */
WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 0, 31, 1);
vlock_state = VLOCK_STATE_DISABLE_STEP2_DONE;
- amvecm_hiu_reg_read(HHI_HDMI_PLL_CNTL6, &temp_val);
- if (is_meson_gxtvbb_cpu() && (((temp_val >> 21) & 0x3) != 0))
- amvecm_hiu_reg_write_bits(HHI_HDMI_PLL_CNTL6, 0, 21, 2);
+ if (is_meson_gxtvbb_cpu()) {
+ amvecm_hiu_reg_read(HHI_HDMI_PLL_CNTL6, &temp_val);
+ if (((temp_val >> 21) & 0x3) != 0)
+ amvecm_hiu_reg_write_bits(HHI_HDMI_PLL_CNTL6,
+ 0, 21, 2);
+ }
+ ret = true;
+
+ if (vlock_debug & VLOCK_DEBUG_INFO)
+ pr_info(">>>[%s]\n", __func__);
}
+
+ return ret;
}
static void vlock_enable_step1(struct vframe_s *vf, struct vinfo_s *vinfo,
unsigned int input_hz, unsigned int output_hz)
vlock_sync_limit_flag = 0;
vlock_vmode_changed = 0;
vlock_dis_cnt = 0;
- vlock_state = VLOCK_STATE_ENABLE_STEP1_DONE;
+ /*vlock_state = VLOCK_STATE_ENABLE_STEP1_DONE;*/
vlock_pll_stable_cnt = 0;
vlock_log_cnt = 0;
vlock_enc_stable_flag = 0;
+
+ if (vlock_debug & VLOCK_DEBUG_INFO)
+ pr_info(">>>[%s]\n", __func__);
}
void vlock_log_start(void)
vlock_reg_get();
vlock_log_cnt++;
}
+ if (vlock_debug & VLOCK_DEBUG_INFO)
+ pr_info(">>>[%s]\n", __func__);
}
static void vlock_enable_step3_soft_enc(void)
vlock_reg_get();
vlock_log_cnt++;
}
+ if (vlock_debug & VLOCK_DEBUG_INFO)
+ pr_info(">>>[%s]\n", __func__);
}
+
/*check pll adj value (0x3020),otherwise may cause blink*/
static void vlock_pll_adj_limit_check(unsigned int *pll_val)
{
}
}
}
+
static void vlock_enable_step3_pll(void)
{
- unsigned int m_reg_value, tmp_value, abs_val, hiu_reg_addr;
+ unsigned int m_reg_value, tmp_value, abs_val;
unsigned int ia, oa, abs_cnt;
-
- if (get_cpu_type() >= MESON_CPU_MAJOR_ID_GXL)
- hiu_reg_addr = HHI_HDMI_PLL_CNTL1;
- else
- hiu_reg_addr = HHI_HDMI_PLL_CNTL2;
+ unsigned int pre_m, new_m, tar_m, org_m;
/*vs_i*/
tmp_value = READ_VPP_REG(VPU_VLOCK_RO_VS_I_DIST);
m_reg_value = READ_VPP_REG(VPU_VLOCK_RO_M_INT_FRAC);
if (vlock_log_en && (vlock_log_cnt < vlock_log_size)) {
+ #if 0
vlock_log[vlock_log_cnt]->pll_frac =
(vlock_pll_val_last & 0xfff) >> 2;
vlock_log[vlock_log_cnt]->pll_m =
(vlock_pll_val_last >> 16) & 0x1ff;
+ #else
+ /*amvecm_hiu_reg_read(hhi_pll_reg_frac, &tmp_value);*/
+ tmp_value = vlock_get_panel_pll_frac();
+ vlock_log[vlock_log_cnt]->pll_frac = tmp_value;
+
+ /*amvecm_hiu_reg_read(hhi_pll_reg_m, &tmp_value);*/
+ tmp_value = vlock_get_panel_pll_m();
+ vlock_log[vlock_log_cnt]->pll_m = tmp_value;
+ #endif
vlock_reg_get();
vlock_log_cnt++;
}
return;
}
/*check adjust delta limit*/
- vlock_pll_adj_limit_check(&m_reg_value);
+ if (vlock.dtdata->vlk_hwver < vlock_hw_ver2)
+ vlock_pll_adj_limit_check(&m_reg_value);
/*vlsi suggest config:don't enable load signal,
*on gxtvbb this load signal will effect SSG,
*which may result in flashes black
*/
- amvecm_hiu_reg_read(HHI_HDMI_PLL_CNTL6, &tmp_value);
- if (is_meson_gxtvbb_cpu() && (((tmp_value >> 21) & 0x3) != 2))
- amvecm_hiu_reg_write_bits(HHI_HDMI_PLL_CNTL6, 2, 21, 2);
- /*add delta count check*/
- /*for interlace input need div 2*/
- if (vlock_intput_type)
+ if (is_meson_gxtvbb_cpu()) {
+ amvecm_hiu_reg_read(HHI_HDMI_PLL_CNTL6, &tmp_value);
+ if (((tmp_value >> 21) & 0x3) != 2)
+ amvecm_hiu_reg_write_bits(HHI_HDMI_PLL_CNTL6, 2, 21, 2);
+ }
+
+ /* add delta count check
+ *for interlace input need div 2
+ *0:progressive type
+ *1:interlace type
+ */
+ if (vlock_intput_type &&
+ (vlock.dtdata->vlk_hwver < vlock_hw_ver2))
ia = READ_VPP_REG(VPU_VLOCK_RO_VS_I_DIST) / 2;
else
ia = READ_VPP_REG(VPU_VLOCK_RO_VS_I_DIST);
return;
}
/*frac*/
- amvecm_hiu_reg_read(hiu_reg_addr, &tmp_value);
- abs_val = abs(((m_reg_value & 0xfff) >> 2) - (tmp_value & 0xfff));
- if ((abs_val >= vlock_log_delta_frac) && (vlock_log_delta_en&(1<<3)))
- pr_info("vlock frac delta:%d(0x%x,0x%x)\n",
- abs_val, ((m_reg_value & 0xfff) >> 2),
+ /*amvecm_hiu_reg_read(hhi_pll_reg_frac, &tmp_value);*/
+ tmp_value = vlock_get_panel_pll_frac();
+ if (vlock.dtdata->vlk_hwver < vlock_hw_ver2) {
+ abs_val = abs(((m_reg_value & 0xfff) >> 2) -
(tmp_value & 0xfff));
- if ((abs_val >= vlock_delta_limit) &&
- (abs_cnt > vlock_delta_cnt_limit)) {
- tmp_value = (tmp_value & 0xfffff000) |
- ((m_reg_value & 0xfff) >> 2);
- amvecm_hiu_reg_write(hiu_reg_addr, tmp_value);
- vlock_pll_val_last &= 0xffff0000;
- vlock_pll_val_last |= (m_reg_value & 0xfff);
+ if ((abs_val >= vlock_log_delta_frac) &&
+ (vlock_log_delta_en&(1<<3)))
+ pr_info("vlock frac delta:%d(0x%x,0x%x)\n",
+ abs_val, ((m_reg_value & 0xfff) >> 2),
+ (tmp_value & 0xfff));
+ if ((abs_val >= vlock_delta_limit) &&
+ (abs_cnt > vlock_delta_cnt_limit)) {
+ tmp_value = (tmp_value & 0xfffff000) |
+ ((m_reg_value & 0xfff) >> 2);
+ /*amvecm_hiu_reg_write(hhi_pll_reg_frac, tmp_value);*/
+ vlock_set_panel_pll_frac(tmp_value);
+ vlock_pll_val_last &= 0xffff0000;
+ vlock_pll_val_last |= (m_reg_value & 0xfff);
+ }
+ /*check stable by diff frac*/
+ if ((abs_val < (2 * vlock_delta_limit)) &&
+ (abs_cnt < vlock_enc_adj_limit))
+ vlock_pll_stable_cnt++;
+ else
+ vlock_pll_stable_cnt = 0;
+ } else {
+ abs_val = abs((tmp_value & 0x1ffff) -
+ ((m_reg_value & 0xfff) << 5));
+
+ if (abs_val > (50 << 5))
+ tmp_value = ((tmp_value & 0xfffe0000) |
+ (((tmp_value & 0x1ffff) +
+ ((m_reg_value & 0xfff) << 5)) >> 1));
+ else
+ tmp_value = (tmp_value & 0xfffe0000) |
+ ((m_reg_value & 0xfff) << 5);
+
+ /*16:0*/
+ /*amvecm_hiu_reg_write(hhi_pll_reg_frac, tmp_value);*/
+ vlock_set_panel_pll_frac(tmp_value);
}
- /*check stable by diff frac*/
- if ((abs_val < (2 * vlock_delta_limit)) &&
- (abs_cnt < vlock_enc_adj_limit))
- vlock_pll_stable_cnt++;
- else
- vlock_pll_stable_cnt = 0;
+
/*m*/
- amvecm_hiu_reg_read(HHI_HDMI_PLL_CNTL, &tmp_value);
- abs_val = abs(((m_reg_value >> 16) & 0x1ff) - (pre_hiu_reg_m & 0x1ff));
- if ((abs_val > vlock_log_delta_m) && (vlock_log_delta_en&(1<<4)))
- pr_info("vlock m delta:%d(0x%x,0x%x)\n",
- abs_val, ((m_reg_value >> 16) & 0x1ff),
- (tmp_value & 0x1ff));
- if ((abs_val <= vlock_pll_m_limit) &&
- (((m_reg_value >> 16) & 0x1ff) != (tmp_value & 0x1ff)) &&
- (abs_cnt > vlock_delta_cnt_limit)) {
- tmp_value = (tmp_value & 0xfffffe00) |
- ((m_reg_value >> 16) & 0x1ff);
- amvecm_hiu_reg_write(HHI_HDMI_PLL_CNTL, tmp_value);
- vlock_pll_val_last &= 0x0000ffff;
- vlock_pll_val_last |= (m_reg_value & 0xffff0000);
+ /*amvecm_hiu_reg_read(hhi_pll_reg_m, &tmp_value);*/
+ tmp_value = vlock_get_panel_pll_m();
+ if (vlock.dtdata->vlk_hwver < vlock_hw_ver2) {
+ abs_val = abs(((m_reg_value >> 16) & 0xff) -
+ (pre_hiu_reg_m & 0xff));
+ if ((abs_val > vlock_log_delta_m) &&
+ (vlock_log_delta_en&(1<<4)))
+ pr_info("vlock m delta:%d(0x%x,0x%x)\n",
+ abs_val, ((m_reg_value >> 16) & 0x1ff),
+ (tmp_value & 0x1ff));
+ if ((abs_val <= vlock_pll_m_limit) &&
+ (((m_reg_value >> 16) & 0x1ff) !=
+ (tmp_value & 0x1ff)) &&
+ (abs_cnt > vlock_delta_cnt_limit)) {
+ tmp_value = (tmp_value & 0xfffffe00) |
+ ((m_reg_value >> 16) & 0x1ff);
+ /*amvecm_hiu_reg_write(hhi_pll_reg_m, tmp_value);*/
+ vlock_set_panel_pll_m(tmp_value);
+ vlock_pll_val_last &= 0x0000ffff;
+ vlock_pll_val_last |= (m_reg_value & 0xffff0000);
+ }
+ } else {
+ pre_m = (tmp_value & 0xff);
+ new_m = ((m_reg_value >> 16) & 0x1ff);
+ org_m = (vlock.val_m & 0xff);
+ if (pre_m != new_m) {
+ if (vlock_debug & VLOCK_DEBUG_INFO)
+ pr_info("vlock m chg: pre=0x%x, report=0x%x\n",
+ pre_m, new_m);
+
+ if (new_m > pre_m) {
+ tar_m = ((pre_m + 1) <
+ (org_m + 1))?(pre_m + 1):(org_m + 1);
+ } else {
+ /*tar_m < pre_m*/
+ tar_m = ((pre_m - 1) <
+ (org_m - 1))?(org_m - 1):(pre_m - 1);
+ }
+ tmp_value = (tmp_value & 0xffffff00) + tar_m;
+ /*amvecm_hiu_reg_write(hhi_pll_reg_m, tmp_value);*/
+ vlock_set_panel_pll_m(tmp_value);
+ }
}
+
/*check stable by diff m*/
- if (((m_reg_value >> 16) & 0x1ff) != (tmp_value & 0x1ff))
- vlock_pll_stable_cnt = 0;
+ if (vlock.dtdata->vlk_hwver >= vlock_hw_ver2) {
+ if (((m_reg_value >> 16) & 0xff) != (tmp_value & 0xff))
+ vlock_pll_stable_cnt = 0;
+ } else {
+ if (((m_reg_value >> 16) & 0x1ff) != (tmp_value & 0x1ff))
+ vlock_pll_stable_cnt = 0;
+ }
}
/* won't change this function internal seqence,
* if really need change,please be carefull and check with vlsi
}
vinfo = get_current_vinfo();
input_hz = vlock_check_input_hz(vf);
- output_hz = vlock_check_output_hz(vinfo->sync_duration_num);
+ output_hz = vlock_check_output_hz(vinfo->sync_duration_num,
+ vinfo->sync_duration_den);
vlock_dis_cnt_no_vf = 0;
if (vecm_latch_flag & FLAG_VLOCK_EN) {
vlock_enable_step1(vf, vinfo, input_hz, output_hz);
+ vlock_state = VLOCK_STATE_ENABLE_STEP1_DONE;
vlock_en = 1;
vecm_latch_flag &= ~FLAG_VLOCK_EN;
}
(input_hz != pre_input_freq) ||
(output_hz != pre_output_freq) ||
vlock_vmode_changed ||
- (vlock_state == VLOCK_STATE_ENABLE_FORCE_RESET))
+ (vlock_state == VLOCK_STATE_ENABLE_FORCE_RESET)) {
vlock_enable_step1(vf, vinfo, input_hz, output_hz);
+ vlock_state = VLOCK_STATE_ENABLE_STEP1_DONE;
+ }
if ((vlock_sync_limit_flag < 10) &&
(vlock_state >= VLOCK_STATE_ENABLE_STEP1_DONE)) {
vlock_sync_limit_flag++;
if ((vlock_sync_limit_flag <= 3) &&
((vlock_mode & (VLOCK_MODE_MANUAL_ENC |
VLOCK_MODE_MANUAL_PLL)))) {
+ /*reset*/
WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 1, 5, 1);
WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 1, 2, 1);
+ /*clear first 3 frame internal cnt*/
WRITE_VPP_REG(VPU_VLOCK_OVWRITE_ACCUM0, 0);
WRITE_VPP_REG(VPU_VLOCK_OVWRITE_ACCUM1, 0);
+ if (vlock_debug & VLOCK_DEBUG_INFO)
+ pr_info("amve_vlock_process-0\n");
}
if ((vlock_sync_limit_flag == 4) &&
((vlock_mode & (VLOCK_MODE_MANUAL_ENC |
VLOCK_MODE_MANUAL_PLL)))) {
+ /*release reset*/
WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 0, 5, 1);
WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 0, 2, 1);
+ if (vlock_debug & VLOCK_DEBUG_INFO)
+ pr_info("amve_vlock_process-1\n");
}
}
+
if ((vlock_sync_limit_flag == 5) &&
(vlock_state == VLOCK_STATE_ENABLE_STEP1_DONE)) {
/*input_vs_cnt =*/
/*READ_VPP_REG_BITS(VPU_VLOCK_RO_VS_I_DIST,*/
/* 0, 28);*/
input_vs_cnt = XTAL_VLOCK_CLOCK/input_hz;
- if (vf->type_original & VIDTYPE_TYPEMASK)
+ /*tl1 not need */
+ if (!cpu_after_eq(MESON_CPU_MAJOR_ID_TL1) &&
+ vf->type_original & VIDTYPE_TYPEMASK)
input_vs_cnt = input_vs_cnt << 1;
+
WRITE_VPP_REG(VPU_VLOCK_LOOP1_IMISSYNC_MAX,
input_vs_cnt*125/100);
WRITE_VPP_REG(VPU_VLOCK_LOOP1_IMISSYNC_MIN,
input_vs_cnt*70/100);
+
/*cal accum1 value*/
WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 0, 2, 1);
/*cal accum0 value*/
- WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 0, 5, 1);
+ //WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 0, 5, 1);
vlock_state = VLOCK_STATE_ENABLE_STEP2_DONE;
+
+ /*
+ * tl1 auto pll,swich clk need after
+ *several frames
+ */
+ if (vlock.dtdata->vlk_hwver >= vlock_hw_ver2) {
+ if (IS_AUTO_MODE(vlock_mode))
+ amvecm_hiu_reg_write_bits(
+ HHI_HDMI_PLL_VLOCK_CNTL, 0x7, 0, 3);
+ else if (IS_MANUAL_MODE(vlock_mode))
+ amvecm_hiu_reg_write_bits(
+ HHI_HDMI_PLL_VLOCK_CNTL, 0x6, 0, 3);
+ }
+
+ if (vlock_debug & VLOCK_DEBUG_INFO)
+ pr_info("amve_vlock_process-2\n");
} else if (vlock_dynamic_adjust &&
(vlock_sync_limit_flag > 5) &&
(vlock_state == VLOCK_STATE_ENABLE_STEP2_DONE) &&
}
}
+void vlock_clear_frame_counter(void)
+{
+ vlock.frame_cnt_in = 0;
+ vlock.frame_cnt_no = 0;
+ vlock_log_cnt = 0;
+}
+
+void vlock_set_en(bool en)
+{
+ /*if (vlock.dtdata->vlk_support)*/
+ vlock_en = en;
+}
+
+void vlock_status_init(void)
+{
+ /*config vlock mode*/
+ /*todo:txlx & g9tv support auto pll,*/
+ /*but support not good,need vlsi support optimize*/
+ vlock_mode = VLOCK_MODE_MANUAL_PLL;
+ if (is_meson_gxtvbb_cpu() ||
+ is_meson_txl_cpu() || is_meson_txlx_cpu()
+ || is_meson_tl1_cpu())
+ vlock_en = 1;
+ else
+ vlock_en = 0;
+
+ /*initial pll register address*/
+ if (is_meson_tl1_cpu()) {
+ hhi_pll_reg_m = HHI_TCON_PLL_CNTL0;
+ hhi_pll_reg_frac = HHI_TCON_PLL_CNTL1;
+ /*hhi_pll_reg_vlock_ctl = HHI_HDMI_PLL_VLOCK_CNTL;*/
+ } else if (get_cpu_type() >=
+ MESON_CPU_MAJOR_ID_GXL) {
+ hhi_pll_reg_m = HHI_HDMI_PLL_CNTL;
+ hhi_pll_reg_frac = HHI_HDMI_PLL_CNTL2;
+ } else {
+ hhi_pll_reg_m = HHI_HDMI_PLL_CNTL;
+ hhi_pll_reg_frac = HHI_HDMI_PLL_CNTL2;
+ }
+
+ /*initial enc register address*/
+ switch (READ_VPP_REG_BITS(VPU_VIU_VENC_MUX_CTRL,
+ 0, 2)) {
+ case 0:
+ enc_max_line_addr = ENCL_VIDEO_MAX_LNCNT;
+ enc_max_pixel_addr = ENCL_VIDEO_MAX_PXCNT;
+ enc_video_mode_addr = ENCL_VIDEO_MODE;
+ enc_video_mode_adv_addr = ENCL_VIDEO_MODE_ADV;
+ enc_max_line_switch_addr =
+ ENCL_MAX_LINE_SWITCH_POINT;
+ break;
+#if 0 /*enc mode not adapt to ENCP and ENCT*/
+ case 2:
+ enc_max_line_addr = ENCP_VIDEO_MAX_LNCNT;
+ enc_max_pixel_addr = ENCP_VIDEO_MAX_PXCNT;
+ enc_video_mode_addr = ENCP_VIDEO_MODE;
+ enc_max_line_switch_addr =
+ ENCP_MAX_LINE_SWITCH_POINT;
+ break;
+ case 3:
+ enc_max_line_addr = ENCT_VIDEO_MAX_LNCNT;
+ enc_max_pixel_addr = ENCT_VIDEO_MAX_PXCNT;
+ enc_video_mode_addr = ENCT_VIDEO_MODE;
+ enc_max_line_switch_addr =
+ ENCT_MAX_LINE_SWITCH_POINT;
+ break;
+#endif
+ default:
+ enc_max_line_addr = ENCL_VIDEO_MAX_LNCNT;
+ enc_max_pixel_addr = ENCL_VIDEO_MAX_PXCNT;
+ enc_video_mode_addr = ENCL_VIDEO_MODE;
+ enc_video_mode_adv_addr = ENCL_VIDEO_MODE_ADV;
+ enc_max_line_switch_addr =
+ ENCL_MAX_LINE_SWITCH_POINT;
+ break;
+ }
+
+ /*back up orignal pll value*/
+ vlock.val_m = vlock_get_panel_pll_m();
+ vlock.val_frac = vlock_get_panel_pll_frac();
+
+ vlock.fsm_sts = VLOCK_STATE_NULL;
+ vlock.fsm_prests = VLOCK_STATE_NULL;
+ vlock.vf_sts = false;
+ vlock.vmd_chg = false;
+ vlock.md_support = false;
+ /* vlock.phlock_percent = phlock_percent; */
+ vlock_clear_frame_counter();
+
+
+ pr_info("%s vlock_en:%d\n", __func__, vlock_en);
+}
+
+void vlock_dt_match_init(struct vecm_match_data_s *pdata)
+{
+ vlock.dtdata = pdata;
+ /*vlock_en = vlock.dtdata.vlk_support;*/
+ pr_info("vlock dt support: %d\n", vlock.dtdata->vlk_support);
+ pr_info("vlock dt new_fsm: %d\n", vlock.dtdata->vlk_new_fsm);
+ pr_info("vlock dt hwver: %d\n", vlock.dtdata->vlk_hwver);
+ pr_info("vlock dt phlock_en: %d\n", vlock.dtdata->vlk_phlock_en);
+}
+
+void vlock_set_phase(u32 percent)
+{
+ u32 vs_i_val = READ_VPP_REG(VPU_VLOCK_RO_VS_I_DIST);
+ /*u32 vs_o_val = READ_VPP_REG(VPU_VLOCK_RO_VS_O_DIST);*/
+ u32 data = 0;
+
+ if (!vlock.dtdata->vlk_phlock_en)
+ return;
+
+ if (percent > 100) {
+ pr_info("percent val err:%d\n", percent);
+ return;
+ }
+
+ vlock.phlock_percent = percent;
+ data = (vs_i_val * (100 + vlock.phlock_percent))/200;
+ WRITE_VPP_REG(VPU_VLOCK_LOOP1_PHSDIF_TGT, data);
+ pr_info("LOOP1_PHSDIF_TGT:0x%x\n", data);
+
+ /*reset*/
+ data = READ_VPP_REG(VPU_VLOCK_CTRL);
+ data |= 1 << 2;
+ data |= 1 << 5;
+ WRITE_VPP_REG(VPU_VLOCK_CTRL, data);
+ data &= ~(1 << 2);
+ data &= ~(1 << 5);
+ WRITE_VPP_REG(VPU_VLOCK_CTRL, data);
+}
+
+void vlock_set_phase_en(u32 en)
+{
+ if (en)
+ vlock.dtdata->vlk_phlock_en = true;
+ else
+ vlock.dtdata->vlk_phlock_en = false;
+ pr_info("vlock phlock_en=%d\n", en);
+}
+
+void vlock_phaselock_check(struct stvlock_sig_sts *pvlock,
+ struct vframe_s *vf)
+{
+ /*vs_i*/
+ u32 ia = READ_VPP_REG(VPU_VLOCK_RO_VS_I_DIST);
+ u32 val;
+ static u32 cnt = 48;
+
+ if (vlock.dtdata->vlk_phlock_en) {
+ if (cnt++ > 50) {
+ ia = READ_VPP_REG(VPU_VLOCK_RO_VS_I_DIST);
+ val = (ia * (100 + vlock.phlock_percent))/200;
+ WRITE_VPP_REG(VPU_VLOCK_LOOP1_PHSDIF_TGT, val);
+ cnt = 0;
+ #if 0
+ /*reset*/
+ WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 1, 2, 1);
+ WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 1, 5, 1);
+ WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 0, 2, 1);
+ WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 0, 5, 1);
+ #endif
+ }
+ }
+}
+
+bool vlock_get_phlock_flag(void)
+{
+ u32 flag;
+ u32 sts;
+
+ if (!vlock.dtdata->vlk_phlock_en)
+ return false;
+
+ flag = READ_VPP_REG(VPU_VLOCK_RO_LCK_FRM) >> 17;
+ flag = flag&0x01;
+
+ if (vlock.dtdata->vlk_new_fsm)
+ sts = vlock.fsm_sts;
+ else
+ sts = vlock_state;
+
+ if (flag && (sts == VLOCK_STATE_ENABLE_STEP2_DONE))
+ return true;
+ else
+ return false;
+}
+
+bool vlock_get_vlock_flag(void)
+{
+ u32 flag;
+ u32 sts;
+
+ flag = READ_VPP_REG(VPU_VLOCK_RO_LCK_FRM) >> 16;
+ flag = flag&0x01;
+
+ if (vlock.dtdata->vlk_new_fsm)
+ sts = vlock.fsm_sts;
+ else
+ sts = vlock_state;
+
+ if (flag && (sts == VLOCK_STATE_ENABLE_STEP2_DONE))
+ return true;
+ else
+ return false;
+}
+
+void vlock_enc_timing_monitor(void)
+{
+ static unsigned int pre_line, pre_pixel;
+ unsigned int cur_line, cur_pixel;
+ unsigned int val;
+
+ val = READ_VPP_REG(VPU_VLOCK_RO_LINE_PIX_ADJ);
+ cur_pixel = (val & 0x0000ffff);
+ cur_line = (val >> 16) & 0x0000ffff;
+
+ if ((cur_line != pre_line) || (cur_pixel != pre_pixel)) {
+ pr_info("vlock line=0x%x pixel=0x%x\n",
+ cur_line, cur_pixel);
+ pre_line = cur_line;
+ pre_pixel = cur_pixel;
+ }
+}
+
+#if 1
+
+u32 vlock_fsm_check_support(struct stvlock_sig_sts *pvlock,
+ struct vframe_s *vf)
+{
+ u32 ret = true;
+
+ if (((pvlock->input_hz != pvlock->output_hz) && (vlock_adapt == 0)) ||
+ (pvlock->input_hz == 0) || (pvlock->output_hz == 0) ||
+ (((vf->type_original & VIDTYPE_TYPEMASK)
+ != VIDTYPE_PROGRESSIVE) &&
+ is_meson_txlx_package_962E())) {
+
+ if (vlock_debug & VLOCK_DEBUG_INFO) {
+ pr_info("[%s] for no support case!!!\n",
+ __func__);
+ pr_info("input_hz:%d, output_hz:%d\n",
+ pvlock->input_hz, pvlock->output_hz);
+ pr_info("type_original:0x%x\n", vf->type_original);
+ }
+ ret = false;
+ }
+
+ if (vlock_vmode_change_status == VOUT_EVENT_MODE_CHANGE_PRE) {
+ if (vlock_debug & VLOCK_DEBUG_INFO)
+ pr_info("[%s] for vmode change pre case!!!\n",
+ __func__);
+ ret = false;
+ }
+
+ return ret;
+}
+
+u32 vlock_fsm_input_check(struct stvlock_sig_sts *vlock, struct vframe_s *vf)
+{
+ u32 ret = 0;
+ u32 vframe_sts;
+ struct vinfo_s *vinfo = NULL;
+
+ if (vf == NULL)
+ vframe_sts = false;
+ else
+ vframe_sts = true;
+
+ vlock_vmode_check();
+
+ if (vf != NULL) {
+ vinfo = get_current_vinfo();
+ vlock->input_hz = vlock_check_input_hz(vf);
+ vlock->output_hz = vlock_check_output_hz(
+ vinfo->sync_duration_num, vinfo->sync_duration_den);
+ }
+
+ /*check vf exist status*/
+ if (vlock->vf_sts != vframe_sts) {
+ vlock->vf_sts = vframe_sts;
+ if (vlock_debug & VLOCK_DEBUG_INFO)
+ pr_info("vlock vfsts chg %d\n", vframe_sts);
+ ret = 1;
+ } else if (vlock_vmode_change_status) {
+ /*check video mode status*/
+ vlock->vmd_chg = true;
+ ret = 1;
+ if (vlock_debug & VLOCK_DEBUG_INFO)
+ pr_info("vlock vmode chg\n");
+ }
+
+ if (vlock->vf_sts)
+ vlock->md_support = vlock_fsm_check_support(vlock, vf);
+
+ return ret;
+}
+
+u32 vlock_fsm_to_en_func(struct stvlock_sig_sts *pvlock,
+ struct vframe_s *vf)
+{
+ u32 ret = 0;
+ struct vinfo_s *vinfo;
+
+ if ((vf->source_type != pre_source_type) ||
+ (vf->source_mode != pre_source_mode) ||
+ (pvlock->input_hz != pre_input_freq) ||
+ (pvlock->output_hz != pre_output_freq) ||
+ vlock_vmode_changed ||
+ (pvlock->fsm_sts ==
+ VLOCK_STATE_ENABLE_FORCE_RESET)) {
+
+ /*back up orignal pll value*/
+ /*amvecm_hiu_reg_read(hhi_pll_reg_m, &vlock.val_m);*/
+ /*amvecm_hiu_reg_read(hhi_pll_reg_frac, &vlock.val_frac);*/
+ vlock.val_m = vlock_get_panel_pll_m();
+ vlock.val_frac = vlock_get_panel_pll_frac();
+ if (vlock_debug & VLOCK_DEBUG_INFO) {
+ pr_info("HIU pll m[0x%x]=0x%x\n",
+ hhi_pll_reg_m, vlock.val_m);
+ pr_info("HIU pll f[0x%x]=0x%x\n",
+ hhi_pll_reg_frac, vlock.val_frac);
+ }
+ vinfo = get_current_vinfo();
+ vlock_enable_step1(vf, vinfo,
+ pvlock->input_hz, pvlock->output_hz);
+ ret = 1;
+ }
+
+ return ret;
+}
+
+u32 vlock_fsm_en_step1_func(struct stvlock_sig_sts *pvlock,
+ struct vframe_s *vf)
+{
+ u32 ret = 0;
+ u32 input_vs_cnt;
+
+ if ((pvlock->frame_cnt_in <= 3) &&
+ ((vlock_mode & (VLOCK_MODE_MANUAL_ENC |
+ VLOCK_MODE_MANUAL_PLL)))) {
+ WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 1, 5, 1);
+ WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 1, 2, 1);
+ /*clear first 3 frame internal cnt*/
+ WRITE_VPP_REG(VPU_VLOCK_OVWRITE_ACCUM0, 0);
+ WRITE_VPP_REG(VPU_VLOCK_OVWRITE_ACCUM1, 0);
+ if (vlock_debug & VLOCK_DEBUG_INFO)
+ pr_info("%s -0\n", __func__);
+ } else if ((pvlock->frame_cnt_in == 4) &&
+ ((vlock_mode & (VLOCK_MODE_MANUAL_ENC |
+ VLOCK_MODE_MANUAL_PLL)))) {
+ /*cal accum0 value*/
+ WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 0, 5, 1);
+ /*cal accum1 value*/
+ WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 0, 2, 1);
+ if (vlock_debug & VLOCK_DEBUG_INFO)
+ pr_info("%s -1\n", __func__);
+ } else if (pvlock->frame_cnt_in == 5) {
+ /*input_vs_cnt =*/
+ /*READ_VPP_REG_BITS(VPU_VLOCK_RO_VS_I_DIST,*/
+ /* 0, 28);*/
+ input_vs_cnt = XTAL_VLOCK_CLOCK/pvlock->input_hz;
+ /*tl1 not need */
+ if (!cpu_after_eq(MESON_CPU_MAJOR_ID_TL1) &&
+ vf->type_original & VIDTYPE_TYPEMASK)
+ input_vs_cnt = input_vs_cnt << 1;
+
+ WRITE_VPP_REG(VPU_VLOCK_LOOP1_IMISSYNC_MAX,
+ input_vs_cnt*125/100);
+ WRITE_VPP_REG(VPU_VLOCK_LOOP1_IMISSYNC_MIN,
+ input_vs_cnt*70/100);
+
+ /*cal accum1 value*/
+ WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 0, 2, 1);
+ /*cal accum0 value*/
+ WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 0, 5, 1);
+
+ /*
+ * tl1 auto pll,swich clk need after
+ *several frames
+ */
+ if (vlock.dtdata->vlk_hwver >= vlock_hw_ver2) {
+ if (IS_AUTO_MODE(vlock_mode))
+ amvecm_hiu_reg_write_bits(
+ HHI_HDMI_PLL_VLOCK_CNTL, 0x7, 0, 3);
+ else if (IS_MANUAL_MODE(vlock_mode))
+ amvecm_hiu_reg_write_bits(
+ HHI_HDMI_PLL_VLOCK_CNTL, 0x6, 0, 3);
+ }
+
+ ret = 1;
+ if (vlock_debug & VLOCK_DEBUG_INFO)
+ pr_info("%s -2\n", __func__);
+ }
+
+ return ret;
+}
+
+u32 vlock_fsm_en_step2_func(struct stvlock_sig_sts *pvlock,
+ struct vframe_s *vf)
+{
+ u32 ret = 0;
+
+ if (vlock_dynamic_adjust &&
+ (cpu_after_eq(MESON_CPU_MAJOR_ID_GXTVBB)) &&
+ (IS_MANUAL_MODE(vlock_mode))) {
+ if (IS_MANUAL_ENC_MODE(vlock_mode))
+ vlock_enable_step3_enc();
+ else if (IS_MANUAL_PLL_MODE(vlock_mode))
+ vlock_enable_step3_pll();
+ else if (IS_MANUAL_SOFTENC_MODE(vlock_mode))
+ vlock_enable_step3_soft_enc();
+ }
+
+ if (IS_ENC_MODE(vlock_mode))
+ vlock_enc_timing_monitor();
+
+ /*check phase*/
+ vlock_phaselock_check(pvlock, vf);
+ return ret;
+}
+
+
+void vlock_fsm_monitor(struct vframe_s *vf)
+{
+ u32 changed;
+
+ changed = vlock_fsm_input_check(&vlock, vf);
+ switch (vlock.fsm_sts) {
+ case VLOCK_STATE_NULL:
+ if (vlock.vf_sts) {
+ /*have frame in*/
+ if (vlock.frame_cnt_in++ >= 20) {
+ /*vframe input valid*/
+ if (vlock.md_support) {
+ if (vlock_fsm_to_en_func(&vlock, vf)) {
+ vlock_clear_frame_counter();
+ vlock.fsm_sts =
+ VLOCK_STATE_ENABLE_STEP1_DONE;
+ } else {
+ /*error waitting here*/
+ vlock_clear_frame_counter();
+ }
+ }
+ }
+ } else if (vlock.vmd_chg) {
+ vlock_clear_frame_counter();
+ vlock.vmd_chg = false;
+ vlock.fsm_sts = VLOCK_STATE_DISABLE_STEP2_DONE;
+ } else {
+ /*disabled and waitting here*/
+ vlock_clear_frame_counter();
+ }
+ break;
+
+ case VLOCK_STATE_ENABLE_STEP1_DONE:
+ if (vlock.vf_sts) {
+ vlock.frame_cnt_in++;
+ if (vlock_fsm_en_step1_func(&vlock, vf))
+ vlock.fsm_sts = VLOCK_STATE_ENABLE_STEP2_DONE;
+ } else if (vlock.vmd_chg) {
+ vlock_clear_frame_counter();
+ vlock.vmd_chg = false;
+ vlock.fsm_sts = VLOCK_STATE_DISABLE_STEP1_DONE;
+ } else {
+ vlock.frame_cnt_in = 0;
+ if (vlock.frame_cnt_no++ > vlock_dis_cnt_no_vf_limit) {
+ /*go to disable state*/
+ vlock_clear_frame_counter();
+ vlock.fsm_sts = VLOCK_STATE_DISABLE_STEP1_DONE;
+ }
+ }
+ break;
+
+ case VLOCK_STATE_ENABLE_STEP2_DONE:
+ if (vlock.vf_sts) {
+ if (!vlock.md_support) {
+ /*function not support*/
+ vlock_clear_frame_counter();
+ vlock.fsm_sts = VLOCK_STATE_DISABLE_STEP1_DONE;
+ } else if (vecm_latch_flag & FLAG_VLOCK_DIS) {
+ /*disable vlock by vecm cmd*/
+ vlock_disable_step1();
+ vlock_disable_step2();
+ vlock_en = 0;
+ vecm_latch_flag &= ~FLAG_VLOCK_DIS;
+ if (vlock_debug & VLOCK_DEBUG_INFO)
+ pr_info("[%s] vlock dis\n", __func__);
+ vlock_clear_frame_counter();
+ vlock.fsm_sts = VLOCK_STATE_NULL;
+ } else {
+ /*normal mode*/
+ vlock.frame_cnt_no = 0;
+ vlock_fsm_en_step2_func(&vlock, vf);
+ }
+ } else if (vlock.vmd_chg) {
+ vlock_clear_frame_counter();
+ vlock.vmd_chg = false;
+ vlock.fsm_sts = VLOCK_STATE_DISABLE_STEP1_DONE;
+ } else {
+ /*no frame input*/
+ if (vlock.frame_cnt_no++ > vlock_dis_cnt_no_vf_limit) {
+ /*go to disable state*/
+ vlock_clear_frame_counter();
+ vlock.fsm_sts = VLOCK_STATE_DISABLE_STEP1_DONE;
+ }
+ }
+ break;
+
+ case VLOCK_STATE_DISABLE_STEP1_DONE:
+ vlock_disable_step1();
+ if (vlock_disable_step2())
+ vlock.fsm_sts = VLOCK_STATE_NULL;
+ else
+ vlock.fsm_sts = VLOCK_STATE_DISABLE_STEP2_DONE;
+ break;
+
+ case VLOCK_STATE_DISABLE_STEP2_DONE:
+ if (vlock_disable_step2())
+ vlock.fsm_sts = VLOCK_STATE_NULL;
+ break;
+
+ default:
+ pr_info("err state %d\n", vlock.fsm_sts);
+ break;
+ }
+
+ /*capture log*/
+ if (((vlock_mode & (VLOCK_MODE_AUTO_PLL |
+ VLOCK_MODE_AUTO_ENC))) &&
+ vlock_log_en && (vlock_log_cnt < vlock_log_size) &&
+ (vlock_debug & VLOCK_DEBUG_AUTO_MODE_LOG_EN)) {
+ vlock_reg_get();
+ vlock_log_cnt++;
+ }
+
+ if ((vlock_debug & VLOCK_DEBUG_INFO) &&
+ vlock.fsm_sts != vlock.fsm_prests) {
+ pr_info(">>> %s fsm %d to %d\n", __func__,
+ vlock.fsm_prests, vlock.fsm_sts);
+ vlock.fsm_prests = vlock.fsm_sts;
+ }
+}
+#endif
+
/*new packed separeted from amvecm_on_vs,avoid the influencec of repeate call,
*which may affect vlock process
*/
void vlock_process(struct vframe_s *vf)
{
- if (probe_ok == 0)
+ if (probe_ok == 0 || !vlock_en)
+ return;
+
+ if (vlock_debug & VLOCK_DEBUG_FSM_DIS)
return;
/* todo:vlock processs only for tv chip */
- if (is_meson_gxtvbb_cpu() ||
- is_meson_txl_cpu() || is_meson_txlx_cpu()
- || is_meson_txhd_cpu()) {
+ if (vlock.dtdata->vlk_new_fsm)
+ vlock_fsm_monitor(vf);
+ else {
if (vf != NULL)
amve_vlock_process(vf);
else
}
void vlock_status(void)
{
+ struct vinfo_s *vinfo;
+
pr_info("\n current vlock parameters status:\n");
+ pr_info("vlock driver version : %s\n", VLOCK_VER);
pr_info("vlock_mode:%d\n", vlock_mode);
pr_info("vlock_en:%d\n", vlock_en);
pr_info("vlock_adapt:%d\n", vlock_adapt);
pr_info("vlock_debug:0x%x\n", vlock_debug);
pr_info("vlock_dynamic_adjust:%d\n", vlock_dynamic_adjust);
pr_info("vlock_state:%d\n", vlock_state);
+ pr_info("vecm_latch_flag:0x%x\n", vecm_latch_flag);
pr_info("vlock_sync_limit_flag:%d\n", vlock_sync_limit_flag);
pr_info("pre_hiu_reg_m:0x%x\n", pre_hiu_reg_m);
pr_info("pre_hiu_reg_frac:0x%x\n", pre_hiu_reg_frac);
pr_info("vlock_intput_type:%d\n", vlock_intput_type);
pr_info("vlock_pll_adj_limit:%d\n", vlock_pll_adj_limit);
pr_info("vlock_pll_val_last:%d\n", vlock_pll_val_last);
- pr_info("vlock driver version : %s\n", VLOCK_VER);
+ pr_info("vlk_fsm_sts:%d(2 is working)\n", vlock.fsm_sts);
+ pr_info("vlk_support:%d\n", vlock.dtdata->vlk_support);
+ pr_info("vlk_new_fsm:%d\n", vlock.dtdata->vlk_new_fsm);
+ pr_info("vlk_phlock_en:%d\n", vlock.dtdata->vlk_phlock_en);
+ pr_info("vlk_hwver:%d\n", vlock.dtdata->vlk_hwver);
+ pr_info("phlock flag:%d\n", vlock_get_phlock_flag());
+ pr_info("vlock flag:%d\n", vlock_get_vlock_flag());
+ pr_info("phase:%d\n", vlock.phlock_percent);
+ vinfo = get_current_vinfo();
+ pr_info("vinfo sync_duration_num:%d\n", vinfo->sync_duration_num);
+ pr_info("vinfo sync_duration_den:%d\n", vinfo->sync_duration_den);
+ pr_info("vinfo video_clk:%d\n", vinfo->video_clk);
+ pr_info("vframe input_hz:%d\n", vlock.input_hz);
+ pr_info("vframe output_hz:%d\n", vlock.output_hz);
}
+
void vlock_reg_dump(void)
{
unsigned int addr;
+ unsigned int val;
pr_info("----dump vlock reg----\n");
for (addr = (0x3000); addr <= (0x3020); addr++)
pr_info("[0x%x]vcbus[0x%04x]=0x%08x\n",
(0xd0100000+(addr<<2)), addr,
READ_VPP_REG(addr));
+
+ if (vlock.dtdata->vlk_hwver >= vlock_hw_ver2) {
+ for (addr = (0x3021); addr <= (0x302b); addr++)
+ pr_info("[0x%x]vcbus[0x%04x]=0x%08x\n",
+ (0xd0100000+(addr<<2)), addr,
+ READ_VPP_REG(addr));
+ amvecm_hiu_reg_read(HHI_HDMI_PLL_VLOCK_CNTL, &val);
+ pr_info("HIU [0x%04x]=0x%08x\n", HHI_HDMI_PLL_VLOCK_CNTL, val);
+ }
+ /*amvecm_hiu_reg_read(hhi_pll_reg_m, &val);*/
+ val = vlock_get_panel_pll_m();
+ pr_info("HIU pll m[0x%04x]=0x%08x\n", hhi_pll_reg_m, val);
+ /*amvecm_hiu_reg_read(hhi_pll_reg_frac, &val);*/
+ val = vlock_get_panel_pll_frac();
+ pr_info("HIU pll f[0x%04x]=0x%08x\n", hhi_pll_reg_frac, val);
+
+ /*back up orignal pll value*/
+ pr_info("HIU pll m[0x%x]=0x%x\n", hhi_pll_reg_m, vlock.val_m);
+ pr_info("HIU pll f[0x%x]=0x%x\n", hhi_pll_reg_frac, vlock.val_frac);
+
}
/*work around method for vlock process hdmirx input interlace source.@20170803
**for interlace input,TOP and BOT have one line delta,
void vdin_vlock_input_sel(unsigned int type,
enum vframe_source_type_e source_type)
{
+ if (vlock.dtdata->vlk_hwver >= vlock_hw_ver2)
+ return;
+ /*
+ *1:fromhdmi rx ,
+ *2:from tv-decoder,
+ *3:from dvin,
+ *4:from dvin,
+ *5:from 2nd bt656
+ */
vlock_intput_type = type & VIDTYPE_TYPEMASK;
- if ((vlock_intput_type == 0) ||
+ if ((vlock_intput_type == VIDTYPE_PROGRESSIVE) ||
(vlock_mode & VLOCK_MODE_MANUAL_SOFT_ENC))
return;
if (vlock_intput_type == VIDTYPE_INTERLACE_TOP) {
vlock_mode &= ~VLOCK_MODE_MANUAL_MIX_PLL_ENC;
vlock_mode |= VLOCK_MODE_MANUAL_PLL;
}
+ pr_info("param_config vlock_en:%d\n", vlock_en);
}
int vlock_notify_callback(struct notifier_block *block, unsigned long cmd,
return 0;
}
+static int __init phlock_phase_config(char *str)
+{
+ unsigned char *ptr = str;
+
+ pr_info("%s: bootargs is %s.\n", __func__, str);
+ if (strstr(ptr, "1"))
+ vlock.phlock_percent = 99;
+ else
+ vlock.phlock_percent = 40;
+
+ return 0;
+}
+__setup("video_reverse=", phlock_phase_config);
+
/*video lock end*/
#include <linux/amlogic/media/vfm/vframe.h>
#include "linux/amlogic/media/amvecm/ve.h"
-#define VLOCK_VER "Ref.2018/11/07a"
+#define VLOCK_VER "Ref.2019/1/24"
#define VLOCK_REG_NUM 33
VLOCK_PARAM_MAX,
};
+struct stvlock_sig_sts {
+ u32 fsm_sts;
+ u32 fsm_prests;
+ u32 vf_sts;
+ u32 vmd_chg;
+ u32 frame_cnt_in;
+ u32 frame_cnt_no;
+ u32 input_hz;
+ u32 output_hz;
+ bool md_support;
+ u32 phlock_percent;
+ struct vecm_match_data_s *dtdata;
+ u32 val_frac;
+ u32 val_m;
+};
extern void amve_vlock_process(struct vframe_s *vf);
extern void amve_vlock_resume(void);
extern void vlock_param_set(unsigned int val, enum vlock_param_e sel);
extern void vlock_log_start(void);
extern void vlock_log_stop(void);
extern void vlock_log_print(void);
-
+extern int phase_lock_check(void);
#define VLOCK_STATE_NULL 0
#define VLOCK_STATE_ENABLE_STEP1_DONE 1
#define VLOCK_STATE_ENABLE_FORCE_RESET 5
/* video lock */
-#define VLOCK_MODE_AUTO_ENC (1 << 0)
-#define VLOCK_MODE_AUTO_PLL (1 << 1)
-#define VLOCK_MODE_MANUAL_PLL (1 << 2)
-#define VLOCK_MODE_MANUAL_ENC (1 << 3)
-#define VLOCK_MODE_MANUAL_SOFT_ENC (1 << 4)
-#define VLOCK_MODE_MANUAL_MIX_PLL_ENC (1 << 5)
+enum VLOCK_MD {
+ VLOCK_MODE_AUTO_ENC = 0x01,
+ VLOCK_MODE_AUTO_PLL = 0x02,
+ VLOCK_MODE_MANUAL_PLL = 0x04,
+ VLOCK_MODE_MANUAL_ENC = 0x08,
+ VLOCK_MODE_MANUAL_SOFT_ENC = 0x10,
+ VLOCK_MODE_MANUAL_MIX_PLL_ENC = 0x20,
+};
+
+#define IS_MANUAL_MODE(md) (md & \
+ (VLOCK_MODE_MANUAL_PLL | \
+ VLOCK_MODE_MANUAL_ENC | \
+ VLOCK_MODE_MANUAL_SOFT_ENC))
+
+#define IS_AUTO_MODE(md) (md & \
+ (VLOCK_MODE_AUTO_PLL | \
+ VLOCK_MODE_AUTO_ENC))
+
+#define IS_PLL_MODE(md) (md & \
+ (VLOCK_MODE_MANUAL_PLL | \
+ VLOCK_MODE_AUTO_PLL))
+
+#define IS_ENC_MODE(md) (md & \
+ (VLOCK_MODE_MANUAL_ENC | \
+ VLOCK_MODE_MANUAL_SOFT_ENC | \
+ VLOCK_MODE_AUTO_ENC))
+
+#define IS_AUTO_PLL_MODE(md) (md & \
+ VLOCK_MODE_AUTO_PLL)
+
+#define IS_MANUAL_ENC_MODE(md) (md & \
+ VLOCK_MODE_MANUAL_ENC)
+
+#define IS_MANUAL_PLL_MODE(md) (md & \
+ VLOCK_MODE_MANUAL_PLL)
+
+#define IS_MANUAL_SOFTENC_MODE(md) (md & \
+ VLOCK_MODE_MANUAL_SOFT_ENC)
+
#define XTAL_VLOCK_CLOCK 24000000/*vlock use xtal clock*/
#define VLOCK_PLL_ADJ_LIMIT 9/*vlock pll adj limit(0x300a default)*/
/*vlock_debug mask*/
-#define VLOCK_DEBUG_INFO (1 << 0)
-#define VLOCK_DEBUG_FLUSH_REG_DIS (1 << 1)
-#define VLOCK_DEBUG_ENC_LINE_ADJ_DIS (1 << 2)
-#define VLOCK_DEBUG_ENC_PIXEL_ADJ_DIS (1 << 3)
-#define VLOCK_DEBUG_AUTO_MODE_LOG_EN (1 << 4)
-#define VLOCK_DEBUG_PLL2ENC_DIS (1 << 5)
+#define VLOCK_DEBUG_INFO (0x1)
+#define VLOCK_DEBUG_FLUSH_REG_DIS (0x2)
+#define VLOCK_DEBUG_ENC_LINE_ADJ_DIS (0x4)
+#define VLOCK_DEBUG_ENC_PIXEL_ADJ_DIS (0x8)
+#define VLOCK_DEBUG_AUTO_MODE_LOG_EN (0x10)
+#define VLOCK_DEBUG_PLL2ENC_DIS (0x20)
+#define VLOCK_DEBUG_FSM_DIS (0x40)
/* 0:enc;1:pll;2:manual pll */
extern unsigned int vlock_mode;
extern unsigned int vlock_en;
extern unsigned int vecm_latch_flag;
-extern void __iomem *amvecm_hiu_reg_base;
+/*extern void __iomem *amvecm_hiu_reg_base;*/
extern unsigned int probe_ok;
extern void lcd_ss_enable(bool flag);
extern int vlock_notify_callback(struct notifier_block *block,
unsigned long cmd, void *para);
#endif
+extern void vlock_status_init(void);
+extern void vlock_dt_match_init(struct vecm_match_data_s *pdata);
+extern void vlock_set_en(bool en);
+extern void vlock_set_phase(u32 percent);
+extern void vlock_set_phase_en(u32 en);
if (!p)
return -1;
memset(p, val, span);
+ codec_mm_dma_flush(p, span, DMA_TO_DEVICE);
codec_mm_unmap_phyaddr(p);
}
return 0;
p = codec_mm_vmap(addr, span);
if (!p)
return -1;
+ codec_mm_dma_flush(p, span, DMA_FROM_DEVICE);
vfs_write(fp, (char *)p,
span, &pos);
pos += span;
}
para.dest_hactive = dst_w;
para.dest_vactive = dst_h;
+ para.reserved |= PARAM_STATE_SCREENCAP;
if (para.scan_mode == TVIN_SCAN_MODE_INTERLACED)
para.dest_vactive = para.dest_vactive / 2;
if (para.port == TVIN_PORT_VIU1_VIDEO) {
if (vf && (vf->source_type
!= VFRAME_SOURCE_TYPE_HDMI))
r |= (1 << 19); /* dos_uncomp */
+
+ if (type & VIDTYPE_COMB_MODE)
+ r |= (1 << 20);
}
VSYNC_WR_MPEG_REG(AFBC_ENABLE, r);
if (is_meson_gxtvbb_cpu() || is_meson_gxl_cpu() ||
is_meson_gxm_cpu() || is_meson_g12a_cpu() ||
- is_meson_g12b_cpu() || is_meson_tl1_cpu()) {
+ is_meson_g12b_cpu() || is_meson_tl1_cpu() ||
+ is_meson_tm2_cpu()) {
hw_cnt = 1;
} else if (is_meson_gxbb_cpu()) {
hw_cnt = 2;
}
/*
+ * hdmirx_get_allm_mode - get allm mode
+ */
+void hdmirx_get_latency_info(struct tvin_sig_property_s *prop)
+{
+ prop->latency.allm_mode = rx.vs_info_details.allm_mode;
+ prop->latency.it_content = it_content;
+ prop->latency.cn_type = rx.cur.cn_type;
+}
+
+/*
* hdmirx_get_hdr_info - get hdr info
*/
void hdmirx_get_hdr_info(struct tvin_sig_property_s *prop)
hdmirx_set_timing_info(prop);
hdmirx_get_hdr_info(prop);
hdmirx_get_vsi_info(prop);
+ hdmirx_get_latency_info(prop);
prop->skip_vf_num = vdin_drop_frame_cnt;
}
*
*
*/
-#define RX_VER1 "ver.2018/10/22"
+#define RX_VER1 "ver.2018/12/24"
/*
*
*
MAP_ADDR_MODULE_NUM
};
+enum rx_cn_type_e {
+ CN_GRAPHICS,
+ CN_PHOTO,
+ CN_CINEMA,
+ CN_GAME,
+};
+
/**
* @short HDMI RX controller video parameters
*
enum hdmi_vic_e sw_vic;
uint8_t sw_dvi;
unsigned int it_content;
+ enum rx_cn_type_e cn_type;
/** AVI Q1-0, RGB quantization range */
unsigned int rgb_quant_range;
/** AVI Q1-0, YUV quantization range */
bool backlt_md_bit;
unsigned int dolby_timeout;
unsigned int eff_tmax_pq;
+ bool allm_mode;
};
#define CHANNEL_STATUS_SIZE 24
/* AVI parameters */
rx.cur.hw_vic =
hdmirx_rd_bits_dwc(DWC_PDEC_AVI_PB, VID_IDENT_CODE);
+ rx.cur.cn_type =
+ hdmirx_rd_bits_dwc(DWC_PDEC_AVI_HB, CONETNT_TYPE);
rx.cur.repeat =
hdmirx_rd_bits_dwc(DWC_PDEC_AVI_HB, PIX_REP_FACTOR);
rx.cur.colorspace =
#define N_DECODED MSK(20, 0)
/** Register address: auxiliary video information info frame */
#define DWC_PDEC_AVI_HB (0x3A0UL)
+/** AVI content type*/
+#define CONETNT_TYPE MSK(2, 28)
/** PR3-0, pixel repetition factor */
#define PIX_REP_FACTOR MSK(4, 24)
/** Q1-0, YUV quantization range */
((pkt->sbpkt.payload.data[0] & 0xff) == 0)) {
rx.vs_info_details.dolby_vision = false;
}
+ } else if (pkt->ieee == 0xd85dc4) {
+ /*TODO:hdmi2.1 spec vsi packet*/
+ tmp = pkt->sbpkt.payload.data[0] & _BIT(9);
+ rx.vs_info_details.allm_mode = tmp ? true : false;
} else {
/*3d VSI*/
if (pkt->sbpkt.vsi_3Dext.vdfmt == VSI_FORMAT_3D_FORMAT) {
/*pb6*/
uint8_t data[22];/* val=0 */
} __packed vsi_DobV;
-
+ /*TODO:hdmi2.1 spec vsi packet*/
+ struct vsi_st_21 {
+ /*pb4*/
+ uint8_t ver:8;
+ /*pb5*/
+ uint8_t threeD_valid:1;
+ uint8_t allm_mode:1;
+ uint8_t rsvd1:2;
+ uint8_t ccbpc:4;
+ /*pb6*/
+ /*todo*/
+ } __packed vsi_st_21;
} __packed sbpkt;
} __packed;
static int cutwindow_val_h_level3 = 20;
static int cutwindow_val_h_level4 = 62;/*48-->62 for ntsc-m*/
+/*tvconfig snow config*/
+static bool snow_cfg;
/*1: snow function on;*/
/*0: off snow function*/
bool tvafe_snow_function_flag;
#ifdef CONFIG_AMLOGIC_MEDIA_TVIN_AVDETECT
/*only txlx chip enabled*/
if (tvafe_cpu_type() == CPU_TYPE_TXLX ||
- tvafe_cpu_type() == CPU_TYPE_TL1) {
+ tvafe_cpu_type() == CPU_TYPE_TL1 ||
+ tvafe_cpu_type() == CPU_TYPE_TM2) {
/*synctip set to 0 when tvafe working&&av connected*/
/*enable clamp if av connected*/
if (port == TVIN_PORT_CVBS1) {
enum tvin_port_e port = devp->tvafe.parm.port;
mutex_lock(&devp->afe_mutex);
+ manual_flag = 0;
if (!(devp->flags & TVAFE_FLAG_DEV_OPENED)) {
tvafe_pr_err("tvafe_dec_start(%d) decode havn't opened\n",
W_APB_REG(CVD2_H_LOOP_MAXSTATE, 0x9);
#ifdef CONFIG_AMLOGIC_MEDIA_TVIN_AVDETECT
- if (tvafe_cpu_type() == CPU_TYPE_TXLX) {
+ if (tvafe_cpu_type() == CPU_TYPE_TXLX ||
+ tvafe_cpu_type() == CPU_TYPE_TL1 ||
+ tvafe_cpu_type() == CPU_TYPE_TM2) {
if (port == TVIN_PORT_CVBS1)
tvafe_avin_detect_ch1_anlog_enable(0);
else if (port == TVIN_PORT_CVBS2)
tvafe_cvd2_set_default_de(&tvafe->cvd2);
}
#ifdef CONFIG_AMLOGIC_MEDIA_TVIN_AVDETECT
- if (tvafe_cpu_type() == CPU_TYPE_TXLX) {
+ if (tvafe_cpu_type() == CPU_TYPE_TXLX ||
+ tvafe_cpu_type() == CPU_TYPE_TL1 ||
+ tvafe_cpu_type() == CPU_TYPE_TM2) {
if (port == TVIN_PORT_CVBS1)
tvafe_avin_detect_ch1_anlog_enable(1);
else if (port == TVIN_PORT_CVBS2)
#endif
#ifdef CONFIG_AMLOGIC_MEDIA_TVIN_AVDETECT
if (tvafe_cpu_type() == CPU_TYPE_TXLX ||
- tvafe_cpu_type() == CPU_TYPE_TL1) {
+ tvafe_cpu_type() == CPU_TYPE_TL1 ||
+ tvafe_cpu_type() == CPU_TYPE_TM2) {
/*avsync tip set 1 to resume av detect*/
if (tvafe->parm.port == TVIN_PORT_CVBS1) {
avport_opened = 0;
if ((port >= TVIN_PORT_CVBS0) && (port <= TVIN_PORT_CVBS3)) {
ret = tvafe_cvd2_no_sig(&tvafe->cvd2, &devp->mem);
+ /*fix black side when config atv snow*/
+ if (ret && (port == TVIN_PORT_CVBS3) &&
+ (devp->flags & TVAFE_FLAG_DEV_SNOW_FLAG) &&
+ (tvafe->cvd2.config_fmt == TVIN_SIG_FMT_CVBS_PAL_I) &&
+ (tvafe->cvd2.info.state != TVAFE_CVD2_STATE_FIND))
+ tvafe_snow_config_acd();
+ else if ((tvafe->cvd2.config_fmt == TVIN_SIG_FMT_CVBS_PAL_I) &&
+ (tvafe->cvd2.info.state == TVAFE_CVD2_STATE_FIND) &&
+ (port == TVIN_PORT_CVBS3))
+ tvafe_snow_config_acd_resume();
+
/* normal sigal & adc reg error, reload source mux */
if (tvafe->cvd2.info.adc_reload_en && !ret)
tvafe_set_source_muxing(port, devp->pinmux);
}
+bool tvafe_get_snow_cfg(void)
+{
+ return snow_cfg;
+}
+EXPORT_SYMBOL(tvafe_get_snow_cfg);
+
+void tvafe_set_snow_cfg(bool cfg)
+{
+ snow_cfg = cfg;
+}
+EXPORT_SYMBOL(tvafe_set_snow_cfg);
+
/**check frame skip,only for av input*/
static bool tvafe_cvbs_check_frame_skip(struct tvin_frontend_s *fe)
{
unsigned int cmd, unsigned long arg)
{
long ret = 0;
+ unsigned int snowcfg = 0;
void __user *argp = (void __user *)arg;
struct tvafe_dev_s *devp = file->private_data;
struct tvafe_info_s *tvafe = &devp->tvafe;
return -EPERM;
mutex_lock(&devp->afe_mutex);
- if (!(devp->flags & TVAFE_FLAG_DEV_OPENED)) {
-
+ if (!(devp->flags & TVAFE_FLAG_DEV_OPENED) &&
+ cmd != TVIN_IOC_S_AFE_SONWCFG) {
tvafe_pr_info("%s, tvafe device is disable, ignore the command %d\n",
__func__, cmd);
mutex_unlock(&devp->afe_mutex);
break;
}
+ case TVIN_IOC_S_AFE_SONWCFG:
+ /*tl1/txhd tvconfig snow en/disable*/
+ if (copy_from_user(&snowcfg, argp,
+ sizeof(unsigned int))) {
+ tvafe_pr_info("snowcfg: get param err\n");
+ ret = -EINVAL;
+ break;
+ }
+ if (snowcfg == 1)
+ tvafe_set_snow_cfg(true);
+ else
+ tvafe_set_snow_cfg(false);
+ tvafe_pr_info("tvconfig snow:%d\n", snow_cfg);
+ break;
case TVIN_IOC_S_AFE_SONWON:
devp->flags |= TVAFE_FLAG_DEV_SNOW_FLAG;
tvafe_snow_function_flag = true;
tvafe->cvd2.manual_fmt = fmt;
tvafe_pr_info("%s: ioctl set cvd2 manual fmt:%s.\n",
__func__, tvin_sig_fmt_str(fmt));
+ if (fmt != TVIN_SIG_FMT_NULL)
+ manual_flag = 1;
break;
}
default:
.name = "meson-tl1-tvafe",
};
+struct meson_tvafe_data meson_tm2_tvafe_data = {
+ .cpu_id = CPU_TYPE_TM2,
+ .name = "meson-tm2-tvafe",
+};
+
static const struct of_device_id meson_tvafe_dt_match[] = {
{
.compatible = "amlogic, tvafe-gxtvbb",
}, {
.compatible = "amlogic, tvafe-tl1",
.data = &meson_tl1_tvafe_data,
+ }, {
+ .compatible = "amlogic, tvafe-tm2",
+ .data = &meson_tm2_tvafe_data,
},
{},
};
/* ************************************************* */
/* *** macro definitions ********************************************* */
/* *********************************************************** */
-#define TVAFE_VER "Ref.2018/06/27"
+#define TVAFE_VER "Ref.2019/03/18"
/* used to set the flag of tvafe_dev_s */
#define TVAFE_FLAG_DEV_OPENED 0x00000010
unsigned int sizeof_tvafe_dev_s;
};
+bool tvafe_get_snow_cfg(void);
+void tvafe_set_snow_cfg(bool cfg);
+
typedef int (*hook_func_t)(void);
extern void aml_fe_hook_cvd(hook_func_t atv_mode,
hook_func_t cvd_hv_lock, hook_func_t get_fmt);
.name = "meson-tl1-avin-detect",
};
+struct meson_avin_data tm2_data = {
+ .cpu_id = AVIN_CPU_TYPE_TM2,
+ .name = "meson-tm2-avin-detect",
+};
+
static const struct of_device_id tvafe_avin_dt_match[] = {
{ .compatible = "amlogic, tvafe_avin_detect",
},
{ .compatible = "amlogic, tl1_tvafe_avin_detect",
.data = &tl1_data,
},
+ { .compatible = "amlogic, tm2_tvafe_avin_detect",
+ .data = &tm2_data,
+ },
{},
};
#else
AVIN_CPU_TYPE_TXLX = 1,
AVIN_CPU_TYPE_TXHD = 2,
AVIN_CPU_TYPE_TL1 = 3,
+ AVIN_CPU_TYPE_TM2 = 4,
AVIN_CPU_TYPE_MAX,
};
#include <linux/amlogic/media/frame_provider/tvin/tvin.h>
#include "../tvin_global.h"
#include "../tvin_format_table.h"
+#include "tvafe.h"
#include "tvafe_regs.h"
#include "tvafe_cvd.h"
#include "tvafe_debug.h"
}
/*setting for txhd snow*/
- if (tvafe_cpu_type() == CPU_TYPE_TXHD ||
- tvafe_cpu_type() == CPU_TYPE_TL1) {
+ if (tvafe_get_snow_cfg() &&
+ (tvafe_cpu_type() == CPU_TYPE_TXHD ||
+ tvafe_cpu_type() == CPU_TYPE_TL1 ||
+ tvafe_cpu_type() == CPU_TYPE_TM2)) {
W_APB_BIT(CVD2_OUTPUT_CONTROL, 3, 5, 2);
W_APB_REG(ACD_REG_6C, 0x80500000);
}
W_APB_REG(ACD_REG_2E, tmp);
scene_colorful_old = 0;
if (cvd_dbg_en)
- tvafe_pr_info("%s: vlines:%d, de_offset:%d tmp:%x\n",
+ tvafe_pr_info("%s: lrg vlines:%d, de_offset:%d tmp:%x\n",
__func__, l_ave, lines->de_offset, tmp);
}
} else {
if (lines->de_offset > 0) {
tmp = ((TVAFE_CVD2_PAL_DE_START -
- lines->de_offset) << 16) |
+ lines->de_offset + 1) << 16) |
(288 + TVAFE_CVD2_PAL_DE_START -
- lines->de_offset);
+ lines->de_offset + 1);
W_APB_REG(ACD_REG_2E, tmp);
scene_colorful_old = 0;
if (cvd_dbg_en)
#ifdef TVAFE_SET_CVBS_PGA_EN
tvafe_cvd2_reset_pga();
#endif
+ /*pali to nosignal,restore default vstart-end after auto de*/
+ if (cvd2->config_fmt == TVIN_SIG_FMT_CVBS_PAL_I) {
+ W_APB_REG(ACD_REG_2E, 0x170137);
+ if (cvd_dbg_en)
+ pr_info("[tvafe..] %s: reset auto de.\n", __func__);
+ }
/* init variable */
memset(&cvd2->info, 0, sizeof(struct tvafe_cvd2_info_s));
cvd2->cvd2_init_en = true;
cvd2->info.hs_adj_level = 0;
acd_h = acd_h_back;
}
+ } else {
+ /*signal unstable,set default value*/
+ W_APB_REG(ACD_REG_2D, acd_h_back);
+ W_APB_BIT(CVD2_ACTIVE_VIDEO_HSTART, cvd_2e,
+ HACTIVE_START_BIT, HACTIVE_START_WID);
+ W_APB_BIT(ACD_REG_28, acd_128, 16, 5);
+ cvd2->info.hs_adj_en = 0;
+ cvd2->info.hs_adj_level = 0;
+ acd_h = acd_h_back;
}
}
{
if (tvafe_snow_function_flag == 0 ||
tvafe_cpu_type() == CPU_TYPE_TXHD ||
- tvafe_cpu_type() == CPU_TYPE_TL1)
+ tvafe_cpu_type() == CPU_TYPE_TL1 ||
+ tvafe_cpu_type() == CPU_TYPE_TM2)
return;
if (onoff)
W_APB_BIT(CVD2_OUTPUT_CONTROL, 3, BLUE_MODE_BIT, BLUE_MODE_WID);
void tvafe_snow_config_clamp(unsigned int onoff)
{
if (tvafe_cpu_type() == CPU_TYPE_TXHD ||
- tvafe_cpu_type() == CPU_TYPE_TL1) {
+ tvafe_cpu_type() == CPU_TYPE_TL1 ||
+ tvafe_cpu_type() == CPU_TYPE_TM2) {
if (onoff)
vdin_adjust_tvafesnow_brightness();
return;
/*0x8e035e is debug test result*/
if (acd_h_config)
W_APB_REG(ACD_REG_2D, acd_h_config);
- acd_h = acd_h_back;
}
/*only for pal-i*/
void tvafe_snow_config_acd_resume(void)
}
} else if (!strncmp(buff, "afe_ver", strlen("afe_ver"))) {
tvafe_pr_info("tvafe version : %s\n", TVAFE_VER);
+ } else if (!strncmp(buff, "snowcfg", strlen("snowcfg"))) {
+ if (kstrtoul(parm[1], 10, &val) < 0) {
+ kfree(buf_orig);
+ return -EINVAL;
+ }
+ if (val) {
+ tvafe_set_snow_cfg(true);
+ tvafe_pr_info("[tvafe..]hadware snow cfg en\n");
+ } else {
+ tvafe_set_snow_cfg(false);
+ tvafe_pr_info("[tvafe..]hadware snow cfg dis\n");
+ }
} else if (!strncmp(buff, "snowon", strlen("snowon"))) {
if (kstrtoul(parm[1], 10, &val) < 0) {
kfree(buf_orig);
if (tvafe_cpu_type() == CPU_TYPE_TXL ||
tvafe_cpu_type() == CPU_TYPE_TXLX ||
tvafe_cpu_type() == CPU_TYPE_TXHD ||
- tvafe_cpu_type() == CPU_TYPE_TL1) {
+ tvafe_cpu_type() >= CPU_TYPE_TL1) {
tvafe_pr_info("[tvafe]%s:pin:%d\n",
__func__, (unsigned int)pin);
if (pin == TVAFE_CVBS_IN0) {
W_APB_BIT(TVFE_VAFE_CTRL1, 1,
VAFE_IN_SEL_BIT, VAFE_IN_SEL_WID);
- W_APB_BIT(TVFE_VAFE_CTRL2, 3, 4, 3);
+ if (tvafe_cpu_type() < CPU_TYPE_TL1)
+ W_APB_BIT(TVFE_VAFE_CTRL2, 3, 4, 3);
ret = TVAFE_ADC_CH_0;
} else if (pin == TVAFE_CVBS_IN1) {
W_APB_BIT(TVFE_VAFE_CTRL1, 2,
VAFE_IN_SEL_BIT, VAFE_IN_SEL_WID);
- W_APB_BIT(TVFE_VAFE_CTRL2, 5, 4, 3);
+ if (tvafe_cpu_type() < CPU_TYPE_TL1)
+ W_APB_BIT(TVFE_VAFE_CTRL2, 5, 4, 3);
ret = TVAFE_ADC_CH_1;
} else if (pin == TVAFE_CVBS_IN2) {
unsigned int i = 0;
/**disable auto mode clock**/
- if (tvafe_cpu_type() != CPU_TYPE_TL1)
+ if (tvafe_cpu_type() < CPU_TYPE_TL1)
W_HIU_REG(HHI_TVFE_AUTOMODE_CLK_CNTL, 0);
/*config adc*/
W_HIU_REG(HHI_DADC_CNTL, 0x00102038);
W_HIU_REG(HHI_DADC_CNTL2, 0x00000401);
W_HIU_REG(HHI_DADC_CNTL3, 0x00082183);
- } else if (tvafe_cpu_type() == CPU_TYPE_TL1) {
+ } else if (tvafe_cpu_type() >= CPU_TYPE_TL1) {
/** DADC CNTL for LIF signal input **/
W_HIU_REG(HHI_DADC_CNTL, 0x0030303c);
W_HIU_REG(HHI_DADC_CNTL2, 0x00003480);
W_HIU_REG(HHI_DADC_CNTL, 0x00102038);
W_HIU_REG(HHI_DADC_CNTL2, 0x00000400);
W_HIU_REG(HHI_DADC_CNTL3, 0x00082183);
- } else if (tvafe_cpu_type() == CPU_TYPE_TL1) {
+ } else if (tvafe_cpu_type() >= CPU_TYPE_TL1) {
W_HIU_REG(HHI_DADC_CNTL, 0x0030303c);
W_HIU_REG(HHI_DADC_CNTL2, 0x00003400);
W_HIU_REG(HHI_DADC_CNTL3, 0x08300b83);
if (tvafe_cpu_type() == CPU_TYPE_TXL ||
tvafe_cpu_type() == CPU_TYPE_TXLX ||
tvafe_cpu_type() == CPU_TYPE_TXHD ||
- tvafe_cpu_type() == CPU_TYPE_TL1) {
- if (tvafe_cpu_type() == CPU_TYPE_TL1) {
+ tvafe_cpu_type() >= CPU_TYPE_TL1) {
+ if (tvafe_cpu_type() >= CPU_TYPE_TL1) {
if (port == TVIN_PORT_CVBS3) {
W_APB_REG(TVFE_VAFE_CTRL0, 0x000d0710);
W_APB_REG(TVFE_VAFE_CTRL1, 0x00003000);
W_APB_REG(TVFE_VAFE_CTRL0, 0x000d0710);
W_APB_REG(TVFE_VAFE_CTRL1, 0x0);
W_APB_REG(TVFE_VAFE_CTRL2, 0x1010eeb0);
- } else if (tvafe_cpu_type() == CPU_TYPE_TL1) {
+ } else if (tvafe_cpu_type() >= CPU_TYPE_TL1) {
W_APB_REG(TVFE_VAFE_CTRL0, 0x000d0710);
W_APB_REG(TVFE_VAFE_CTRL1, 0x3000);
W_APB_REG(TVFE_VAFE_CTRL2, 0x1fe09e31);
if (tvafe_cpu_type() == CPU_TYPE_TXL ||
tvafe_cpu_type() == CPU_TYPE_TXLX ||
tvafe_cpu_type() == CPU_TYPE_TXHD ||
- tvafe_cpu_type() == CPU_TYPE_TL1) {
+ tvafe_cpu_type() >= CPU_TYPE_TL1) {
if (enable) {
tvafe_clk_gate_ctrl(1);
if (port == TVIN_PORT_CVBS3) {
break;
}
mutex_lock(&pll_mutex);
- if (tvafe_cpu_type() == CPU_TYPE_TL1) {
+ if (tvafe_cpu_type() >= CPU_TYPE_TL1) {
do {
W_HIU_REG(HHI_ADC_PLL_CNTL0_TL1, 0x012004e0);
W_HIU_REG(HHI_ADC_PLL_CNTL0_TL1, 0x312004e0);
break;
}
mutex_lock(&pll_mutex);
- if (tvafe_cpu_type() == CPU_TYPE_TL1) {
+ if (tvafe_cpu_type() >= CPU_TYPE_TL1) {
do {
W_HIU_REG(HHI_ADC_PLL_CNTL0_TL1, 0x012004e0);
W_HIU_REG(HHI_ADC_PLL_CNTL0_TL1, 0x312004e0);
break;
}
mutex_lock(&pll_mutex);
- if (tvafe_cpu_type() == CPU_TYPE_TL1) {
+ if (tvafe_cpu_type() >= CPU_TYPE_TL1) {
do {
W_HIU_REG(HHI_ADC_PLL_CNTL0_TL1, 0x012004e0);
W_HIU_REG(HHI_ADC_PLL_CNTL0_TL1, 0x312004e0);
W_HIU_REG(HHI_DEMOD_CLK_CNTL, 0x1000502);
adc_pll_lock_cnt = 1;
- } else if (tvafe_cpu_type() == CPU_TYPE_TL1) {
+ } else if (tvafe_cpu_type() >= CPU_TYPE_TL1) {
do {//25M
W_HIU_REG(HHI_ADC_PLL_CNTL0_TL1, 0x001104c8);
W_HIU_REG(HHI_ADC_PLL_CNTL0_TL1, 0x301104c8);
if ((port >= TVIN_PORT_CVBS0) && (port <= TVIN_PORT_CVBS3)) {
#ifdef CRYSTAL_25M
- if (tvafe_cpu_type() != CPU_TYPE_TL1)
+ if (tvafe_cpu_type() < CPU_TYPE_TL1)
W_HIU_REG(HHI_VAFE_CLKIN_CNTL, 0x703);/* can't write !!! */
#endif
/* enable */
/* main clk up */
- if (tvafe_cpu_type() == CPU_TYPE_TL1) {
+ if (tvafe_cpu_type() >= CPU_TYPE_TL1) {
W_HIU_BIT(HHI_ATV_DMD_SYS_CLK_CNTL, 1,
VAFE_CLK_SELECT, VAFE_CLK_SELECT_WIDTH);
W_HIU_BIT(HHI_ATV_DMD_SYS_CLK_CNTL, 1,
TVFE_ADC_CLK_DIV_WID);
/* main clk down */
- if (tvafe_cpu_type() == CPU_TYPE_TL1) {
+ if (tvafe_cpu_type() >= CPU_TYPE_TL1) {
W_HIU_BIT(HHI_ATV_DMD_SYS_CLK_CNTL, 0,
VAFE_CLK_SELECT, VAFE_CLK_SELECT_WIDTH);
W_HIU_BIT(HHI_ATV_DMD_SYS_CLK_CNTL, 0,
CPU_TYPE_TXHD = 3,
CPU_TYPE_GXLX = 4,
CPU_TYPE_TL1 = 5,
+ CPU_TYPE_TM2 = 6,
};
struct meson_tvafe_data {
return val;
}
+static inline void W_VCBUS(uint32_t reg, const uint32_t value)
+{
+ aml_write_vcbus(reg, value);
+}
+
+static inline uint32_t R_VCBUS(uint32_t reg)
+{
+ return aml_read_vcbus(reg);
+}
static inline void W_VCBUS_BIT(uint32_t reg,
const uint32_t value,
unsigned int hdr_check_cnt;
};
+enum tvin_cn_type_e {
+ GRAPHICS,
+ PHOTO,
+ CINEMA,
+ GAME,
+};
+
+struct tvin_latency_s {
+ bool allm_mode;
+ bool it_content;
+ enum tvin_cn_type_e cn_type;
+};
+
struct tvin_sig_property_s {
enum tvin_trans_fmt trans_fmt;
enum tvin_color_fmt_e color_format;
bool low_latency;/*is low latency dolby mode*/
uint8_t fps;
unsigned int skip_vf_num;/*skip pre vframe num*/
+ struct tvin_latency_s latency;
};
#define TVAFE_VF_POOL_SIZE 6 /* 8 */
#
# Makefile for Vdin.
#
+ifeq ($(TARGET_BUILD_VARIANT),userdebug)
+ccflags-y := -DDEBUG_SUPPORT
+else
+ccflags-y := -DDEBUG
+endif
obj-$(CONFIG_AMLOGIC_MEDIA_VDIN) = tvin_vdin.o
tvin_vdin-objs += vdin_v4l2.o
tvin_vdin-objs += vdin_vf.o
#include "vdin_canvas.h"
#include "vdin_afbce.h"
-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_bytes = PAGE_SIZE;
-
-unsigned int vdin_afbce_cma_alloc(struct vdin_dev_s *devp)
+/* fixed config mif by default */
+void vdin_mif_config_init(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;
- /*afbce head need 1036800 byte at most*/
- unsigned int afbce_head_size_byte = PAGE_SIZE * 300;/*1.2M*/
- /*afbce map_table need 218700 byte at most*/
- unsigned int afbce_table_size_byte = PAGE_SIZE * 60;/*0.3M*/
- unsigned int afbce_mem_used;
- unsigned int frame_head_size;
- unsigned int mmu_used;
- //unsigned long afbce_head_phy_addr;
- //unsigned long afbce_table_phy_addr;
- unsigned long body_start_paddr;
-
- if (devp->rdma_enable)
- 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_CVBS3))))
- 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;
- devp->canvas_max_num = 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) &&
- (devp->color_depth_mode != 1)) {
- h_size = roundup(h_size *
- VDIN_YUV444_10BIT_PER_PIXEL_BYTE,
- devp->canvas_align);
- devp->canvas_alin_w = h_size /
- VDIN_YUV444_10BIT_PER_PIXEL_BYTE;
- } else {
- h_size = roundup(h_size *
- VDIN_YUV444_8BIT_PER_PIXEL_BYTE,
- devp->canvas_align);
- 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, devp->canvas_align);
- devp->canvas_alin_w = h_size;
- /*todo change with canvas alloc!!*/
- /* nv21/nv12 only have 8bit mode */
+ if (devp->index == 0) {
+ W_VCBUS_BIT(VDIN_MISC_CTRL,
+ 1, VDIN0_MIF_ENABLE_BIT, 1);
+ W_VCBUS_BIT(VDIN_MISC_CTRL,
+ 0, VDIN0_OUT_AFBCE_BIT, 1);
+ W_VCBUS_BIT(VDIN_MISC_CTRL,
+ 1, VDIN0_OUT_MIF_BIT, 1);
} 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, devp->canvas_align);
- 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,
- devp->canvas_align);
- devp->canvas_alin_w = h_size /
- VDIN_YUV422_10BIT_PER_PIXEL_BYTE;
- } else {
- h_size = roundup(h_size *
- VDIN_YUV422_8BIT_PER_PIXEL_BYTE,
- devp->canvas_align);
- devp->canvas_alin_w = h_size /
- VDIN_YUV422_8BIT_PER_PIXEL_BYTE;
- }
+ W_VCBUS_BIT(VDIN_MISC_CTRL,
+ 1, VDIN1_MIF_ENABLE_BIT, 1);
+ W_VCBUS_BIT(VDIN_MISC_CTRL,
+ 0, VDIN1_OUT_AFBCE_BIT, 1);
+ W_VCBUS_BIT(VDIN_MISC_CTRL,
+ 1, VDIN1_OUT_MIF_BIT, 1);
}
- 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_bytes;
- devp->vfmem_size = (devp->vfmem_size/PAGE_SIZE + 1)*PAGE_SIZE;
-
- mem_size = PAGE_ALIGN(mem_size) * max_buffer_num +
- dolby_size_bytes * 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) {
- devp->afbce_info->head_paddr = codec_mm_alloc_for_dma(
- vdin_name, afbce_head_size_byte/PAGE_SIZE, 0, flags);
- devp->afbce_info->table_paddr = codec_mm_alloc_for_dma(
- vdin_name, afbce_table_size_byte/PAGE_SIZE, 0, flags);
- devp->afbce_info->head_size = afbce_head_size_byte;
- devp->afbce_info->table_size = afbce_table_size_byte;
- devp->afbce_info->frame_body_size = devp->vfmem_size;
-
- pr_info("vdin%d head_start = 0x%lx, head_size = 0x%x\n",
- devp->index, devp->afbce_info->head_paddr,
- devp->afbce_info->head_size);
- pr_info("vdin%d table_start = 0x%lx, table_size = 0x%x\n",
- devp->index, devp->afbce_info->table_paddr,
- devp->afbce_info->table_size);
-
- /* set fm_body_paddr */
- for (i = 0; i < max_buffer_num; i++) {
- devp->afbce_info->fm_body_paddr[i] =
- codec_mm_alloc_for_dma(vdin_name,
- devp->vfmem_size/PAGE_SIZE, 0, flags);
- if (devp->afbce_info->fm_body_paddr[i] == 0) {
- pr_err("\nvdin%d-afbce buf[%d]codec alloc fail!!!\n",
- devp->index, i);
- devp->cma_mem_alloc = 0;
- } else {
- devp->cma_mem_alloc = 1;
- pr_info("vdin%d fm_body_paddr[%d] = 0x%lx, body_size = 0x%x\n",
- devp->index, i,
- devp->afbce_info->fm_body_paddr[i],
- devp->afbce_info->frame_body_size);
- }
-
- if (devp->cma_mem_alloc == 0)
- return 1;
- }
- pr_info("vdin%d-afbce codec cma alloc ok!\n", devp->index);
- devp->mem_size = mem_size;
- } 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;
- devp->cma_mem_alloc = 1;
-
- devp->afbce_info->head_paddr = devp->mem_start;
- devp->afbce_info->head_size = 2*SZ_1M;/*2M*/
- devp->afbce_info->table_paddr =
- devp->mem_start + devp->afbce_info->head_paddr;
- devp->afbce_info->table_size = 2*SZ_1M;/*2M*/
- devp->afbce_info->frame_body_size = devp->vfmem_size;
-
- body_start_paddr = devp->afbce_info->table_paddr +
- devp->afbce_info->table_size;
-
- pr_info("vdin%d head_start = 0x%lx, head_size = 0x%x\n",
- devp->index, devp->afbce_info->head_paddr,
- devp->afbce_info->head_size);
- pr_info("vdin%d table_start = 0x%lx, table_size = 0x%x\n",
- devp->index, devp->afbce_info->table_paddr,
- devp->afbce_info->table_size);
-
- /* set fm_body_paddr */
- for (i = 0; i < max_buffer_num; i++) {
- devp->afbce_info->fm_body_paddr[i] =
- body_start_paddr + (devp->vfmem_size * i);
-
- pr_info("vdin%d body[%d]_start = 0x%lx, body_size = 0x%x\n",
- devp->index, i,
- devp->afbce_info->fm_body_paddr[i],
- devp->afbce_info->frame_body_size);
- }
-
- /*check memory over the boundary*/
- afbce_mem_used =
- devp->afbce_info->fm_body_paddr[max_buffer_num]
- + devp->afbce_info->frame_body_size -
- devp->afbce_info->head_paddr;
- if (afbce_mem_used > devp->cma_mem_size) {
- pr_info("afbce mem: afbce_mem_used(%d) > cma_mem_size(%d)\n",
- afbce_mem_used, devp->cma_mem_size);
- return 1;
- }
- devp->cma_mem_alloc = 1;
- pr_info("vdin%d cma alloc ok!\n", devp->index);
- } else {
- devp->cma_mem_alloc = 0;
- pr_err("\nvdin%d-afbce cma mem undefined2.\n",
- devp->index);
- return 1;
- }
- }
-
- /* 1 block = 32 * 4 pixle = 128 pixel */
- /* there is a header in one block, a header has 4 bytes */
- /* set fm_head_paddr start */
- frame_head_size = roundup(devp->h_active * devp->v_active, 128);
- /*h_active * v_active / 128 * 4 = frame_head_size*/
- frame_head_size = devp->h_active * devp->v_active / 32;
- frame_head_size = PAGE_ALIGN(frame_head_size);
-
- devp->afbce_info->frame_head_size = frame_head_size;
-
- for (i = 0; i < max_buffer_num; i++) {
- devp->afbce_info->fm_head_paddr[i] =
- devp->afbce_info->head_paddr + (frame_head_size*i);
-
- pr_info("vdin%d fm_head_paddr[%d] = 0x%lx, frame_head_size = 0x%x\n",
- devp->index, i,
- devp->afbce_info->fm_head_paddr[i],
- frame_head_size);
- }
- /* set fm_head_paddr end */
-
- /* set fm_table_paddr start */
- mmu_used = devp->afbce_info->frame_body_size >> 12;
- mmu_used = mmu_used * 4;
- mmu_used = PAGE_ALIGN(mmu_used);
- devp->afbce_info->frame_table_size = mmu_used;
-
- for (i = 0; i < max_buffer_num; i++) {
- devp->afbce_info->fm_table_paddr[i] =
- devp->afbce_info->table_paddr + (mmu_used*i);
-
- pr_info("vdin%d fm_table_paddr[%d]=0x%lx, frame_table_size = 0x%x\n",
- devp->index, i,
- devp->afbce_info->fm_table_paddr[i],
- devp->afbce_info->frame_table_size);
- }
- /* set fm_table_paddr end */
-
- return 0;
}
-void vdin_afbce_cma_release(struct vdin_dev_s *devp)
+/* only support init vdin0 mif/afbce */
+void vdin_write_mif_or_afbce_init(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);
+ enum vdin_output_mif_e sel;
+
+ if ((devp->afbce_flag & VDIN_AFBCE_EN) == 0)
return;
+
+ if (devp->afbce_mode == 0)
+ sel = VDIN_OUTPUT_TO_MIF;
+ else
+ sel = VDIN_OUTPUT_TO_AFBCE;
+
+ if (devp->index == 0) {
+ if (sel == VDIN_OUTPUT_TO_MIF) {
+ vdin_afbce_hw_disable();
+
+ W_VCBUS_BIT(VDIN_MISC_CTRL,
+ 1, VDIN0_MIF_ENABLE_BIT, 1);
+ W_VCBUS_BIT(VDIN_MISC_CTRL,
+ 0, VDIN0_OUT_AFBCE_BIT, 1);
+ W_VCBUS_BIT(VDIN_MISC_CTRL,
+ 1, VDIN0_OUT_MIF_BIT, 1);
+ } else if (sel == VDIN_OUTPUT_TO_AFBCE) {
+ W_VCBUS_BIT(VDIN_MISC_CTRL,
+ 1, VDIN0_MIF_ENABLE_BIT, 1);
+ W_VCBUS_BIT(VDIN_MISC_CTRL,
+ 0, VDIN0_OUT_MIF_BIT, 1);
+ W_VCBUS_BIT(VDIN_MISC_CTRL,
+ 1, VDIN0_OUT_AFBCE_BIT, 1);
+
+ vdin_afbce_hw_enable();
+ }
}
- if (devp->index == 0)
- strcpy(vdin_name, "vdin0");
- else if (devp->index == 1)
- strcpy(vdin_name, "vdin1");
-
- if (devp->cma_config_flag == 0x101) {
- codec_mm_free_for_dma(vdin_name, devp->afbce_info->head_paddr);
- codec_mm_free_for_dma(vdin_name, devp->afbce_info->table_paddr);
- for (i = 0; i < devp->vfmem_max_cnt; i++)
- codec_mm_free_for_dma(vdin_name,
- devp->afbce_info->fm_body_paddr[i]);
- pr_info("vdin%d-afbce codec 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-afbce 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;
}
+/* only support config vdin0 mif/afbce dynamically */
void vdin_write_mif_or_afbce(struct vdin_dev_s *devp,
enum vdin_output_mif_e sel)
{
- unsigned int offset = devp->addr_offset;
- if (offset == 0) {
- if (sel == VDIN_OUTPUT_TO_MIF) {
- W_VCBUS_BIT(VDIN_MISC_CTRL, 1, VDIN0_MIF_ENABLE_BIT, 1);
- W_VCBUS_BIT(VDIN_MISC_CTRL, 1, VDIN0_OUT_MIF_BIT, 1);
- W_VCBUS_BIT(VDIN_MISC_CTRL, 0, VDIN0_OUT_AFBCE_BIT, 1);
- } else if (sel == VDIN_OUTPUT_TO_AFBCE) {
- W_VCBUS_BIT(VDIN_MISC_CTRL, 1, VDIN0_MIF_ENABLE_BIT, 1);
- W_VCBUS_BIT(VDIN_MISC_CTRL, 0, VDIN0_OUT_MIF_BIT, 1);
- W_VCBUS_BIT(VDIN_MISC_CTRL, 1, VDIN0_OUT_AFBCE_BIT, 1);
- }
- } else {
- if (sel == VDIN_OUTPUT_TO_MIF) {
- W_VCBUS_BIT(VDIN_MISC_CTRL, 1, VDIN1_MIF_ENABLE_BIT, 1);
- W_VCBUS_BIT(VDIN_MISC_CTRL, 1, VDIN1_OUT_MIF_BIT, 1);
- W_VCBUS_BIT(VDIN_MISC_CTRL, 0, VDIN1_OUT_AFBCE_BIT, 1);
- } else if (sel == VDIN_OUTPUT_TO_AFBCE) {
- /*sel vdin1 afbce: not support in sw now,
- *just reserved interface
- */
- W_VCBUS_BIT(VDIN_MISC_CTRL, 1, VDIN1_MIF_ENABLE_BIT, 1);
- W_VCBUS_BIT(VDIN_MISC_CTRL, 0, VDIN1_OUT_MIF_BIT, 1);
- W_VCBUS_BIT(VDIN_MISC_CTRL, 1, VDIN1_OUT_AFBCE_BIT, 1);
- }
+ if ((devp->afbce_flag & VDIN_AFBCE_EN) == 0)
+ return;
+
+ if (sel == VDIN_OUTPUT_TO_MIF) {
+ rdma_write_reg_bits(devp->rdma_handle, AFBCE_ENABLE, 0, 8, 1);
+ rdma_write_reg_bits(devp->rdma_handle, VDIN_MISC_CTRL,
+ 0, VDIN0_OUT_AFBCE_BIT, 1);
+ rdma_write_reg_bits(devp->rdma_handle, VDIN_MISC_CTRL,
+ 1, VDIN0_OUT_MIF_BIT, 1);
+ } else if (sel == VDIN_OUTPUT_TO_AFBCE) {
+ rdma_write_reg_bits(devp->rdma_handle, VDIN_MISC_CTRL,
+ 0, VDIN0_OUT_MIF_BIT, 1);
+ rdma_write_reg_bits(devp->rdma_handle, VDIN_MISC_CTRL,
+ 1, VDIN0_OUT_AFBCE_BIT, 1);
+ rdma_write_reg_bits(devp->rdma_handle, AFBCE_ENABLE, 1, 8, 1);
}
}
-
+/*
static void afbce_wr(uint32_t reg, const uint32_t val)
{
wr(0, reg, val);
}
+*/
+#define VDIN_AFBCE_HOLD_LINE_NUM 4
+void vdin_afbce_update(struct vdin_dev_s *devp)
+{
+ int hold_line_num = VDIN_AFBCE_HOLD_LINE_NUM;
+ int reg_format_mode;/* 0:444 1:422 2:420 */
+ int reg_fmt444_comb;
+ int sblk_num;
+ int uncmp_bits;
+ int uncmp_size;
+
+ if (!devp->afbce_info)
+ return;
+
+#ifndef CONFIG_AMLOGIC_MEDIA_RDMA
+ pr_info("##############################################\n");
+ pr_info("vdin afbce must use RDMA,but it not be opened\n");
+ pr_info("##############################################\n");
+#endif
+
+ if ((devp->prop.dest_cfmt == TVIN_YUV444) && (devp->h_active > 2048))
+ reg_fmt444_comb = 1;
+ else
+ reg_fmt444_comb = 0;
+
+ if ((devp->prop.dest_cfmt == TVIN_NV12) ||
+ (devp->prop.dest_cfmt == TVIN_NV21)) {
+ reg_format_mode = 2;
+ sblk_num = 12;
+ } else if ((devp->prop.dest_cfmt == TVIN_YUV422) ||
+ (devp->prop.dest_cfmt == TVIN_YUYV422) ||
+ (devp->prop.dest_cfmt == TVIN_YVYU422) ||
+ (devp->prop.dest_cfmt == TVIN_UYVY422) ||
+ (devp->prop.dest_cfmt == TVIN_VYUY422)) {
+ reg_format_mode = 1;
+ sblk_num = 16;
+ } else {
+ reg_format_mode = 0;
+ sblk_num = 24;
+ }
+ uncmp_bits = devp->source_bitdepth;
+
+ /* bit size of uncompression mode */
+ uncmp_size = (((((16*uncmp_bits*sblk_num)+7)>>3)+31)/32)<<1;
+ /*
+ *pr_info("%s: dest_cfmt=%d, reg_format_mode=%d, uncmp_bits=%d,
+ * sblk_num=%d, uncmp_size=%d\n",
+ * __func__, devp->prop.dest_cfmt, reg_format_mode,
+ * uncmp_bits, sblk_num, uncmp_size);
+ */
+
+ rdma_write_reg(devp->rdma_handle, AFBCE_MODE,
+ (0 & 0x7) << 29 | (0 & 0x3) << 26 | (3 & 0x3) << 24 |
+ (hold_line_num & 0x7f) << 16 |
+ (2 & 0x3) << 14 | (reg_fmt444_comb & 0x1));
+
+ rdma_write_reg_bits(devp->rdma_handle,
+ AFBCE_MIF_SIZE, (uncmp_size & 0x1fff), 16, 5);/* uncmp_size */
+
+ rdma_write_reg(devp->rdma_handle, AFBCE_FORMAT,
+ (reg_format_mode & 0x3) << 8 |
+ (uncmp_bits & 0xf) << 4 |
+ (uncmp_bits & 0xf));
+}
void vdin_afbce_config(struct vdin_dev_s *devp)
{
- unsigned int offset = devp->addr_offset;
- int hold_line_num = 4;
+ int hold_line_num = VDIN_AFBCE_HOLD_LINE_NUM;
int lbuf_depth = 256;
int lossy_luma_en = 0;
int lossy_chrm_en = 0;
int sblk_num;
int uncmp_bits;
int uncmp_size;
- int def_color_0 = 0;
- int def_color_1 = 0;
- int def_color_2 = 0;
+ int def_color_0 = 4095;
+ int def_color_1 = 2048;
+ int def_color_2 = 2048;
int def_color_3 = 0;
int hblksize_out = (devp->h_active + 31) >> 5;
int vblksize_out = (devp->v_active + 3) >> 2;
int enc_win_bgn_v;//input scope
int enc_win_end_v;//input scope
- if (offset != 0) {
- pr_info("cat not use afbce on vdin1 at the moment\n");
+ if (!devp->afbce_info)
return;
- }
+
+#ifndef CONFIG_AMLOGIC_MEDIA_RDMA
+ pr_info("##############################################\n");
+ pr_info("vdin afbce must use RDMA,but it not be opened\n");
+ pr_info("##############################################\n");
+#endif
enc_win_bgn_h = 0;
enc_win_end_h = devp->h_active - 1;
W_VCBUS_BIT(VDIN_WRARB_REQEN_SLV, 0x1, 3, 1);//vpu arb axi_enable
W_VCBUS_BIT(VDIN_WRARB_REQEN_SLV, 0x1, 7, 1);//vpu arb axi_enable
- afbce_wr(AFBCE_MODE,
+ W_VCBUS(AFBCE_MODE,
(0 & 0x7) << 29 | (0 & 0x3) << 26 | (3 & 0x3) << 24 |
(hold_line_num & 0x7f) << 16 |
(2 & 0x3) << 14 | (reg_fmt444_comb & 0x1));
W_VCBUS_BIT(AFBCE_QUANT_ENABLE, (lossy_luma_en & 0x1), 0, 1);//loosy
W_VCBUS_BIT(AFBCE_QUANT_ENABLE, (lossy_chrm_en & 0x1), 4, 1);//loosy
- afbce_wr(AFBCE_SIZE_IN,
+ if (devp->afbce_flag & VDIN_AFBCE_EN_LOOSY) {
+ W_VCBUS(AFBCE_QUANT_ENABLE, 0xc11);
+ pr_info("afbce use lossy compression mode\n");
+ }
+
+ W_VCBUS(AFBCE_SIZE_IN,
((devp->h_active & 0x1fff) << 16) | // hsize_in of afbc input
((devp->v_active & 0x1fff) << 0) // vsize_in of afbc input
);
- afbce_wr(AFBCE_BLK_SIZE_IN,
+ W_VCBUS(AFBCE_BLK_SIZE_IN,
((hblksize_out & 0x1fff) << 16) | // out blk hsize
((vblksize_out & 0x1fff) << 0) // out blk vsize
);
//head addr of compressed data
- afbce_wr(AFBCE_HEAD_BADDR, devp->afbce_info->fm_head_paddr[0]);
+ W_VCBUS(AFBCE_HEAD_BADDR,
+ devp->afbce_info->fm_head_paddr[0]);
W_VCBUS_BIT(AFBCE_MIF_SIZE, (uncmp_size & 0x1fff), 16, 5);//uncmp_size
/* how to set reg when we use crop ? */
// scope of hsize_in ,should be a integer multipe of 32
// scope of vsize_in ,should be a integer multipe of 4
- afbce_wr(AFBCE_PIXEL_IN_HOR_SCOPE,
+ W_VCBUS(AFBCE_PIXEL_IN_HOR_SCOPE,
((enc_win_end_h & 0x1fff) << 16) |
((enc_win_bgn_h & 0x1fff) << 0));
// scope of hsize_in ,should be a integer multipe of 32
// scope of vsize_in ,should be a integer multipe of 4
- afbce_wr(AFBCE_PIXEL_IN_VER_SCOPE,
+ W_VCBUS(AFBCE_PIXEL_IN_VER_SCOPE,
((enc_win_end_v & 0x1fff) << 16) |
((enc_win_bgn_v & 0x1fff) << 0));
- afbce_wr(AFBCE_CONV_CTRL, lbuf_depth);//fix 256
+ W_VCBUS(AFBCE_CONV_CTRL, lbuf_depth);//fix 256
- afbce_wr(AFBCE_MIF_HOR_SCOPE,
+ W_VCBUS(AFBCE_MIF_HOR_SCOPE,
((blk_out_bgn_h & 0x3ff) << 16) | // scope of out blk hsize
((blk_out_end_h & 0xfff) << 0) // scope of out blk vsize
);
- afbce_wr(AFBCE_MIF_VER_SCOPE,
+ W_VCBUS(AFBCE_MIF_VER_SCOPE,
((blk_out_bgn_v & 0x3ff) << 16) | // scope of out blk hsize
((blk_out_end_v & 0xfff) << 0) // scope of out blk vsize
);
- afbce_wr(AFBCE_FORMAT,
+ W_VCBUS(AFBCE_FORMAT,
(reg_format_mode & 0x3) << 8 |
(uncmp_bits & 0xf) << 4 |
(uncmp_bits & 0xf));
- afbce_wr(AFBCE_DEFCOLOR_1,
+ W_VCBUS(AFBCE_DEFCOLOR_1,
((def_color_3 & 0xfff) << 12) | // def_color_a
((def_color_0 & 0xfff) << 0) // def_color_y
);
- afbce_wr(AFBCE_DEFCOLOR_2,
+ W_VCBUS(AFBCE_DEFCOLOR_2,
((def_color_2 & 0xfff) << 12) | // def_color_v
((def_color_1 & 0xfff) << 0) // def_color_u
);
- //cur_mmu_used += Rd(AFBCE_MMU_NUM); //4k addr have used in every frame;
-
W_VCBUS_BIT(AFBCE_MMU_RMIF_CTRL4, devp->afbce_info->table_paddr, 0, 32);
W_VCBUS_BIT(AFBCE_MMU_RMIF_SCOPE_X, cur_mmu_used, 0, 12);
- W_VCBUS_BIT(AFBCE_ENABLE, 1, 8, 1);//enable afbce
+ W_VCBUS_BIT(AFBCE_ENABLE, 1, 12, 1); //set afbce pulse mode
+ W_VCBUS_BIT(AFBCE_ENABLE, 0, 8, 1);//disable afbce
}
void vdin_afbce_maptable_init(struct vdin_dev_s *devp)
{
unsigned int i, j;
- unsigned int *ptable = NULL;
+ unsigned int highmem_flag = 0;
+ unsigned long ptable = 0;
unsigned int *vtable = NULL;
unsigned int body;
unsigned int size;
+ void *p = NULL;
+
+ if (!devp->afbce_info)
+ return;
size = roundup(devp->afbce_info->frame_body_size, 4096);
+ ptable = devp->afbce_info->fm_table_paddr[0];
+ if (devp->cma_config_flag == 0x101)
+ highmem_flag = PageHighMem(phys_to_page(ptable));
+ else
+ highmem_flag = PageHighMem(phys_to_page(ptable));
+
for (i = 0; i < devp->vfmem_max_cnt; i++) {
- ptable = (unsigned int *)
- (devp->afbce_info->fm_table_paddr[i]&0xffffffff);
- if (devp->cma_config_flag == 0x101)
- vtable = codec_mm_phys_to_virt((unsigned long)ptable);
- else if (devp->cma_config_flag == 0)
- vtable = phys_to_virt((unsigned long)ptable);
+ ptable = devp->afbce_info->fm_table_paddr[i];
+ if (highmem_flag == 0) {
+ if (devp->cma_config_flag == 0x101)
+ vtable = codec_mm_phys_to_virt(ptable);
+ else if (devp->cma_config_flag == 0)
+ vtable = phys_to_virt(ptable);
+ else
+ vtable = phys_to_virt(ptable);
+ } else {
+ vtable = (unsigned int *)vdin_vmap(ptable,
+ devp->afbce_info->frame_table_size);
+ if (vdin_dbg_en) {
+ pr_err("----vdin vmap v: %p, p: %lx, size: %d\n",
+ vtable, ptable,
+ devp->afbce_info->frame_table_size);
+ }
+ if (!vtable) {
+ pr_err("vmap fail, size: %d.\n",
+ devp->afbce_info->frame_table_size);
+ return;
+ }
+ }
+
+ p = vtable;
body = devp->afbce_info->fm_body_paddr[i]&0xffffffff;
for (j = 0; j < size; j += 4096) {
*vtable = ((j + body) >> 12) & 0x000fffff;
vtable++;
}
+
+ /* clean tail data. */
+ memset(vtable, 0, devp->afbce_info->frame_table_size -
+ ((char *)vtable - (char *)p));
+
+ vdin_dma_flush(devp, p,
+ devp->afbce_info->frame_table_size,
+ DMA_TO_DEVICE);
+
+ if (highmem_flag)
+ vdin_unmap_phyaddr(p);
+
+ vtable = NULL;
}
}
unsigned int rdma_enable, struct vf_entry *vfe)
{
unsigned char i;
- unsigned int cur_mmu_used;
+
+ if (!devp->afbce_info)
+ return;
i = vfe->af_num;
- cur_mmu_used = devp->afbce_info->fm_table_paddr[i] / 4;
-
-#ifdef CONFIG_AML_RDMA
- if (rdma_enable)
- rdma_write_reg_bits(devp->rdma_handle,
- AFBCE_HEAD_BADDR, devp->afbce_info->fm_head_paddr[i]);
- rdma_write_reg(devp->rdma_handle,
- AFBCE_MMU_RMIF_SCOPE_X, cur_mmu_used, 0, 12);
- else
+ vfe->vf.compHeadAddr = devp->afbce_info->fm_head_paddr[i];
+ vfe->vf.compBodyAddr = devp->afbce_info->fm_body_paddr[i];
+
+#ifdef CONFIG_AMLOGIC_MEDIA_RDMA
+ if (rdma_enable) {
+ rdma_write_reg(devp->rdma_handle, AFBCE_HEAD_BADDR,
+ devp->afbce_info->fm_head_paddr[i]);
+ rdma_write_reg_bits(devp->rdma_handle, AFBCE_MMU_RMIF_CTRL4,
+ devp->afbce_info->fm_table_paddr[i], 0, 32);
+ rdma_write_reg_bits(devp->rdma_handle, AFBCE_ENABLE, 1, 0, 1);
+ } else
#endif
- afbce_wr(AFBCE_HEAD_BADDR, devp->afbce_info->fm_head_paddr[i]);
- W_VCBUS_BIT(AFBCE_MMU_RMIF_SCOPE_X, cur_mmu_used, 0, 12);
+ {
+ pr_info("afbce must use RDMA.\n");
+ }
+
+ vdin_afbce_clear_writedown_flag(devp);
+}
+
+void vdin_afbce_clear_writedown_flag(struct vdin_dev_s *devp)
+{
+ rdma_write_reg(devp->rdma_handle, AFBCE_CLR_FLAG, 1);
+}
+
+/* return 1: write down*/
+int vdin_afbce_read_writedown_flag(void)
+{
+ int val1, val2;
+
+ val1 = rd_bits(0, AFBCE_STA_FLAGT, 0, 1);
+ val2 = rd_bits(0, AFBCE_STA_FLAGT, 2, 2);
+
+ if ((val1 == 1) || (val2 == 0))
+ return 1;
+ else
+ return 0;
+}
+
+void vdin_afbce_hw_disable(void)
+{
+ /*can not use RDMA*/
+ W_VCBUS_BIT(AFBCE_ENABLE, 0, 8, 1);//disable afbce
+}
+
+void vdin_afbce_hw_enable(void)
+{
+ W_VCBUS_BIT(AFBCE_ENABLE, 1, 8, 1);
}
+void vdin_afbce_hw_disable_rdma(struct vdin_dev_s *devp)
+{
+ rdma_write_reg_bits(devp->rdma_handle, AFBCE_ENABLE, 0, 8, 1);
+}
+
+void vdin_afbce_hw_enable_rdma(struct vdin_dev_s *devp)
+{
+ if (devp->afbce_flag & VDIN_AFBCE_EN_LOOSY)
+ rdma_write_reg(devp->rdma_handle, AFBCE_QUANT_ENABLE, 0xc11);
+ rdma_write_reg_bits(devp->rdma_handle, AFBCE_ENABLE, 1, 8, 1);
+}
+
+void vdin_afbce_soft_reset(void)
+{
+ W_VCBUS_BIT(AFBCE_MODE, 0, 30, 1);
+ W_VCBUS_BIT(AFBCE_MODE, 1, 30, 1);
+ W_VCBUS_BIT(AFBCE_MODE, 0, 30, 1);
+}
#define AFBCE_MMU_RMIF_RO_STAT 0x41c6
+extern void vdin_write_mif_or_afbce_init(struct vdin_dev_s *devp);
extern void vdin_write_mif_or_afbce(struct vdin_dev_s *devp,
enum vdin_output_mif_e sel);
-extern unsigned int vdin_afbce_cma_alloc(struct vdin_dev_s *devp);
-extern void vdin_afbce_cma_release(struct vdin_dev_s *devp);
+extern void vdin_afbce_update(struct vdin_dev_s *devp);
extern void vdin_afbce_config(struct vdin_dev_s *devp);
extern void vdin_afbce_maptable_init(struct vdin_dev_s *devp);
extern void vdin_afbce_set_next_frame(struct vdin_dev_s *devp,
-unsigned int rdma_enable, struct vf_entry *vfe);
-
+ unsigned int rdma_enable, struct vf_entry *vfe);
+extern void vdin_afbce_clear_writedown_flag(struct vdin_dev_s *devp);
+extern int vdin_afbce_read_writedown_flag(void);
+extern void vdin_afbce_hw_disable(void);
+extern void vdin_afbce_hw_enable(void);
+extern void vdin_afbce_hw_disable_rdma(struct vdin_dev_s *devp);
+extern void vdin_afbce_hw_enable_rdma(struct vdin_dev_s *devp);
+extern void vdin_afbce_soft_reset(void);
#endif
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->canvas_max_num < devp->vfmem_max_cnt) {
+ pr_err("\nvdin%d canvas_max_num %d less than vfmem_max_cnt %d\n",
+ devp->index, devp->canvas_max_num, devp->vfmem_max_cnt);
+ }
+
+ if (devp->set_canvas_manual == 1) {
+ for (i = 0; i < 4; i++) {
+ canvas_id =
+ vdin_canvas_ids[devp->index][i * canvas_step];
+ canvas_addr = vdin_set_canvas_addr[i].paddr;
+ canvas_config(canvas_id, canvas_addr,
+ devp->canvas_w, devp->canvas_h,
+ CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_LINEAR);
+ pr_info("canvas index=%d- %3d: 0x%lx-0x%lx %ux%u\n",
+ i, canvas_id, canvas_addr,
+ canvas_addr + devp->canvas_max_size,
+ devp->canvas_w, devp->canvas_h);
+ }
+ return;
+ }
+
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, devp->canvas_align);
/* need to be static for pointer use in codec_mm */
static char vdin_name[6];
/* return val:1: fail;0: ok */
+/* combined canvas and afbce memory */
unsigned int vdin_cma_alloc(struct vdin_dev_s *devp)
{
unsigned int mem_size, h_size, v_size;
CODEC_MM_FLAGS_DMA;
unsigned int max_buffer_num = min_buf_num;
unsigned int i;
+ /*head_size:3840*2160*3*9/32*/
+ unsigned int afbce_head_size_byte = PAGE_SIZE * 1712;
+ /*afbce map_table need 218700 byte at most*/
+ unsigned int afbce_table_size_byte = PAGE_SIZE * 60;/*0.3M*/
+ unsigned long ref_paddr;
+ unsigned int mem_used;
+ unsigned int frame_head_size;
+ unsigned int mmu_used;
if (devp->rdma_enable)
max_buffer_num++;
devp->vfmem_size = PAGE_ALIGN(mem_size) + dolby_size_byte;
devp->vfmem_size = (devp->vfmem_size/PAGE_SIZE + 1)*PAGE_SIZE;
+ if (devp->set_canvas_manual == 1) {
+ for (i = 0; i < VDIN_CANVAS_MAX_CNT; i++) {
+ if (vdin_set_canvas_addr[i].dmabuff == NULL)
+ break;
+
+ vdin_set_canvas_addr[i].paddr =
+ roundup(vdin_set_canvas_addr[i].paddr,
+ devp->canvas_align);
+ }
+
+ devp->canvas_max_num = max_buffer_num = i;
+ devp->vfmem_max_cnt = max_buffer_num;
+ }
+
+
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)
+
+ if (mem_size > devp->cma_mem_size) {
mem_size = devp->cma_mem_size;
+ pr_err("\nvdin%d cma_mem_size is not enough!!!\n", devp->index);
+ devp->cma_mem_alloc = 0;
+ return 1;
+ }
if (devp->index == 0)
strcpy(vdin_name, "vdin0");
else if (devp->index == 1)
strcpy(vdin_name, "vdin1");
if (devp->cma_config_flag == 0x101) {
+ /* canvas or afbce paddr */
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);
devp->index, i);
devp->cma_mem_alloc = 0;
return 1;
- } else {
- 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);
}
+ if (devp->afbce_info) {
+ devp->afbce_info->fm_body_paddr[i] =
+ devp->vfmem_start[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);
}
- pr_info("vdin%d codec cma alloc ok!\n", devp->index);
+ if (devp->afbce_info)
+ devp->afbce_info->frame_body_size = devp->vfmem_size;
devp->mem_size = mem_size;
+
+ if (devp->afbce_info) {
+ devp->afbce_info->head_paddr = codec_mm_alloc_for_dma(
+ vdin_name, afbce_head_size_byte/PAGE_SIZE,
+ 0, flags);
+ if (devp->afbce_info->head_paddr == 0) {
+ pr_err("\nvdin%d header codec alloc fail!!!\n",
+ devp->index);
+ devp->cma_mem_alloc = 0;
+ return 1;
+ }
+ devp->afbce_info->table_paddr = codec_mm_alloc_for_dma(
+ vdin_name, afbce_table_size_byte/PAGE_SIZE,
+ 0, flags);
+ if (devp->afbce_info->table_paddr == 0) {
+ pr_err("\nvdin%d table codec alloc fail!!!\n",
+ devp->index);
+ codec_mm_free_for_dma(vdin_name,
+ devp->afbce_info->head_paddr);
+ devp->cma_mem_alloc = 0;
+ return 1;
+ }
+ devp->afbce_info->head_size = afbce_head_size_byte;
+ devp->afbce_info->table_size = afbce_table_size_byte;
+
+ pr_info("vdin%d head_start = 0x%lx, head_size = 0x%x\n",
+ devp->index, devp->afbce_info->head_paddr,
+ devp->afbce_info->head_size);
+ pr_info("vdin%d table_start = 0x%lx, table_size = 0x%x\n",
+ devp->index, devp->afbce_info->table_paddr,
+ devp->afbce_info->table_size);
+ }
+
+ devp->cma_mem_alloc = 1;
} 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;
- } else {
- 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);
}
+ 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);
} 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 {
+ if (!devp->vfvenc_pages[i]) {
devp->cma_mem_alloc = 0;
pr_err("\nvdin%d cma mem undefined2.\n",
devp->index);
return 1;
}
+ 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);
}
+ devp->mem_size = mem_size;
devp->cma_mem_alloc = 1;
- devp->mem_size = mem_size;
- pr_info("vdin%d cma alloc ok!\n", devp->index);
} else {
+ /* canvas or afbce paddr */
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 {
+ if (!devp->venc_pages) {
devp->cma_mem_alloc = 0;
pr_err("\nvdin%d cma mem undefined2.\n",
devp->index);
return 1;
}
+ devp->mem_start = page_to_phys(devp->venc_pages);
+ devp->mem_size = mem_size;
+
+ /* set fm_body_paddr */
+ if (devp->afbce_info) {
+ ref_paddr = devp->mem_start;
+ devp->afbce_info->frame_body_size = devp->vfmem_size;
+ for (i = 0; i < max_buffer_num; i++) {
+ ref_paddr = devp->mem_start +
+ (devp->vfmem_size * i);
+ devp->afbce_info->fm_body_paddr[i] = ref_paddr;
+
+ pr_info("vdin%d body[%d]_start = 0x%lx, body_size = 0x%x\n",
+ devp->index, i,
+ devp->afbce_info->fm_body_paddr[i],
+ devp->afbce_info->frame_body_size);
+ }
+
+ /* afbce header & table paddr */
+ devp->afbce_info->head_paddr = ref_paddr +
+ devp->vfmem_size;
+ devp->afbce_info->head_size = 2 * SZ_1M;/*2M*/
+ devp->afbce_info->table_paddr =
+ devp->afbce_info->head_paddr +
+ devp->afbce_info->head_size;
+ devp->afbce_info->table_size = 2 * SZ_1M;/*2M*/
+
+ pr_info("vdin%d head_start = 0x%lx, head_size = 0x%x\n",
+ devp->index, devp->afbce_info->head_paddr,
+ devp->afbce_info->head_size);
+ pr_info("vdin%d table_start = 0x%lx, table_size = 0x%x\n",
+ devp->index, devp->afbce_info->table_paddr,
+ devp->afbce_info->table_size);
+
+ /*check memory over the boundary*/
+ mem_used = devp->afbce_info->table_paddr +
+ devp->afbce_info->table_size -
+ devp->afbce_info->fm_body_paddr[0];
+ if (mem_used > devp->cma_mem_size) {
+ pr_err("vdin%d error: mem_used(%d) > cma_mem_size(%d)\n",
+ devp->index, mem_used,
+ devp->cma_mem_size);
+ 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);
}
+
+ /* set afbce head paddr */
+ if (devp->afbce_info) {
+ /* 1 block = 32 * 4 pixle = 128 pixel */
+ /* there is a header in one block, a header has 4 bytes */
+ frame_head_size = (int)roundup(devp->vfmem_size, 128);
+ /*h_active * v_active / 128 * 4 = frame_head_size*/
+ frame_head_size = PAGE_ALIGN(frame_head_size / 32);
+
+ devp->afbce_info->frame_head_size = frame_head_size;
+
+ for (i = 0; i < max_buffer_num; i++) {
+ devp->afbce_info->fm_head_paddr[i] =
+ devp->afbce_info->head_paddr +
+ (frame_head_size*i);
+
+ pr_info("vdin%d fm_head_paddr[%d] = 0x%lx, frame_head_size = 0x%x\n",
+ devp->index, i,
+ devp->afbce_info->fm_head_paddr[i],
+ frame_head_size);
+ }
+
+ /* set afbce table paddr */
+ mmu_used = devp->afbce_info->frame_body_size >> 12;
+ mmu_used = mmu_used * 4;
+ mmu_used = PAGE_ALIGN(mmu_used);
+ devp->afbce_info->frame_table_size = mmu_used;
+
+ for (i = 0; i < max_buffer_num; i++) {
+ devp->afbce_info->fm_table_paddr[i] =
+ devp->afbce_info->table_paddr + (mmu_used*i);
+
+ pr_info("vdin%d fm_table_paddr[%d]=0x%lx, frame_table_size = 0x%x\n",
+ devp->index, i,
+ devp->afbce_info->fm_table_paddr[i],
+ devp->afbce_info->frame_table_size);
+ }
+ }
+
+ pr_info("vdin%d cma alloc ok!\n", devp->index);
return 0;
}
strcpy(vdin_name, "vdin1");
if (devp->cma_config_flag == 0x101) {
+ if (devp->afbce_info) {
+ if (devp->afbce_info->head_paddr) {
+ codec_mm_free_for_dma(vdin_name,
+ devp->afbce_info->head_paddr);
+ }
+ if (devp->afbce_info->table_paddr) {
+ codec_mm_free_for_dma(vdin_name,
+ devp->afbce_info->table_paddr);
+ }
+ }
+ /* canvas or afbce paddr */
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);
#define VDIN_MIN_SOURCE_BITDEPTH 8
-#define VDIN_YUV444_MAX_CMA_WIDTH 1920
-#define VDIN_YUV444_MAX_CMA_HEIGH 1080
+#define VDIN_YUV444_MAX_CMA_WIDTH 4096
+#define VDIN_YUV444_MAX_CMA_HEIGH 2160
extern const unsigned int vdin_canvas_ids[2][VDIN_CANVAS_MAX_CNT];
extern void vdin_canvas_init(struct vdin_dev_s *devp);
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/platform_device.h>
+#include <linux/amlogic/media/codec_mm/codec_mm.h>
+#include <linux/highmem.h>
+#include <linux/page-flags.h>
+#include <linux/vmalloc.h>
#include <linux/dma-mapping.h>
#include <linux/dma-contiguous.h>
#include <linux/amlogic/media/video_sink/video.h>
#define pr_info(fmt, ...)
#endif
+u8 *vdin_vmap(ulong addr, u32 size)
+{
+ u8 *vaddr = NULL;
+ struct page **pages = NULL;
+ u32 i, npages, offset = 0;
+ ulong phys, page_start;
+ /*pgprot_t pgprot = pgprot_noncached(PAGE_KERNEL);*/
+ pgprot_t pgprot = PAGE_KERNEL;
+
+ if (!PageHighMem(phys_to_page(addr)))
+ return phys_to_virt(addr);
+
+ offset = offset_in_page(addr);
+ page_start = addr - offset;
+ npages = DIV_ROUND_UP(size + offset, PAGE_SIZE);
+
+ pages = kmalloc_array(npages, sizeof(struct page *), GFP_KERNEL);
+ if (!pages)
+ return NULL;
+
+ for (i = 0; i < npages; i++) {
+ phys = page_start + i * PAGE_SIZE;
+ pages[i] = pfn_to_page(phys >> PAGE_SHIFT);
+ }
+
+ vaddr = vmap(pages, npages, VM_MAP, pgprot);
+ if (!vaddr) {
+ pr_err("the phy(%lx) vmaped fail, size: %d\n",
+ page_start, npages << PAGE_SHIFT);
+ kfree(pages);
+ return NULL;
+ }
+
+ kfree(pages);
+
+ if (vdin_dbg_en) {
+ pr_info("[vdin HIGH-MEM-MAP] %s, pa(%lx) to va(%p), size: %d\n",
+ __func__, page_start, vaddr, npages << PAGE_SHIFT);
+ }
+
+ return vaddr + offset;
+}
+
+void vdin_unmap_phyaddr(u8 *vaddr)
+{
+ void *addr = (void *)(PAGE_MASK & (ulong)vaddr);
+
+ if (is_vmalloc_or_module_addr(vaddr)) {
+ if (vdin_dbg_en)
+ pr_info("----vdin unmap v: %p\n", addr);
+ vunmap(addr);
+ }
+}
+
+void vdin_dma_flush(struct vdin_dev_s *devp, void *vaddr,
+ int size, enum dma_data_direction dir)
+{
+ ulong phy_addr;
+
+ if (is_vmalloc_or_module_addr(vaddr)) {
+ phy_addr = page_to_phys(vmalloc_to_page(vaddr))
+ + offset_in_page(vaddr);
+ if (phy_addr && PageHighMem(phys_to_page(phy_addr))) {
+ if (vdin_dbg_en)
+ pr_info("----vdin flush v: %p, p: %lx\n",
+ vaddr, phy_addr);
+ dma_sync_single_for_device(&devp->this_pdev->dev,
+ phy_addr, size, dir);
+ }
+ return;
+ }
+}
+
/*reset reg mif value of vdin0:
* VDIN_WR_CTRL \VDIN_COM_CTRL0\ VDIN_MISC_CTRL
*/
format_convert = VDIN_FORMAT_CONVERT_YUV_NV21;
else if (devp->prop.dest_cfmt == TVIN_NV12)
format_convert = VDIN_FORMAT_CONVERT_YUV_NV12;
+ else if (devp->prop.dest_cfmt == TVIN_YUV444)
+ format_convert = VDIN_FORMAT_CONVERT_YUV_YUV444;
else
format_convert = VDIN_FORMAT_CONVERT_YUV_YUV422;
break;
meas_mux = MEAS_MUX_656_B;
else if ((is_meson_gxl_cpu() || is_meson_gxm_cpu() ||
is_meson_g12a_cpu() || is_meson_g12b_cpu() ||
- is_meson_tl1_cpu()) && (bt_path == BT_PATH_GPIO))
+ is_meson_tl1_cpu() || is_meson_sm1_cpu() ||
+ is_meson_tm2_cpu()) &&
+ (bt_path == BT_PATH_GPIO))
meas_mux = MEAS_MUX_656;
else
pr_info("cpu not define or do not support bt656");
b.BT_PATH_GPIO_B:gxtvbb & gxbb
c.txl and txlx don't support bt656
*/
-void vdin_set_top(unsigned int offset,
+void vdin_set_top(struct vdin_dev_s *devp, unsigned int offset,
enum tvin_port_e port,
enum tvin_color_fmt_e input_cfmt, unsigned int h,
enum bt_path_e bt_path)
VDI9_ASFIFO_CTRL_BIT, VDI9_ASFIFO_CTRL_WID);
} else if ((is_meson_gxm_cpu() || is_meson_gxl_cpu() ||
is_meson_g12a_cpu() || is_meson_g12b_cpu() ||
- is_meson_tl1_cpu()) && (bt_path == BT_PATH_GPIO)) {
+ is_meson_tl1_cpu() || is_meson_sm1_cpu() ||
+ is_meson_tm2_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);
if (port != TVIN_PORT_VIU1)
wr_bits(offset, VDIN_ASFIFO_CTRL3, 0xe4,
VDI6_ASFIFO_CTRL_BIT, VDI6_ASFIFO_CTRL_WID);
- else
- wr_bits(offset, VDIN_ASFIFO_CTRL3, 0xf4,
- VDI6_ASFIFO_CTRL_BIT, VDI6_ASFIFO_CTRL_WID);
+ else {
+ if (/*is_meson_gxlx2_cpu() || */is_meson_g12b_cpu()
+ || is_meson_tl1_cpu() || is_meson_sm1_cpu() ||
+ is_meson_tm2_cpu())
+ wr_bits(offset, VDIN_ASFIFO_CTRL3, 0xd4,
+ VDI6_ASFIFO_CTRL_BIT,
+ VDI6_ASFIFO_CTRL_WID);
+ else
+ wr_bits(offset, VDIN_ASFIFO_CTRL3, 0xf4,
+ VDI6_ASFIFO_CTRL_BIT,
+ VDI6_ASFIFO_CTRL_WID);
+ }
break;
case 0xc0: /* viu2 */
vdin_mux = VDIN_MUX_VIU_2;
if (port != TVIN_PORT_VIU2)
wr_bits(offset, VDIN_ASFIFO_CTRL3, 0xe4,
VDI8_ASFIFO_CTRL_BIT, VDI8_ASFIFO_CTRL_WID);
- else
- wr_bits(offset, VDIN_ASFIFO_CTRL3, 0xf4,
- VDI8_ASFIFO_CTRL_BIT, VDI8_ASFIFO_CTRL_WID);
+ else {
+ if (/*is_meson_gxlx2_cpu() || */is_meson_g12b_cpu()
+ || is_meson_tl1_cpu() || is_meson_sm1_cpu() ||
+ is_meson_tm2_cpu())
+ wr_bits(offset, VDIN_ASFIFO_CTRL3, 0xd4,
+ VDI6_ASFIFO_CTRL_BIT,
+ VDI6_ASFIFO_CTRL_WID);
+ else
+ wr_bits(offset, VDIN_ASFIFO_CTRL3, 0xf4,
+ VDI6_ASFIFO_CTRL_BIT,
+ VDI6_ASFIFO_CTRL_WID);
+ }
break;
case 0x100:/* mipi in mybe need modify base on truth */
vdin_mux = VDIN_MUX_MIPI;
vdin_mux = VDIN_MUX_NULL;
break;
}
+
switch (input_cfmt) {
case TVIN_YVYU422:
vdin_data_bus_1 = VDIN_MAP_RCR;
vdin_data_bus_1 = VDIN_MAP_RCR;
vdin_data_bus_2 = VDIN_MAP_Y_G;
break;
+ case TVIN_RGB444:
+ /*RGB mapping*/
+ if (devp->set_canvas_manual == 1) {
+ vdin_data_bus_0 = VDIN_MAP_RCR;
+ vdin_data_bus_1 = VDIN_MAP_BPB;
+ vdin_data_bus_2 = VDIN_MAP_Y_G;
+ }
+ break;
default:
break;
}
VDIN_MATRIX_COEF_INDEX_BIT, VDIN_MATRIX_COEF_INDEX_WID);
wr(offset,
- VDIN_MATRIX_PRE_OFFSET0_1, matrix_tbl->pre_offset0_1);
+ VDIN_HDR2_MATRIXI_PRE_OFFSET0_1,
+ matrix_tbl->pre_offset0_1);
wr(offset,
- VDIN_MATRIX_PRE_OFFSET2, matrix_tbl->pre_offset2);
+ VDIN_HDR2_MATRIXI_PRE_OFFSET2, matrix_tbl->pre_offset2);
wr(offset, VDIN_HDR2_MATRIXI_COEF00_01, matrix_tbl->coef00_01);
wr(offset, VDIN_HDR2_MATRIXI_COEF02_10, matrix_tbl->coef02_10);
wr(offset, VDIN_HDR2_MATRIXI_COEF11_12, matrix_tbl->coef11_12);
*/
wr_bits(offset, VDIN_MATRIX_CTRL, 0,
VDIN_MATRIX1_EN_BIT, VDIN_MATRIX1_EN_WID);
- if (is_meson_g12a_cpu() || is_meson_g12b_cpu())
+ if (is_meson_g12a_cpu() || is_meson_g12b_cpu() ||
+ is_meson_sm1_cpu() || is_meson_tm2_cpu())
vdin_set_color_matrix0_g12a(devp->addr_offset,
devp->fmt_info_p,
devp->format_convert,
devp->prop.color_fmt_range,
devp->prop.vdin_hdr_Flag,
devp->color_range_mode);
- if (is_meson_g12a_cpu() || is_meson_g12b_cpu())
+ if (is_meson_g12a_cpu() || is_meson_g12b_cpu() ||
+ is_meson_sm1_cpu() || is_meson_tm2_cpu())
vdin_set_color_matrix0_g12a(devp->addr_offset,
devp->fmt_info_p,
devp->format_convert,
{
switch (id) {
case 0:
- if (is_meson_g12a_cpu() || is_meson_g12b_cpu())
+ if (is_meson_g12a_cpu() || is_meson_g12b_cpu() ||
+ is_meson_sm1_cpu() || is_meson_tm2_cpu())
vdin_set_color_matrix0_g12a(devp->addr_offset,
devp->fmt_info_p,
devp->format_convert,
devp->prop.color_fmt_range,
devp->prop.vdin_hdr_Flag,
devp->color_range_mode);
- if (is_meson_g12a_cpu() || is_meson_g12b_cpu())
+ if (is_meson_g12a_cpu() || is_meson_g12b_cpu() ||
+ is_meson_sm1_cpu() || is_meson_tm2_cpu())
vdin_set_color_matrix0_g12a(devp->addr_offset,
devp->fmt_info_p,
devp->format_convert,
/* use 11: form matrix1 din */
wr_bits(devp->addr_offset, VDIN_HIST_CTRL, 3,
HIST_HIST_DIN_SEL_BIT, HIST_HIST_DIN_SEL_WID);
+
+ /*for project get vdin1 hist*/
+ //if (devp->index == 1)
+ // wr_bits(devp->addr_offset, VDIN_WR_CTRL2, 1, 8, 1);
}
+
+
/* urgent ctr config */
/*if vdin fifo over up_th,will trigger increase
* urgent responds to vdin write,
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 (devp->set_canvas_manual == 1) {
+ /*not swap 2 64bits words in 128 words */
+ wr_bits(offset, VDIN_WR_CTRL, 0, 19, 1);
+ /*little endian*/
+ wr_bits(offset, VDIN_WR_H_START_END, 1, 30, 1);
+ } else
+ wr_bits(offset, VDIN_WR_CTRL, 1, 19, 1);
+
}
void vdin_set_wr_ctrl_vsync(struct vdin_dev_s *devp,
unsigned int offset, enum vdin_format_convert_e format_convert,
hconv_mode = 2;
swap_cbcr = 0;
}
-#ifdef CONFIG_AML_RDMA
+#ifdef CONFIG_AMLOGIC_MEDIA_RDMA
if (rdma_enable) {
rdma_write_reg_bits(devp->rdma_handle,
VDIN_WR_CTRL+devp->addr_offset,
void vdin_set_canvas_id(struct vdin_dev_s *devp, unsigned int rdma_enable,
unsigned int canvas_id)
{
-#ifdef CONFIG_AML_RDMA
+#ifdef CONFIG_AMLOGIC_MEDIA_RDMA
if (rdma_enable) {
- if (is_meson_g12a_cpu() || is_meson_g12b_cpu()) {
+ if (is_meson_g12a_cpu() || is_meson_g12b_cpu() ||
+ is_meson_sm1_cpu()) {
rdma_write_reg_bits(devp->rdma_handle,
VDIN_COM_CTRL0+devp->addr_offset, 1,
VDIN_FORCEGOLINE_EN_BIT, 1);
void vdin_set_chma_canvas_id(struct vdin_dev_s *devp, unsigned int rdma_enable,
unsigned int canvas_id)
{
-#ifdef CONFIG_AML_RDMA
+#ifdef CONFIG_AMLOGIC_MEDIA_RDMA
if (rdma_enable)
rdma_write_reg_bits(devp->rdma_handle,
VDIN_WR_CTRL2+devp->addr_offset,
devp->color_depth_mode, devp->source_bitdepth);
/* top sub-module */
- vdin_set_top(devp->addr_offset, devp->parm.port,
+ vdin_set_top(devp, 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);
-
}
static void vdin_delay_line(unsigned short num, unsigned int offset)
is_meson_gxtvbb_cpu() || is_meson_txl_cpu() ||
is_meson_txlx_cpu() || is_meson_tl1_cpu())
wr(offset, VDIN_LFIFO_CTRL, 0x00000f00);
+ else if (is_meson_tm2_cpu())
+ wr(offset, VDIN_LFIFO_CTRL, 0xc0020f00);
else
wr(offset, VDIN_LFIFO_CTRL, 0x00000780);
/* [15:14] clkgate.bbar = 0/(auto, off, on, on) */
{
return rd_bits(offset, VDIN_COM_STATUS0, 0, 1);
}
+
+bool vdin_check_vdi6_afifo_overflow(unsigned int offset)
+{
+ return rd_bits(offset, VDIN_COM_STATUS2, 15, 1);
+}
+
+void vdin_clear_vdi6_afifo_overflow_flg(unsigned int offset)
+{
+ wr_bits(offset, VDIN_ASFIFO_CTRL3, 0x1, 1, 1);
+ wr_bits(offset, VDIN_ASFIFO_CTRL3, 0x0, 1, 1);
+}
+
static unsigned int vdin_reset_flag;
inline int vdin_vsync_reset_mif(int index)
{
void vdin_dolby_addr_alloc(struct vdin_dev_s *devp, unsigned int size)
{
unsigned int index, alloc_size;
+ int highmem_flag;
alloc_size = dolby_size_byte*size;
devp->dv.dv_dma_vaddr = dma_alloc_coherent(&devp->this_pdev->dev,
return;
}
memset(devp->dv.dv_dma_vaddr, 0, alloc_size);
+ if (devp->cma_config_flag & 0x100)
+ highmem_flag = PageHighMem(phys_to_page(devp->vfmem_start[0]));
+ else
+ highmem_flag = PageHighMem(phys_to_page(devp->mem_start));
+
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));
+
+ if (highmem_flag == 0) {
+ 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));
+ } else {
+ if ((devp->cma_config_flag & 0x100)
+ && devp->cma_config_en)
+ devp->vfp->dv_buf_ori[index] =
+ vdin_vmap(devp->vfmem_start[index] +
+ devp->vfmem_size-dolby_size_byte,
+ dolby_size_byte);
+ else
+ devp->vfp->dv_buf_ori[index] =
+ vdin_vmap(devp->mem_start +
+ devp->mem_size -
+ dolby_size_byte *
+ (devp->canvas_max_num - index),
+ dolby_size_byte);
+ }
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]);
}
+ devp->dv.dv_mem_alloced = 1;
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;
+ int highmem_flag;
+ int index;
+
+ if (devp->dv.dv_mem_alloced == 0)
+ return;
alloc_size = dolby_size_byte*size;
if (devp->dv.dv_dma_vaddr)
dma_free_coherent(&devp->this_pdev->dev, alloc_size,
devp->dv.dv_dma_vaddr, devp->dv.dv_dma_paddr);
devp->dv.dv_dma_vaddr = NULL;
+
+ if (devp->cma_config_flag & 0x100)
+ highmem_flag = PageHighMem(phys_to_page(devp->vfmem_start[0]));
+ else
+ highmem_flag = PageHighMem(phys_to_page(devp->mem_start));
+
+ if (highmem_flag) {
+ for (index = 0; index < size; index++) {
+ if (devp->vfp->dv_buf_ori[index]) {
+ vdin_unmap_phyaddr(
+ devp->vfp->dv_buf_ori[index]);
+ devp->vfp->dv_buf_ori[index] = NULL;
+ }
+ }
+ }
+ devp->dv.dv_mem_alloced = 0;
}
-static void vdin_dolby_metadata_swap(char *buf)
+static void vdin_dolby_metadata_swap(struct vdin_dev_s *devp, char *buf)
{
char ext;
unsigned int i, j;
buf[i*16+15-j] = ext;
}
}
+
+ vdin_dma_flush(devp, buf, dolby_size_byte, DMA_TO_DEVICE);
}
#define swap32(num) \
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);
+ vdin_dma_flush(devp, p, 128, DMA_TO_DEVICE);
+ vdin_dolby_metadata_swap(devp, c);
} else {
wr(offset, VDIN_DOLBY_DSC_CTRL3, 0);
wr(offset, VDIN_DOLBY_DSC_CTRL2, 0xd180c0d5);
if ((i == 31) && (multimeta_flag == 0))
break;
}
+ vdin_dma_flush(devp, p, 128, DMA_TO_DEVICE);
}
+
meta_size = (c[3] << 8) | c[4];
crc = p[31];
crc_result = crc32(0, p, 124);
}
}
+unsigned int vdin0_afbce_debug_force;
int vdin_event_cb(int type, void *data, void *op_arg)
{
unsigned long flags;
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);
+ } else if (type & VFRAME_EVENT_RECEIVER_NEED_NO_COMP) {
+ struct vdin_dev_s *devp = vdin_get_dev(0);
+ unsigned int *cnt;
+
+ /* use for debug */
+ if (vdin0_afbce_debug_force)
+ return 0;
+
+ cnt = (unsigned int *)data;
+ if (*cnt) {
+ devp->afbce_mode = 0;
+ } else {
+ if (devp->afbce_valid)
+ devp->afbce_mode = 1;
+ }
+
+ if (vdin_ctl_dbg&(1<<1))
+ pr_info("%s(type 0x%x vdin%d) afbce_mode: %d, vpp_cnt: %d\n",
+ __func__, type, devp->index,
+ devp->afbce_mode, *cnt);
}
return 0;
}
}
format_convert = devp->format_convert;
if ((format_convert == VDIN_FORMAT_CONVERT_YUV_YUV444) ||
- (format_convert == VDIN_FORMAT_CONVERT_RGB_YUV444))
+ (format_convert == VDIN_FORMAT_CONVERT_RGB_YUV444)) {
type |= VIDTYPE_VIU_444;
- else if ((format_convert == VDIN_FORMAT_CONVERT_YUV_YUV422) ||
+ if (devp->afbce_mode_pre)
+ type |= VIDTYPE_COMB_MODE;
+ } 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_SINGLE_PLANE);
}
+
+ if (devp->afbce_valid)
+ type |= VIDTYPE_SUPPORT_COMPRESS;
+ if (devp->afbce_mode_pre) {
+ type |= VIDTYPE_COMPRESS;
+ type |= VIDTYPE_NO_DW;
+ type |= VIDTYPE_SCATTER;
+ if (devp->afbce_flag & VDIN_AFBCE_EN_LOOSY)
+ type |= VIDTYPE_COMPRESS_LOSS;
+ }
+
return type;
}
#ifndef __TVIN_VDIN_CTL_H
#define __TVIN_VDIN_CTL_H
-
+#include <linux/highmem.h>
+#include <linux/page-flags.h>
+#include <linux/vmalloc.h>
+#include <linux/dma-mapping.h>
+#include <linux/dma-contiguous.h>
#include "vdin_drv.h"
#define DV_SWAP_EN (1 << 0)
#endif
extern unsigned int game_mode;
+extern bool vdin_dbg_en;
/* ************************************************************************ */
/* ******** GLOBAL FUNCTION CLAIM ******** */
/* ************************************************************************ */
+extern u8 *vdin_vmap(ulong addr, u32 size);
+extern void vdin_unmap_phyaddr(u8 *vaddr);
+extern void vdin_dma_flush(struct vdin_dev_s *devp, void *vaddr,
+ int size, enum dma_data_direction dir);
+
extern void vdin_set_vframe_prop_info(struct vframe_s *vf,
struct vdin_dev_s *devp);
extern void LDIM_Initial_2(int pic_h, int pic_v, int BLK_Vnum,
extern void vdin_hw_disable(unsigned int offset);
extern unsigned int vdin_get_field_type(unsigned int offset);
extern int vdin_vsync_reset_mif(int index);
+extern bool vdin_check_vdi6_afifo_overflow(unsigned int offset);
+extern void vdin_clear_vdi6_afifo_overflow_flg(unsigned int offset);
extern void vdin_set_cutwin(struct vdin_dev_s *devp);
extern void vdin_set_decimation(struct vdin_dev_s *devp);
extern void vdin_fix_nonstd_vsync(struct vdin_dev_s *devp);
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,
+extern void vdin_set_top(struct vdin_dev_s *devp, unsigned int offset,
enum tvin_port_e port,
enum tvin_color_fmt_e input_cfmt, unsigned int h,
enum bt_path_e bt_path);
#include <linux/interrupt.h>
#include <linux/uaccess.h>
#include <linux/io.h>
+#include <linux/mm.h>
#include <linux/module.h>
#include <linux/amlogic/media/codec_mm/codec_mm.h>
/* Local Headers */
#include "vdin_drv.h"
#include "vdin_ctl.h"
#include "vdin_regs.h"
+#include "vdin_afbce.h"
/*2018-07-18 add debugfs*/
#include <linux/seq_file.h>
#include <linux/debugfs.h>
struct file *filp = NULL;
loff_t pos = 0;
void *buf = NULL;
- unsigned int i;
+ unsigned int i, j;
+ unsigned int span = 0, count = 0;
+ int highmem_flag;
+ unsigned long highaddr;
+ unsigned long phys;
mm_segment_t old_fs = get_fs();
set_fs(KERNEL_DS);
pr_info("%s:no cma alloc mem!!!\n", __func__);
return;
}
- if (buf_num < devp->canvas_max_num) {
+
+ if (buf_num >= devp->canvas_max_num) {
+ vfs_fsync(filp, 0);
+ filp_close(filp, NULL);
+ set_fs(old_fs);
+ pr_info("buf_num > canvas_max_num, vdin exit dump\n");
+ return;
+ }
+
+ if (devp->cma_config_flag & 0x100)
+ highmem_flag = PageHighMem(phys_to_page(devp->vfmem_start[0]));
+ else
+ highmem_flag = PageHighMem(phys_to_page(devp->mem_start));
+
+ if (highmem_flag == 0) {
+ pr_info("low mem area\n");
if (devp->cma_config_flag == 0x1)
buf = codec_mm_phys_to_virt(devp->mem_start +
devp->canvas_max_size*buf_num);
/*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);
+ } else {
+ pr_info("high mem area\n");
+ count = devp->canvas_h;
+ span = devp->canvas_active_w;
+
+ if (devp->cma_config_flag == 0x1)
+ phys = devp->mem_start + devp->canvas_max_size*buf_num;
+ else if (devp->cma_config_flag == 0x101)
+ phys = devp->vfmem_start[buf_num];
+ else if (devp->cma_config_flag == 0x100)
+ phys = devp->vfmem_start[buf_num];
+ else
+ phys = devp->mem_start + devp->canvas_max_size*buf_num;
+
+ for (j = 0; j < count; j++) {
+ highaddr = phys + j * devp->canvas_w;
+ buf = vdin_vmap(highaddr, span);
+ if (!buf) {
+ pr_info("vdin_vmap error\n");
+ return;
+ }
+
+ vdin_dma_flush(devp, buf, span, DMA_FROM_DEVICE);
+ vfs_write(filp, buf, span, &pos);
+ vdin_unmap_phyaddr(buf);
+ }
+ pr_info("high-mem write buffer %2d of %2u to %s.\n",
+ buf_num, devp->canvas_max_num, path);
}
vfs_fsync(filp, 0);
filp_close(filp, NULL);
{
struct file *filp = NULL;
loff_t pos = 0;
- loff_t i = 0, j = 0;
- unsigned int mem_size = 0;
+ loff_t mem_size = 0;
+ unsigned int i = 0, j = 0;
+ unsigned int span = 0;
+ unsigned int count = 0;
+ unsigned long highaddr;
+ unsigned long phys;
+ int highmem_flag;
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);
- mem_size = devp->canvas_active_w * devp->canvas_h;
+ mem_size = (loff_t)devp->canvas_active_w * devp->canvas_h;
for (i = 0; i < VDIN_CANVAS_MAX_CNT; i++)
vfbuf[i] = NULL;
if (IS_ERR(filp)) {
pr_info("%s:no cma alloc mem!!!\n", __func__);
return;
}
- for (i = 0; i < devp->canvas_max_num; i++) {
- pos = mem_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);
- /*only write active data*/
- for (j = 0; j < devp->canvas_h; j++) {
- if (devp->cma_config_flag & 0x100) {
- vfs_write(filp, vfbuf[i],
- devp->canvas_active_w, &pos);
- vfbuf[i] += devp->canvas_w;
- } else {
- vfs_write(filp, buf,
- devp->canvas_active_w, &pos);
- buf += devp->canvas_w;
+
+ if (devp->cma_config_flag & 0x100)
+ highmem_flag = PageHighMem(phys_to_page(devp->vfmem_start[0]));
+ else
+ highmem_flag = PageHighMem(phys_to_page(devp->mem_start));
+
+ if (highmem_flag == 0) {
+ /*low mem area*/
+ pr_info("low mem area\n");
+ for (i = 0; i < devp->canvas_max_num; i++) {
+ pos = mem_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);
+ /*only write active data*/
+ for (j = 0; j < devp->canvas_h; j++) {
+ if (devp->cma_config_flag & 0x100) {
+ vfs_write(filp, vfbuf[i],
+ devp->canvas_active_w, &pos);
+ vfbuf[i] += devp->canvas_w;
+ } else {
+ vfs_write(filp, buf,
+ devp->canvas_active_w, &pos);
+ buf += devp->canvas_w;
+ }
}
+ pr_info("write buffer %2d of %2u to %s.\n",
+ i, devp->canvas_max_num, path);
+ }
+ } else {
+ /*high mem area*/
+ pr_info("high mem area\n");
+ count = devp->canvas_h;
+ span = devp->canvas_active_w;
+
+ for (i = 0; i < devp->canvas_max_num; i++) {
+ pos = mem_size * i;
+ if (devp->cma_config_flag == 0x1) {
+ phys = devp->mem_start +
+ devp->canvas_max_size*i;
+ } else if (devp->cma_config_flag == 0x101)
+ phys = devp->vfmem_start[i];
+ else if (devp->cma_config_flag == 0x100)
+ phys = devp->vfmem_start[i];
+ else {
+ phys = devp->mem_start +
+ devp->canvas_max_size*i;
+ }
+
+ for (j = 0; j < count; j++) {
+ highaddr = phys + j * devp->canvas_w;
+ buf = vdin_vmap(highaddr, span);
+ if (!buf) {
+ pr_info("vdin_vmap error\n");
+ return;
+ }
+
+ vdin_dma_flush(devp, buf, span,
+ DMA_FROM_DEVICE);
+ vfs_write(filp, buf, span, &pos);
+ vdin_unmap_phyaddr(buf);
+ }
+ pr_info("high-mem write buffer %2d of %2u to %s.\n",
+ i, devp->canvas_max_num, path);
}
- pr_info("write buffer %lld of %2u to %s.\n",
- i, devp->canvas_max_num, path);
}
vfs_fsync(filp, 0);
filp_close(filp, NULL);
void *buf_head = NULL;
void *buf_table = NULL;
void *buf_body = NULL;
+ unsigned long highaddr;
+ unsigned long phys;
+ int highmem_flag = 0;
+ unsigned int span = 0;
+ unsigned int remain = 0;
+ unsigned int count = 0;
+ unsigned int j = 0;
+ void *vbuf = NULL;
unsigned char buff[100];
mm_segment_t old_fs = get_fs();
return;
}
- if (devp->cma_config_flag == 0x101) {
- buf_head = codec_mm_phys_to_virt(
- devp->afbce_info->fm_head_paddr[buf_num]);
- buf_table = codec_mm_phys_to_virt(
- devp->afbce_info->fm_table_paddr[buf_num]);
- buf_body = codec_mm_phys_to_virt(
- devp->afbce_info->fm_body_paddr[buf_num]);
-
- pr_info(".head_paddr=0x%lx,table_paddr=0x%lx,body_paddr=0x%lx\n",
+ highmem_flag = PageHighMem(
+ phys_to_page(devp->afbce_info->fm_body_paddr[0]));
+
+ if (highmem_flag == 0) {
+ /*low mem area*/
+ pr_info("low mem area\n");
+ if (devp->cma_config_flag == 0x101) {
+ buf_head = codec_mm_phys_to_virt(
+ devp->afbce_info->fm_head_paddr[buf_num]);
+ buf_table = codec_mm_phys_to_virt(
+ devp->afbce_info->fm_table_paddr[buf_num]);
+ buf_body = codec_mm_phys_to_virt(
+ devp->afbce_info->fm_body_paddr[buf_num]);
+
+ pr_info(".head_paddr=0x%lx,table_paddr=0x%lx,body_paddr=0x%lx\n",
+ devp->afbce_info->fm_head_paddr[buf_num],
+ (devp->afbce_info->fm_table_paddr[buf_num]),
+ devp->afbce_info->fm_body_paddr[buf_num]);
+ } else if (devp->cma_config_flag == 0) {
+ buf_head = phys_to_virt(
+ devp->afbce_info->fm_head_paddr[buf_num]);
+ buf_table = phys_to_virt(
+ devp->afbce_info->fm_table_paddr[buf_num]);
+ buf_body = phys_to_virt(
+ devp->afbce_info->fm_body_paddr[buf_num]);
+
+ pr_info("head_paddr=0x%lx,table_paddr=0x%lx,body_paddr=0x%lx\n",
+ devp->afbce_info->fm_head_paddr[buf_num],
+ (devp->afbce_info->fm_table_paddr[buf_num]),
+ devp->afbce_info->fm_body_paddr[buf_num]);
+ }
+ } else {
+ /*high mem area*/
+ pr_info("high mem area\n");
+ buf_head = vdin_vmap(
devp->afbce_info->fm_head_paddr[buf_num],
- (devp->afbce_info->fm_table_paddr[buf_num]),
- devp->afbce_info->fm_body_paddr[buf_num]);
- } else if (devp->cma_config_flag == 0) {
- buf_head = phys_to_virt(
- devp->afbce_info->fm_head_paddr[buf_num]);
- buf_table = phys_to_virt(
- devp->afbce_info->fm_table_paddr[buf_num]);
- buf_body = phys_to_virt(
- devp->afbce_info->fm_body_paddr[buf_num]);
+ devp->afbce_info->frame_head_size);
+
+ buf_table = vdin_vmap(
+ devp->afbce_info->fm_table_paddr[buf_num],
+ devp->afbce_info->frame_table_size);
- pr_info("head_paddr=0x%lx,table_paddr=0x%lx,body_paddr=0x%lx\n",
+ pr_info(".head_paddr=0x%lx,table_paddr=0x%lx,body_paddr=0x%lx\n",
devp->afbce_info->fm_head_paddr[buf_num],
(devp->afbce_info->fm_table_paddr[buf_num]),
devp->afbce_info->fm_body_paddr[buf_num]);
return;
}
+ vdin_dma_flush(devp, buf_head,
+ devp->afbce_info->frame_head_size,
+ DMA_FROM_DEVICE);
vfs_write(filp, buf_head, devp->afbce_info->frame_head_size, &pos);
+ if (highmem_flag)
+ vdin_unmap_phyaddr(buf_head);
pr_info("write buffer %2d of %2u head to %s.\n",
buf_num, devp->canvas_max_num, buff);
vfs_fsync(filp, 0);
pr_info("create %s table error.\n", buff);
return;
}
+ vdin_dma_flush(devp, buf_table,
+ devp->afbce_info->frame_table_size,
+ DMA_FROM_DEVICE);
vfs_write(filp, buf_table, devp->afbce_info->frame_table_size, &pos);
+ if (highmem_flag)
+ vdin_unmap_phyaddr(buf_table);
pr_info("write buffer %2d of %2u table to %s.\n",
buf_num, devp->canvas_max_num, buff);
vfs_fsync(filp, 0);
pr_info("create %s body error.\n", buff);
return;
}
- vfs_write(filp, buf_body, devp->afbce_info->frame_body_size, &pos);
- pr_info("write buffer %2d of %2u body to %s.\n",
- buf_num, devp->canvas_max_num, buff);
- vfs_fsync(filp, 0);
- filp_close(filp, NULL);
-
- set_fs(old_fs);
-}
-
-static void vdin_dump_afbce_mem(char *path, struct vdin_dev_s *devp)
-{
- struct file *filp = NULL;
- loff_t pos = 0;
- void *buf_head = NULL;
- void *buf_table = NULL;
- void *buf_body = NULL;
- unsigned char buff[100];
- unsigned int i;
- mm_segment_t old_fs = get_fs();
-
- if ((devp->cma_config_flag & 0x1) &&
- (devp->cma_mem_alloc == 0)) {
- pr_info("%s:no cma alloc mem!!!\n", __func__);
- return;
- }
-
- if (devp->cma_config_flag == 0x101) {
- buf_head = codec_mm_phys_to_virt(
- devp->afbce_info->head_paddr);
- buf_table = codec_mm_phys_to_virt(
- devp->afbce_info->table_paddr);
- buf_body = codec_mm_phys_to_virt(
- devp->afbce_info->fm_body_paddr[0]);
-
- pr_info(".head_paddr=0x%lx,table_paddr=0x%lx,body_paddr=0x%lx\n",
- devp->afbce_info->head_paddr,
- (devp->afbce_info->table_paddr),
- devp->afbce_info->fm_body_paddr[0]);
- } else if (devp->cma_config_flag == 0) {
- buf_head = phys_to_virt(
- devp->afbce_info->head_paddr);
- buf_table = phys_to_virt(
- devp->afbce_info->table_paddr);
- buf_body = phys_to_virt(
- devp->afbce_info->fm_body_paddr[0]);
-
- pr_info("head_paddr=0x%lx,table_paddr=0x%lx,body_paddr=0x%lx\n",
- devp->afbce_info->head_paddr,
- (devp->afbce_info->table_paddr),
- devp->afbce_info->fm_body_paddr[0]);
- }
-
- set_fs(KERNEL_DS);
-
- /* write header bin start */
- strcpy(buff, path);
- strcat(buff, "_header.bin");
- filp = filp_open(buff, O_RDWR|O_CREAT, 0666);
- if (IS_ERR(filp)) {
- pr_info("create %s header error.\n", buff);
- return;
- }
-
- for (i = 0; i < devp->vfmem_max_cnt; i++) {
- vfs_write(filp, buf_head,
- devp->afbce_info->frame_head_size, &pos);
- buf_head += devp->afbce_info->frame_head_size;
- pr_info("write buffer %2d(0x%x bytes) of %2u head to %s.\n",
- i, devp->afbce_info->frame_head_size,
- devp->canvas_max_num, buff);
- }
- vfs_fsync(filp, 0);
- filp_close(filp, NULL);
- /* write header bin end */
-
- /* write table bin start */
- pos = 0;
- strcpy(buff, path);
- strcat(buff, "_table.bin");
- filp = filp_open(buff, O_RDWR|O_CREAT, 0666);
- if (IS_ERR(filp)) {
- pr_info("create %s table error.\n", buff);
- return;
- }
+ if (highmem_flag == 0) {
+ vfs_write(filp, buf_body,
+ devp->afbce_info->frame_body_size, &pos);
+ } else {
+ span = SZ_1M;
+ count = devp->afbce_info->frame_body_size/PAGE_ALIGN(span);
+ remain = devp->afbce_info->frame_body_size%PAGE_ALIGN(span);
+ phys = devp->afbce_info->fm_body_paddr[buf_num];
+
+ for (j = 0; j < count; j++) {
+ highaddr = phys + j * span;
+ vbuf = vdin_vmap(highaddr, span);
+ if (!vbuf) {
+ pr_info("vdin_vmap error\n");
+ return;
+ }
- for (i = 0; i < devp->vfmem_max_cnt; i++) {
- vfs_write(filp, buf_table,
- devp->afbce_info->frame_table_size, &pos);
- buf_table += devp->afbce_info->frame_table_size;
- pr_info("write buffer %2d(0x%x bytes) of %2u table to %s.\n",
- i, devp->afbce_info->frame_table_size,
- devp->canvas_max_num, buff);
- }
- vfs_fsync(filp, 0);
- filp_close(filp, NULL);
- /* write table bin end */
+ vdin_dma_flush(devp, vbuf, span, DMA_FROM_DEVICE);
+ vfs_write(filp, vbuf, span, &pos);
+ vdin_unmap_phyaddr(vbuf);
+ }
- /* write body bin start */
- pos = 0;
- strcpy(buff, path);
- strcat(buff, "_body.bin");
- filp = filp_open(buff, O_RDWR|O_CREAT, 0666);
- if (IS_ERR(filp)) {
- pr_info("create %s body error.\n", buff);
- return;
- }
+ if (remain) {
+ span = devp->afbce_info->frame_body_size - remain;
+ highaddr = phys + span;
+ vbuf = vdin_vmap(highaddr, remain);
+ if (!vbuf) {
+ pr_info("vdin_vmap1 error\n");
+ return;
+ }
- for (i = 0; i < devp->vfmem_max_cnt; i++) {
- vfs_write(filp, buf_body,
- devp->afbce_info->frame_body_size, &pos);
- buf_body += devp->afbce_info->frame_body_size;
- pr_info("write buffer %2d(0x%x bytes) of %2u body to %s.\n",
- i, devp->afbce_info->frame_body_size,
- devp->canvas_max_num, buff);
+ vdin_dma_flush(devp, vbuf, remain, DMA_FROM_DEVICE);
+ vfs_write(filp, vbuf, remain, &pos);
+ vdin_unmap_phyaddr(vbuf);
+ }
}
+ pr_info("write buffer %2d of %2u body to %s.\n",
+ buf_num, devp->canvas_max_num, buff);
vfs_fsync(filp, 0);
filp_close(filp, NULL);
- /* write body bin end */
set_fs(old_fs);
}
pr_info("color_depth_support:0x%x\n", devp->color_depth_support);
pr_info("cma_flag:0x%x\n", devp->cma_config_flag);
pr_info("auto_cutwindow_en:%d\n", devp->auto_cutwindow_en);
+ pr_info("cutwindow_cfg:%d\n", devp->cutwindow_cfg);
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("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("game_mode : %d\n", devp->game_mode);
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->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("afbce_flag: 0x%x\n", devp->afbce_flag);
+ pr_info("afbce_mode: %d\n", devp->afbce_mode);
if (devp->afbce_mode == 1) {
for (i = 0; i < devp->vfmem_max_cnt; i++) {
pr_info("head(%d) addr:0x%lx, size:0x%x\n",
devp->afbce_info->frame_body_size);
}
}
-
pr_info("Vdin driver version : %s\n", VDIN_VER);
}
-/*2018-07-18 add debugfs*/
-struct vdin_dev_s *vdin_get_dev(unsigned int index);
-
/*same as vdin_dump_state*/
static int seq_file_vdin_state_show(struct seq_file *seq, void *v)
{
}
}
+/*type: 1:nv21 2:yuv422 3:yuv444*/
+static void vdin_write_afbce_mem(struct vdin_dev_s *devp, char *type,
+ char *path)
+{
+ char md_path_head[100], md_path_body[100];
+ unsigned int i, j;
+ int highmem_flag = 0;
+ unsigned int size = 0;
+ unsigned int span = 0;
+ unsigned int remain = 0;
+ unsigned int count = 0;
+ unsigned long highaddr;
+ unsigned long phys;
+ long val;
+ struct file *filp = NULL;
+ loff_t pos = 0;
+ mm_segment_t old_fs;
+ void *head_dts = NULL;
+ void *body_dts = NULL;
+ void *vbuf = NULL;
+
+ if (kstrtol(type, 10, &val) < 0)
+ return;
+ if (!path)
+ 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;
+ }
+ }
+
+ sprintf(md_path_head, "%s_1header.bin", path);
+ sprintf(md_path_body, "%s_1body.bin", path);
+
+ i = devp->curr_wr_vfe->af_num;
+ devp->curr_wr_vfe->vf.type = VIDTYPE_VIU_SINGLE_PLANE |
+ VIDTYPE_VIU_FIELD | VIDTYPE_COMPRESS | VIDTYPE_SCATTER;
+ switch (val) {
+ case 1:
+ devp->curr_wr_vfe->vf.type |= VIDTYPE_VIU_NV21;
+ break;
+ case 2:
+ devp->curr_wr_vfe->vf.type |= VIDTYPE_VIU_422;
+ break;
+ case 3:
+ devp->curr_wr_vfe->vf.type |= VIDTYPE_VIU_444;
+ break;
+ default:
+ devp->curr_wr_vfe->vf.type |= VIDTYPE_VIU_422;
+ break;
+ }
+
+ devp->curr_wr_vfe->vf.compHeadAddr = devp->afbce_info->fm_head_paddr[i];
+ devp->curr_wr_vfe->vf.compBodyAddr = devp->afbce_info->fm_body_paddr[i];
+
+ highmem_flag = PageHighMem(
+ phys_to_page(devp->afbce_info->fm_body_paddr[0]));
+ if (highmem_flag == 0) {
+ pr_info("low mem area\n");
+ head_dts = codec_mm_phys_to_virt(
+ devp->afbce_info->fm_head_paddr[i]);
+ } else {
+ pr_info("high mem area\n");
+ head_dts = vdin_vmap(
+ devp->afbce_info->fm_head_paddr[i],
+ devp->afbce_info->frame_head_size);
+ }
+
+ old_fs = get_fs();
+ set_fs(KERNEL_DS);
+ pr_info("head bin file path = %s\n", md_path_head);
+ filp = filp_open(md_path_head, O_RDONLY, 0);
+ if (IS_ERR(filp)) {
+ pr_info("read %s error.\n", md_path_head);
+ return;
+ }
+
+ size = vfs_read(filp, head_dts,
+ devp->afbce_info->frame_head_size, &pos);
+ if (highmem_flag)
+ vdin_unmap_phyaddr(head_dts);
+
+ vfs_fsync(filp, 0);
+ filp_close(filp, NULL);
+ set_fs(old_fs);
+
+ pos = 0;
+ old_fs = get_fs();
+ set_fs(KERNEL_DS);
+ pr_info("body bin file path = %s\n", md_path_body);
+ filp = filp_open(md_path_body, O_RDONLY, 0);
+ if (IS_ERR(filp)) {
+ pr_info("read %s error.\n", md_path_body);
+ return;
+ }
+
+ if (highmem_flag == 0) {
+ body_dts = codec_mm_phys_to_virt(
+ devp->afbce_info->fm_body_paddr[i]);
+
+ size = vfs_read(filp, body_dts,
+ devp->afbce_info->frame_body_size, &pos);
+ } else {
+ span = SZ_1M;
+ count = devp->afbce_info->frame_body_size/PAGE_ALIGN(span);
+ remain = devp->afbce_info->frame_body_size%PAGE_ALIGN(span);
+ phys = devp->afbce_info->fm_body_paddr[i];
+
+
+ for (j = 0; j < count; j++) {
+ highaddr = phys + j * span;
+ vbuf = vdin_vmap(highaddr, span);
+ if (!vbuf) {
+ pr_info("vdin_vmap error\n");
+ return;
+ }
+ vfs_read(filp, vbuf, span, &pos);
+ vdin_unmap_phyaddr(vbuf);
+ }
+ }
+
+ vfs_fsync(filp, 0);
+ filp_close(filp, 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);
+}
+
static void vdin_write_mem(
struct vdin_dev_s *devp, char *type,
char *path, char *md_path)
mm_segment_t old_fs;
void *dts = NULL;
long val;
- int index;
+ int index, j, span;
+ int highmem_flag, count;
unsigned long addr;
+ unsigned long highaddr;
struct vf_pool *p = devp->vfp;
/* vtype = simple_strtol(type, NULL, 10); */
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, 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 (devp->cma_config_flag & 0x100)
+ highmem_flag = PageHighMem(phys_to_page(devp->vfmem_start[0]));
+ else
+ highmem_flag = PageHighMem(phys_to_page(devp->mem_start));
+
+ if (highmem_flag == 0) {
+ pr_info("low mem area\n");
+ dts = phys_to_virt(addr);
+ for (j = 0; j < devp->canvas_h; j++) {
+ vfs_read(filp, dts+(devp->canvas_w*j),
+ devp->canvas_active_w, &pos);
+ }
+ vfs_fsync(filp, 0);
+ iounmap(dts);
+ filp_close(filp, NULL);
+ set_fs(old_fs);
+ } else {
+ pr_info("high mem area\n");
+ count = devp->canvas_h;
+ span = devp->canvas_active_w;
+ for (j = 0; j < count; j++) {
+ highaddr = addr + j * devp->canvas_w;
+ dts = vdin_vmap(highaddr, span);
+ if (!dts) {
+ pr_info("vdin_vmap error\n");
+ return;
+ }
+ vfs_read(filp, dts, span, &pos);
+ vdin_dma_flush(devp, dts, span, DMA_TO_DEVICE);
+ vdin_unmap_phyaddr(dts);
+ }
+ vfs_fsync(filp, 0);
+ filp_close(filp, NULL);
+ set_fs(old_fs);
+ }
+
if (vtype == 8) {
old_fs = get_fs();
set_fs(KERNEL_DS);
u8 *c = devp->vfp->dv_buf_ori[index];
pos = 0;
- size = vfs_read(md_flip,
+ size = (unsigned int)vfs_read(md_flip,
devp->vfp->dv_buf_ori[index],
4096, &pos);
p->dv_buf_size[index] = size;
} else if (!strcmp(parm[1], "video")) {
param.port = TVIN_PORT_VIU1_VIDEO;
pr_info(" port is TVIN_PORT_VIU_VIDEO\n");
+ } else if (!strcmp(parm[1], "viu_wb0_vpp")) {
+ param.port = TVIN_PORT_VIU1_WB0_VPP;
+ pr_info(" port is TVIN_PORT_VIU1_WB0_VPP\n");
} else if (!strcmp(parm[1], "viu_wb0_vd1")) {
param.port = TVIN_PORT_VIU1_WB0_VD1;
pr_info(" port is TVIN_PORT_VIU_WB0_VD1\n");
} else if (!strcmp(parm[1], "viu_wb0_post_blend")) {
param.port = TVIN_PORT_VIU1_WB0_POST_BLEND;
pr_info(" port is TVIN_PORT_VIU_WB0_POST_BLEND\n");
+ } else if (!strcmp(parm[1], "viu_wb1_vpp")) {
+ param.port = TVIN_PORT_VIU1_WB1_VPP;
+ pr_info(" port is TVIN_PORT_VIU1_WB1_VPP\n");
} else if (!strcmp(parm[1], "viu_wb1_vd1")) {
param.port = TVIN_PORT_VIU1_WB1_VD1;
pr_info(" port is TVIN_PORT_VIU_WB1_VD1\n");
} else if (!strcmp(parm[1], "video2")) {
param.port = TVIN_PORT_VIU2_VIDEO;
pr_info(" port is TVIN_PORT_VIU_VIDEO\n");
+ } else if (!strcmp(parm[1], "viu2_wb0_vpp")) {
+ param.port = TVIN_PORT_VIU2_WB0_VPP;
+ pr_info(" port is TVIN_PORT_VIU2_WB0_VPP\n");
} else if (!strcmp(parm[1], "viu2_wb0_vd1")) {
param.port = TVIN_PORT_VIU2_WB0_VD1;
pr_info(" port is TVIN_PORT_VIU_WB0_VD1\n");
} else if (!strcmp(parm[1], "viu2_wb0_post_blend")) {
param.port = TVIN_PORT_VIU2_WB0_POST_BLEND;
pr_info(" port is TVIN_PORT_VIU_WB0_POST_BLEND\n");
+ } else if (!strcmp(parm[1], "viu2_wb1_vpp")) {
+ param.port = TVIN_PORT_VIU2_WB1_VPP;
+ pr_info(" port is TVIN_PORT_VIU2_WB1_VPP\n");
} else if (!strcmp(parm[1], "viu2_wb1_vd1")) {
param.port = TVIN_PORT_VIU2_WB1_VD1;
pr_info(" port is TVIN_PORT_VIU_WB1_VD1\n");
#endif
} else if (!strcmp(parm[0], "force_recycle")) {
devp->flags |= VDIN_FLAG_FORCE_RECYCLE;
+ } else if (!strcmp(parm[0], "read_pic_afbce")) {
+ if (parm[1] && parm[2])
+ vdin_write_afbce_mem(devp, parm[1], parm[2]);
+ else
+ pr_err("miss parameters.\n");
} else if (!strcmp(parm[0], "read_pic")) {
if (parm[1] && parm[2])
vdin_write_mem(devp, parm[1], parm[2], parm[3]);
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++)
- pr_info("[0x%x]reg:0x%x-0x%x\n",
- (0xd0100000 + ((reg+offset)<<2)),
- (reg+offset), rd(offset, reg));
- pr_info("vdin%d regs end----\n", devp->index);
+ for (reg = VDIN_SCALE_COEF_IDX; reg <= 0x1273; reg++) {
+ pr_info("0x%04x = 0x%08x\n",
+ (reg+offset), rd(offset, reg));
+ }
+ pr_info("vdin%d regs end----\n", devp->index);
+ if (devp->afbce_flag & VDIN_AFBCE_EN) {
+ pr_info("vdin%d afbce regs start----\n", devp->index);
+ for (reg = AFBCE_ENABLE; reg <= AFBCE_MMU_RMIF_RO_STAT;
+ reg++) {
+ pr_info("0x%04x = 0x%08x\n",
+ (reg), R_VCBUS(reg));
+ }
+ pr_info("vdin%d afbce regs end----\n", devp->index);
+ }
+ reg = VDIN_MISC_CTRL;
+ pr_info("0x%04x = 0x%08x\n", (reg), R_VCBUS(reg));
+ pr_info("\n");
} else if (!strcmp(parm[0], "rgb_xy")) {
unsigned int x = 0, y = 0;
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")) {
+ } else if (!strcmp(parm[0], "irq_cnt"))
+ pr_info("vdin(%d) irq_cnt: %d\n", devp->index, devp->irq_cnt);
+ 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)) {
buf_num = val;
vdin_dump_one_afbce_mem(parm[1], devp, buf_num);
} else if (parm[1] != NULL) {
- vdin_dump_afbce_mem(parm[1], devp);
+ vdin_dump_one_afbce_mem(parm[1], devp, 0);
}
- } else {
+ } else if (!strcmp(parm[0], "skip_frame_debug")) {
+ if (parm[1] != NULL) {
+ if (kstrtouint(parm[1], 10, &skip_frame_debug) == 0)
+ pr_info("set skip_frame_debug: %d\n",
+ skip_frame_debug);
+ } else {
+ pr_info("skip_frame_debug: %d\n", skip_frame_debug);
+ }
+ } else if (!strcmp(parm[0], "max_recycle_cnt")) {
+ if (parm[1] != NULL) {
+ if (kstrtouint(parm[1], 10,
+ &max_recycle_frame_cnt) == 0)
+ pr_info("set max_recycle_frame_cnt: %d\n",
+ max_recycle_frame_cnt);
+ } else {
+ pr_info("max_recycle_frame_cnt: %d\n",
+ max_recycle_frame_cnt);
+ }
+ } else if (!strcmp(parm[0], "max_ignore_cnt")) {
+ if (parm[1] != NULL) {
+ if (kstrtouint(parm[1], 10, &max_ignore_frame_cnt) == 0)
+ pr_info("set max_ignore_frame_cnt: %d\n",
+ max_ignore_frame_cnt);
+ } else {
+ pr_info("max_ignore_frame_cnt: %d\n",
+ max_ignore_frame_cnt);
+ }
+ } else if (!strcmp(parm[0], "afbce_flag")) {
+ if (parm[1] != NULL) {
+ if (kstrtouint(parm[1], 16, &devp->afbce_flag) == 0) {
+ pr_info("set vdin_afbce_flag: 0x%x\n",
+ devp->afbce_flag);
+ }
+ } else {
+ pr_info("vdin_afbce_flag: 0x%x\n", devp->afbce_flag);
+ }
+ } else if (!strcmp(parm[0], "afbce_mode")) {
+ unsigned int mode = 0, flag = 0;
+
+ if (parm[2] != NULL) {
+ if ((kstrtouint(parm[1], 10, &mode) == 0) &&
+ (kstrtouint(parm[2], 10, &flag) == 0)) {
+ vdin0_afbce_debug_force = flag;
+ if (devp->afbce_flag & VDIN_AFBCE_EN)
+ devp->afbce_mode = mode;
+ else
+ devp->afbce_mode = 0;
+ if (vdin0_afbce_debug_force) {
+ pr_info("set force vdin_afbce_mode: %d\n",
+ devp->afbce_mode);
+ } else {
+ pr_info("set vdin_afbce_mode: %d\n",
+ devp->afbce_mode);
+ }
+ }
+ } else if (parm[1] != NULL) {
+ if (kstrtouint(parm[1], 10, &mode) == 0) {
+ if (devp->afbce_flag & VDIN_AFBCE_EN)
+ devp->afbce_mode = mode;
+ else
+ devp->afbce_mode = 0;
+ pr_info("set vdin_afbce_mode: %d\n",
+ devp->afbce_mode);
+ }
+ } else {
+ pr_info("vdin_afbce_mode: %d\n", devp->afbce_mode);
+ }
+ } else if (!strcmp(parm[0], "vdi6_afifo_overflow"))
+ pr_info("%d\n",
+ vdin_check_vdi6_afifo_overflow(devp->addr_offset));
+ else if (!strcmp(parm[0], "vdi6_afifo_clear"))
+ vdin_clear_vdi6_afifo_overflow_flg(devp->addr_offset);
+ else
pr_info("unknown command\n");
- }
+
kfree(buf_orig);
return len;
}
#include <linux/of_reserved_mem.h>
#include <linux/of_irq.h>
#include <linux/cma.h>
+#include <linux/dma-buf.h>
+#include <linux/scatterlist.h>
+#include <linux/mm_types.h>
#include <linux/amlogic/media/codec_mm/codec_mm.h>
#include <linux/dma-contiguous.h>
#include <linux/amlogic/iomap.h>
+#include <linux/fdtable.h>
/* Amlogic Headers */
#include <linux/amlogic/media/vpu/vpu.h>
#include <linux/amlogic/media/vfm/vframe.h>
static struct vdin_dev_s *vdin_devp[VDIN_MAX_DEVS];
static unsigned long mem_start, mem_end;
static unsigned int use_reserved_mem;
+static unsigned int pr_times;
+
+struct vdin_set_canvas_addr_s vdin_set_canvas_addr[VDIN_CANVAS_MAX_CNT];
+static DECLARE_WAIT_QUEUE_HEAD(vframe_waitq);
/*
* canvas_config_mode
* 0: canvas_config in driver probe
*/
static int canvas_config_mode = 2;
static bool work_mode_simple;
-static int max_ignore_frames = 2;
-static int ignore_frames;
+static int phase_lock_flag;
+/*game_mode_switch_frames:min num is 5 by 1080p60hz input test*/
+static int game_mode_switch_frames = 10;
+static int game_mode_phlock_switch_frames = 60;
static unsigned int dv_work_delby;
+
+static struct vf_entry *vfe_drop_force;
+
+unsigned int max_recycle_frame_cnt;
+unsigned int max_ignore_frame_cnt = 2;
+unsigned int skip_frame_debug;
+
/* viu isr select:
* enable viu_hw_irq for the bandwidth is enough on gxbb/gxtvbb and laters ic
*/
static bool viu_hw_irq = 1;
+static bool de_fmt_flag;
#ifdef DEBUG_SUPPORT
module_param(canvas_config_mode, int, 0664);
module_param(work_mode_simple, bool, 0664);
MODULE_PARM_DESC(work_mode_simple, "enable/disable simple work mode");
-module_param(max_ignore_frames, int, 0664);
-MODULE_PARM_DESC(max_ignore_frames, "ignore first <n> frames");
-
-module_param(ignore_frames, int, 0664);
-MODULE_PARM_DESC(ignore_frames, "ignore first <n> frames");
+module_param(viu_hw_irq, bool, 0664);
+MODULE_PARM_DESC(viu_hw_irq, "viu_hw_irq");
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");
+module_param(game_mode_switch_frames, int, 0664);
+MODULE_PARM_DESC(game_mode_switch_frames, "game mode switch <n> frames");
+
+module_param(game_mode_phlock_switch_frames, int, 0664);
+MODULE_PARM_DESC(game_mode_phlock_switch_frames,
+ "game mode switch <n> frames for phase_lock");
#endif
-static bool vdin_dbg_en;
+bool vdin_dbg_en;
module_param(vdin_dbg_en, bool, 0664);
MODULE_PARM_DESC(vdin_dbg_en, "enable/disable vdin debug information");
module_param(vdin_drop_cnt, uint, 0664);
MODULE_PARM_DESC(vdin_drop_cnt, "vdin_drop_cnt");
+struct vdin_hist_s vdin1_hist;
+struct vdin_v4l2_param_s vdin_v4l2_param;
static int irq_max_count;
(devp->parm.port != TVIN_PORT_CVBS3)) {
if (devp->h_active > 720 && ((devp->parm.info.fps == 50) ||
(devp->parm.info.fps == 60)))
- devp->game_mode = 3;
+ if (is_meson_tl1_cpu() || is_meson_tm2_cpu()) {
+ devp->game_mode = (VDIN_GAME_MODE_0 |
+ VDIN_GAME_MODE_1 |
+ VDIN_GAME_MODE_SWITCH_EN);
+ } else {
+ devp->game_mode = (VDIN_GAME_MODE_0 |
+ VDIN_GAME_MODE_1);
+ }
else
- devp->game_mode = 1;
- } else
+ devp->game_mode = VDIN_GAME_MODE_0;
+ } else if (game_mode == 2)/*for debug force game mode*/
+ devp->game_mode = (VDIN_GAME_MODE_0 | VDIN_GAME_MODE_1);
+ else if (game_mode == 3)/*for debug force game mode*/
+ devp->game_mode = (VDIN_GAME_MODE_0 | VDIN_GAME_MODE_2);
+ else if (game_mode == 4)/*for debug force game mode*/
+ devp->game_mode = VDIN_GAME_MODE_0;
+ else if (game_mode == 5)/*for debug force game mode*/
+ devp->game_mode = (VDIN_GAME_MODE_0 | VDIN_GAME_MODE_1 |
+ VDIN_GAME_MODE_SWITCH_EN);
+ else
devp->game_mode = 0;
+
+ pr_info("%s: game_mode flag=%d, game_mode=%d\n",
+ __func__, game_mode, devp->game_mode);
}
/*
*based on the bellow parameters:
#ifndef VDIN_DYNAMIC_DURATION
vf->duration = devp->fmt_info_p->duration;
#endif
+ /* init canvas config */
/*if output fmt is nv21 or nv12 ,
* use the two continuous canvas for one field
*/
(devp->prop.dest_cfmt == TVIN_NV21)) {
chromaid =
(vdin_canvas_ids[index][(vf->index<<1)+1])<<8;
- addr =
- vdin_canvas_ids[index][vf->index<<1] |
- chromaid;
- } else
+ addr = vdin_canvas_ids[index][vf->index<<1] | chromaid;
+ } else {
addr = vdin_canvas_ids[index][vf->index];
-
+ }
vf->canvas0Addr = vf->canvas1Addr = addr;
+ /* init afbce config */
+ if (devp->afbce_info) {
+ vf->compHeadAddr = devp->afbce_info->fm_head_paddr[i];
+ vf->compBodyAddr = devp->afbce_info->fm_body_paddr[i];
+ vf->compWidth = devp->h_active;
+ vf->compHeight = devp->v_active;
+ }
+
/* set source type & mode */
vdin_set_source_type(devp, vf);
vdin_set_source_mode(devp, vf);
}
}
-#ifdef CONFIG_AML_RDMA
+#ifdef CONFIG_AMLOGIC_MEDIA_RDMA
static void vdin_rdma_irq(void *arg)
{
struct vdin_dev_s *devp = arg;
return;
}
-static struct rdma_op_s vdin_rdma_op = {
- vdin_rdma_irq,
- NULL
-};
+static struct rdma_op_s vdin_rdma_op[VDIN_MAX_DEVS];
#endif
+static void vdin_afbce_mode_init(struct vdin_dev_s *devp)
+{
+ /* afbce_valid means can switch into afbce mode */
+ devp->afbce_valid = 0;
+ if (devp->afbce_flag & VDIN_AFBCE_EN) {
+ if ((devp->h_active > 1920) && (devp->v_active > 1080)) {
+ if (devp->afbce_flag & VDIN_AFBCE_EN_4K)
+ devp->afbce_valid = 1;
+ } else if ((devp->h_active > 1280) && (devp->v_active > 720)) {
+ if (devp->afbce_flag & VDIN_AFBCE_EN_1080P)
+ devp->afbce_valid = 1;
+ } else if ((devp->h_active > 720) && (devp->v_active > 576)) {
+ if (devp->afbce_flag & VDIN_AFBCE_EN_720P)
+ devp->afbce_valid = 1;
+ } else {
+ if (devp->afbce_flag & VDIN_AFBCE_EN_SMALL)
+ devp->afbce_valid = 1;
+ }
+ }
+
+ /* default non-afbce mode
+ * switch to afbce_mode if need by vpp notify
+ */
+ devp->afbce_mode = 0;
+ devp->afbce_mode_pre = devp->afbce_mode;
+ pr_info("vdin%d init afbce_mode: %d\n", devp->index, devp->afbce_mode);
+}
+
/*
* 1. config canvas base on canvas_config_mode
* 0: canvas_config in driver probe
pr_info("[vdin]%s null error.\n", __func__);
return;
}
+
if (devp->frontend && devp->frontend->sm_ops) {
sm_ops = devp->frontend->sm_ops;
sm_ops->get_sig_property(devp->frontend, &devp->prop);
-
if (!(devp->flags & VDIN_FLAG_V4L2_DEBUG))
devp->parm.info.cfmt = devp->prop.color_format;
if ((devp->parm.dest_width != 0) ||
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
devp->canvas_config_mode = canvas_config_mode;
/* h_active/v_active will be recalculated by bellow calling */
vdin_set_decimation(devp);
+ if (de_fmt_flag == 1 &&
+ (devp->prop.vs != 0 ||
+ devp->prop.ve != 0 ||
+ devp->prop.hs != 0 ||
+ devp->prop.he != 0)) {
+ devp->prop.vs = 0;
+ devp->prop.ve = 0;
+ devp->prop.hs = 0;
+ devp->prop.he = 0;
+ devp->prop.pre_vs = 0;
+ devp->prop.pre_ve = 0;
+ devp->prop.pre_hs = 0;
+ devp->prop.pre_he = 0;
+ pr_info("ioctl start dec,restore the cutwin param.\n");
+ }
vdin_set_cutwin(devp);
vdin_set_hvscale(devp);
if (cpu_after_eq(MESON_CPU_MAJOR_ID_GXTVBB))
if (get_cpu_type() >= MESON_CPU_MAJOR_ID_TXL)
vdin_fix_nonstd_vsync(devp);
-
- /*reverse / disable reverse write buffer*/
+ /*reverse / disable reverse write buffer*/
vdin_wr_reverse(devp->addr_offset,
- devp->parm.h_reverse,
- devp->parm.v_reverse);
+ devp->parm.h_reverse, devp->parm.v_reverse);
+
+ /* check if need enable afbce */
+ vdin_afbce_mode_init(devp);
+
#ifdef CONFIG_CMA
vdin_cma_malloc_mode(devp);
- if (devp->afbce_mode == 1) {
- if (vdin_afbce_cma_alloc(devp)) {
- pr_err("\nvdin%d-afbce %s fail for cma alloc fail!!!\n",
- devp->index, __func__);
- return;
- }
- } else if (devp->afbce_mode == 0) {
- if (vdin_cma_alloc(devp)) {
- pr_err("\nvdin%d %s fail for cma alloc fail!!!\n",
- devp->index, __func__);
- return;
- }
+ 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 (devp->afbce_mode == 0) {
- if (canvas_config_mode == 1)
- vdin_canvas_start_config(devp);
- else if (canvas_config_mode == 2)
- vdin_canvas_auto_config(devp);
- } else if (devp->afbce_mode == 1) {
+ if (canvas_config_mode == 1)
+ vdin_canvas_start_config(devp);
+ else if (canvas_config_mode == 2)
+ vdin_canvas_auto_config(devp);
+
+ if (devp->afbce_info) {
vdin_afbce_maptable_init(devp);
vdin_afbce_config(devp);
}
+
#if 0
if ((devp->prop.dest_cfmt == TVIN_NV12) ||
(devp->prop.dest_cfmt == TVIN_NV21))
else
devp->duration = devp->fmt_info_p->duration;
- devp->vfp->size = devp->canvas_max_num;
+ devp->vfp->size = devp->vfmem_max_cnt; /* canvas and afbce compatible */
vf_pool_init(devp->vfp, devp->vfp->size);
vdin_game_mode_check(devp);
vdin_vf_init(devp);
devp->abnormal_cnt = 0;
devp->last_wr_vfe = NULL;
irq_max_count = 0;
+ vdin_drop_cnt = 0;
/* devp->stamp_valid = false; */
devp->stamp = 0;
devp->cycle = 0;
vdin_hw_enable(devp->addr_offset);
vdin_set_all_regs(devp);
-
- if (is_meson_tl1_cpu()) {
- if (devp->afbce_mode == 0)
- vdin_write_mif_or_afbce(devp, VDIN_OUTPUT_TO_MIF);
- else if (devp->afbce_mode == 1)
- vdin_write_mif_or_afbce(devp, VDIN_OUTPUT_TO_AFBCE);
- }
+ vdin_write_mif_or_afbce_init(devp);
if (!(devp->parm.flag & TVIN_PARM_FLAG_CAP) &&
(devp->frontend) &&
devp->frontend->dec_ops->start(devp->frontend,
devp->parm.info.fmt);
-#ifdef CONFIG_AML_RDMA
+#ifdef CONFIG_AMLOGIC_MEDIA_RDMA
/*it is better put after all reg init*/
if (devp->rdma_enable && devp->rdma_handle > 0)
devp->flags |= VDIN_FLAG_RDMA_ENABLE;
#endif
vf_notify_receiver(devp->name,
VFRAME_EVENT_PROVIDER_START, NULL);
- if ((devp->parm.port != TVIN_PORT_VIU1) ||
- (viu_hw_irq != 0)) {
- /*enable irq */
- enable_irq(devp->irq);
- if (vdin_dbg_en)
- pr_info("****[%s]enable_irq ifdef VDIN_V2****\n",
- __func__);
- }
if (vdin_dbg_en)
pr_info("****[%s]ok!****\n", __func__);
#endif
devp->irq_cnt = 0;
devp->rdma_irq_cnt = 0;
+ devp->frame_cnt = 0;
+ phase_lock_flag = 0;
+
if (time_en)
pr_info("vdin.%d start time: %ums, run time:%ums.\n",
devp->index, jiffies_to_msecs(jiffies),
jiffies_to_msecs(jiffies)-devp->start_time);
+
+ vfe_drop_force = NULL;
+ devp->recycle_frames = 0;
}
/*
*/
void vdin_stop_dec(struct vdin_dev_s *devp)
{
+ int afbc_write_down_timeout = 500; /* 50ms to cover a 24Hz vsync */
+ int i = 0;
+
/* avoid null pointer oops */
if (!devp || !devp->frontend)
return;
return;
}
#endif
+
disable_irq_nosync(devp->irq);
- vdin_hw_disable(devp->addr_offset);
+
+ if (devp->afbce_mode == 1) {
+ while (i++ < afbc_write_down_timeout) {
+ if (vdin_afbce_read_writedown_flag())
+ break;
+ usleep_range(100, 105);
+ }
+ if (i >= afbc_write_down_timeout) {
+ pr_info("vdin.%d afbc write done timeout\n",
+ devp->index);
+ }
+ }
+
if (!(devp->parm.flag & TVIN_PARM_FLAG_CAP) &&
devp->frontend->dec_ops &&
devp->frontend->dec_ops->stop &&
((devp->flags & VDIN_FLAG_SNOW_FLAG) == 0)))
devp->frontend->dec_ops->stop(devp->frontend, devp->parm.port);
+ vdin_hw_disable(devp->addr_offset);
+
vdin_set_default_regmap(devp->addr_offset);
/*only for vdin0*/
if (devp->urgent_en && (devp->index == 0))
#endif
vf_unreg_provider(&devp->vprov);
devp->dv.dv_config = 0;
-#ifdef CONFIG_CMA
- if (devp->afbce_mode == 1)
- vdin_afbce_cma_release(devp);
- else if (devp->afbce_mode == 0)
- vdin_cma_release(devp);
-#endif
- vdin_dolby_addr_release(devp, devp->vfp->size);
+ if (devp->afbce_mode == 1) {
+ vdin_afbce_hw_disable();
+ vdin_afbce_soft_reset();
+ }
+#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION
+ vdin_dolby_addr_release(devp, devp->vfp->size);
+#endif
+
+#ifdef CONFIG_CMA
+ vdin_cma_release(devp);
+#endif
switch_vpu_mem_pd_vmod(devp->addr_offset?VPU_VIU_VDIN1:VPU_VIU_VDIN0,
VPU_MEM_POWER_DOWN);
memset(&devp->prop, 0, sizeof(struct tvin_sig_property_s));
-#ifdef CONFIG_AML_RDMA
+#ifdef CONFIG_AMLOGIC_MEDIA_RDMA
rdma_clear(devp->rdma_handle);
#endif
devp->flags &= (~VDIN_FLAG_RDMA_ENABLE);
- ignore_frames = 0;
+ devp->ignore_frames = 0;
devp->cycle = 0;
+
/* clear color para*/
memset(&devp->prop, 0, sizeof(devp->prop));
if (time_en)
__func__, no);
return -1;
}
+
fmt = devp->parm.info.fmt;
if (vdin_dbg_en) {
pr_info("**[%s]cfmt:%d;dfmt:%d;dest_hactive:%d;",
pr_info("v_active:%d;scan_mode:%d**\n",
para->v_active, para->scan_mode);
}
+
+ if (devp->index == 1) {
+ devp->parm.reserved |= para->reserved;
+ pr_info("vdin1 add reserved = 0x%lx\n", para->reserved);
+ pr_info("vdin1 all reserved = 0x%x\n", devp->parm.reserved);
+ }
devp->start_time = jiffies_to_msecs(jiffies);
if (devp->flags & VDIN_FLAG_DEC_STARTED) {
pr_err("%s: port 0x%x, decode started already.\n",
__func__, para->port);
- ret = -EBUSY;
- return ret;
- }
- if ((para->port != TVIN_PORT_VIU1) ||
- (viu_hw_irq != 0)) {
- ret = request_irq(devp->irq, vdin_v4l2_isr, IRQF_SHARED,
- devp->irq_name, (void *)devp);
- devp->flags |= VDIN_FLAG_ISR_REQ;
- /*disable vsync irq until vdin configured completely*/
- disable_irq_nosync(devp->irq);
+ if ((devp->parm.reserved & PARAM_STATE_SCREENCAP) &&
+ (devp->parm.reserved & PARAM_STATE_HISTGRAM) &&
+ (devp->index == 1))
+ return 0;
+ else
+ return -EBUSY;
}
+
vdin_clk_onoff(devp, true);
/*config the vdin use default value*/
vdin_set_default_regmap(devp->addr_offset);
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->flags |= VDIN_FLAG_DEC_OPENED;
devp->flags |= VDIN_FLAG_DEC_STARTED;
+ if ((para->port != TVIN_PORT_VIU1) ||
+ (viu_hw_irq != 0)) {
+ ret = request_irq(devp->irq, vdin_v4l2_isr, IRQF_SHARED,
+ devp->irq_name, (void *)devp);
+
+ if (ret != 0) {
+ pr_info("vdin_v4l2_isr request irq error.\n");
+ return -1;
+ }
+ devp->flags |= VDIN_FLAG_ISR_REQ;
+ }
return 0;
}
EXPORT_SYMBOL(start_tvin_service);
unsigned int end_time;
devp = vdin_devp[no];
+ if ((devp->parm.reserved & PARAM_STATE_HISTGRAM) &&
+ (devp->parm.reserved & PARAM_STATE_SCREENCAP) &&
+ (devp->index == 1)) {
+ pr_info("stop vdin v4l2 screencap.\n");
+ devp->parm.reserved &= ~PARAM_STATE_SCREENCAP;
+ return 0;
+ }
+
if (!(devp->flags&VDIN_FLAG_DEC_STARTED)) {
pr_err("%s:decode hasn't started.\n", __func__);
return -EBUSY;
return cur;
}
+static void vdin_hist_tgt(struct vdin_dev_s *devp, struct vframe_s *vf)
+{
+ int ave_luma;
+ int pix_sum;
+ ulong flags;
+
+ spin_lock_irqsave(&devp->hist_lock, flags);
+ vdin1_hist.sum = vf->prop.hist.luma_sum;
+ pix_sum = vf->prop.hist.pixel_sum;
+ vdin1_hist.height = vf->prop.hist.height;
+ vdin1_hist.width = vf->prop.hist.width;
+
+ if ((vdin1_hist.height == 0) || (vdin1_hist.width == 0)) {
+ spin_unlock_irqrestore(&devp->hist_lock, flags);
+ return;
+ }
+
+ vdin1_hist.ave =
+ vdin1_hist.sum/(vdin1_hist.height * vdin1_hist.width);
+
+ ave_luma = vdin1_hist.ave;
+ ave_luma = (ave_luma - 16) < 0 ? 0 : (ave_luma - 16);
+ vdin1_hist.ave = ave_luma*255/(235-16);
+ if (vdin1_hist.ave > 255)
+ vdin1_hist.ave = 255;
+
+ spin_unlock_irqrestore(&devp->hist_lock, flags);
+}
+
+static bool vdin_recycle_frame_check(struct vdin_dev_s *devp)
+{
+ int skip_flag = 0;
+
+ if (devp->index)
+ return false;
+
+ if (devp->recycle_frames < max_recycle_frame_cnt) {
+ devp->recycle_frames++;
+ skip_flag = 1;
+ }
+
+ if (skip_flag) {
+ vfe_drop_force = receiver_vf_get(devp->vfp);
+ if (vfe_drop_force)
+ receiver_vf_put(&vfe_drop_force->vf, devp->vfp);
+ else
+ pr_info("vdin.%d: skip vf get error\n", devp->index);
+ return true;
+ }
+
+ return false;
+}
+
+static void vdin_afbce_mode_update(struct vdin_dev_s *devp)
+{
+ /* vdin mif/afbce mode update */
+ if (devp->afbce_mode) {
+ vdin_write_mif_or_afbce(devp, VDIN_OUTPUT_TO_AFBCE);
+ vdin_afbce_hw_enable_rdma(devp);
+ } else {
+ vdin_afbce_hw_disable_rdma(devp);
+ vdin_write_mif_or_afbce(devp, VDIN_OUTPUT_TO_MIF);
+ }
+
+ if (vdin_dbg_en) {
+ pr_info("vdin.%d: change afbce_mode %d->%d\n",
+ devp->index, devp->afbce_mode_pre, devp->afbce_mode);
+ }
+ devp->afbce_mode_pre = devp->afbce_mode;
+}
+
/*
*VDIN_FLAG_RDMA_ENABLE=1
* provider_vf_put(devp->last_wr_vfe, devp->vfp);
if (!devp->frontend) {
devp->vdin_irq_flag = 1;
- goto irq_handled;
+ if (skip_frame_debug) {
+ pr_info("vdin.%d: vdin_irq_flag=%d\n",
+ devp->index, devp->vdin_irq_flag);
+ }
+ return IRQ_HANDLED;
}
/* ignore fake irq caused by sw reset*/
if (devp->vdin_reset_flag) {
devp->vdin_reset_flag = 0;
+ devp->vdin_irq_flag = 10;
+ if (skip_frame_debug) {
+ pr_info("vdin.%d: vdin_irq_flag=%d\n",
+ devp->index, devp->vdin_irq_flag);
+ }
return IRQ_HANDLED;
}
vf_drop_cnt = vdin_drop_cnt;
*/
spin_lock_irqsave(&devp->isr_lock, flags);
- /* W_VCBUS_BIT(VDIN_MISC_CTRL, 0, 0, 2); */
- devp->vdin_reset_flag = vdin_vsync_reset_mif(devp->index);
+
+ if (devp->afbce_mode == 1) {
+ /* no need reset mif under afbc mode */
+ devp->vdin_reset_flag = 0;
+ } else {
+ /* W_VCBUS_BIT(VDIN_MISC_CTRL, 0, 0, 2); */
+ 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;
devp->vdin_irq_flag = 2;
+ if (skip_frame_debug) {
+ pr_info("vdin.%d: vdin_irq_flag=%d\n",
+ devp->index, devp->vdin_irq_flag);
+ }
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;
- devp->curr_wr_vfe->vf.ready_clock[0] = sched_clock();
+ if (devp->curr_wr_vfe) {
+ devp->curr_wr_vfe->vf.ready_jiffies64 = jiffies_64;
+ devp->curr_wr_vfe->vf.ready_clock[0] = sched_clock();
+ }
/*save the first field stamp*/
devp->stamp = stamp;
devp->vdin_irq_flag = 3;
+ if (skip_frame_debug) {
+ pr_info("vdin.%d: vdin_irq_flag=%d\n",
+ devp->index, devp->vdin_irq_flag);
+ }
goto irq_handled;
}
+
+ /* use RDMA and not game mode */
if (devp->last_wr_vfe && (devp->flags&VDIN_FLAG_RDMA_ENABLE) &&
- !(devp->game_mode & (1 << 1))) {
+ !(devp->game_mode & VDIN_GAME_MODE_1) &&
+ !(devp->game_mode & VDIN_GAME_MODE_2)) {
/*dolby vision metadata process*/
if (dv_dbg_mask & DV_UPDATE_DATA_MODE_DELBY_WORK
&& devp->dv.dv_config) {
}
} else {
devp->vdin_irq_flag = 15;
+ if (skip_frame_debug) {
+ pr_info("vdin.%d: vdin_irq_flag=%d\n",
+ devp->index, devp->vdin_irq_flag);
+ }
vdin_drop_cnt++;
goto irq_handled;
}
(devp->dv.dv_config == true))
vf_notify_receiver("dv_vdin",
VFRAME_EVENT_PROVIDER_VFRAME_READY, NULL);
- else
+ else {
+#endif
+ if (vdin_recycle_frame_check(devp)) {
+ devp->vdin_irq_flag = 16;
+ if (skip_frame_debug) {
+ pr_info("vdin.%d: vdin_irq_flag=%d\n",
+ devp->index,
+ devp->vdin_irq_flag);
+ }
+ vdin_drop_cnt++;
+ } else {
+ vf_notify_receiver(devp->name,
+ VFRAME_EVENT_PROVIDER_VFRAME_READY,
+ NULL);
+ }
+#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION
+ }
#endif
- 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))) {
devp->vdin_irq_flag = 4;
+ if (skip_frame_debug) {
+ pr_info("vdin.%d: vdin_irq_flag=%d\n",
+ devp->index, devp->vdin_irq_flag);
+ }
vdin_drop_cnt++;
goto irq_handled;
}
(state != TVIN_SM_STATUS_STABLE)) &&
(!(devp->flags & VDIN_FLAG_SNOW_FLAG))) {
devp->vdin_irq_flag = 6;
+ if (skip_frame_debug) {
+ pr_info("vdin.%d: vdin_irq_flag=%d\n",
+ devp->index, devp->vdin_irq_flag);
+ }
vdin_drop_cnt++;
goto irq_handled;
}
if (((devp->parm.flag & TVIN_PARM_FLAG_2D_TO_3D) ||
(trans_fmt && (trans_fmt != TVIN_TFMT_3D_FP))) &&
((last_field_type & VIDTYPE_INTERLACE_BOTTOM) ==
- VIDTYPE_INTERLACE_BOTTOM)
- ) {
+ VIDTYPE_INTERLACE_BOTTOM)) {
devp->vdin_irq_flag = 7;
+ if (skip_frame_debug) {
+ pr_info("vdin.%d: vdin_irq_flag=%d\n",
+ devp->index, devp->vdin_irq_flag);
+ }
vdin_drop_cnt++;
goto irq_handled;
}
curr_wr_vfe = devp->curr_wr_vfe;
curr_wr_vf = &curr_wr_vfe->vf;
+ /* change afbce mode */
+ if (devp->afbce_mode_pre != devp->afbce_mode)
+ vdin_afbce_mode_update(devp);
+
/* change color matrix */
if (devp->csc_cfg != 0) {
prop = &devp->prop;
pre_prop = &devp->pre_prop;
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))
+ (prop->color_fmt_range != pre_prop->color_fmt_range)) {
vdin_set_matrix(devp);
+ if (skip_frame_debug) {
+ pr_info("vdin.%d color_format changed\n",
+ devp->index);
+ }
+ }
if (prop->dest_cfmt != pre_prop->dest_cfmt) {
vdin_set_bitdepth(devp);
vdin_source_bitdepth_reinit(devp);
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,
+ vdin_set_top(devp, devp->addr_offset, devp->parm.port,
devp->prop.color_format, devp->h_active,
devp->bt_path);
+
+ if (devp->afbce_valid)
+ vdin_afbce_update(devp);
+
+ if (skip_frame_debug) {
+ pr_info("vdin.%d dest_cfmt changed: %d->%d\n",
+ devp->index,
+ pre_prop->dest_cfmt, prop->dest_cfmt);
+ }
}
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;
- ignore_frames = 0;
+ devp->ignore_frames = 0;
+ devp->vdin_irq_flag = 20;
+ if (skip_frame_debug) {
+ pr_info("vdin.%d: vdin_irq_flag=%d\n",
+ devp->index, devp->vdin_irq_flag);
+ }
vdin_drop_cnt++;
goto irq_handled;
}
decops = devp->frontend->dec_ops;
if (decops->decode_isr(devp->frontend, devp->hcnt64) == TVIN_BUF_SKIP) {
devp->vdin_irq_flag = 8;
+ if (skip_frame_debug) {
+ pr_info("vdin.%d: vdin_irq_flag=%d\n",
+ devp->index, devp->vdin_irq_flag);
+ }
vdin_drop_cnt++;
goto irq_handled;
}
curr_wr_vf->phase = sm_ops->get_secam_phase(devp->frontend) ?
VFRAME_PHASE_DB : VFRAME_PHASE_DR;
-
- if (ignore_frames < max_ignore_frames) {
- ignore_frames++;
+ if (devp->ignore_frames < max_ignore_frame_cnt) {
devp->vdin_irq_flag = 12;
+ if (skip_frame_debug) {
+ pr_info("vdin.%d: vdin_irq_flag=%d\n",
+ devp->index, devp->vdin_irq_flag);
+ }
+ devp->ignore_frames++;
vdin_drop_cnt++;
goto irq_handled;
}
if (sm_ops->check_frame_skip &&
sm_ops->check_frame_skip(devp->frontend)) {
devp->vdin_irq_flag = 13;
+ if (skip_frame_debug) {
+ pr_info("vdin.%d: vdin_irq_flag=%d\n",
+ devp->index, devp->vdin_irq_flag);
+ }
vdin_drop_cnt++;
if (devp->flags&VDIN_FLAG_RDMA_ENABLE)
- ignore_frames = 0;
+ devp->ignore_frames = 0;
goto irq_handled;
}
next_wr_vfe = provider_vf_peek(devp->vfp);
if (!next_wr_vfe) {
- devp->vdin_irq_flag = 14;
- vdin_drop_cnt++;
- vf_drop_cnt = vdin_drop_cnt;/*avoid do skip*/
- goto irq_handled;
+ /*add for force vdin buffer recycle*/
+ if (devp->flags & VDIN_FLAG_FORCE_RECYCLE) {
+ next_wr_vfe = receiver_vf_get(devp->vfp);
+ if (next_wr_vfe)
+ receiver_vf_put(&next_wr_vfe->vf, devp->vfp);
+ else
+ pr_err("[vdin.%d]force recycle error,no buffer in ready list",
+ devp->index);
+ } else {
+ devp->vdin_irq_flag = 14;
+ if (skip_frame_debug) {
+ pr_info("vdin.%d: vdin_irq_flag=%d\n",
+ devp->index, devp->vdin_irq_flag);
+ }
+ vdin_drop_cnt++;
+ vf_drop_cnt = vdin_drop_cnt;/*avoid do skip*/
+ goto irq_handled;
+ }
}
+
#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION
if (((devp->dv.dolby_input & (1 << devp->index)) ||
(devp->dv.dv_flag && is_dolby_vision_enable())) &&
#endif
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
*/
- if ((vdin2nr || (devp->flags & VDIN_FLAG_RDMA_ENABLE)) &&
- !(devp->game_mode & (1 << 1)))
+ if (vdin2nr || (devp->flags & VDIN_FLAG_RDMA_ENABLE))
curr_wr_vf->type = devp->curr_field_type;
else
curr_wr_vf->type = last_field_type;
*/
if (((devp->parm.flag & TVIN_PARM_FLAG_2D_TO_3D) ||
(curr_wr_vf->trans_fmt)) &&
- (last_field_type & VIDTYPE_INTERLACE)
- ) {
+ (last_field_type & VIDTYPE_INTERLACE)) {
curr_wr_vf->type &= ~VIDTYPE_INTERLACE_TOP;
curr_wr_vf->type |= VIDTYPE_PROGRESSIVE;
curr_wr_vf->type |= VIDTYPE_PRE_INTERLACE;
(devp->parm.port <= TVIN_PORT_CVBS3))
vdin_set_display_ratio(devp, curr_wr_vf);
if ((devp->flags&VDIN_FLAG_RDMA_ENABLE) &&
- !(devp->game_mode & (1 << 1))) {
+ !(devp->game_mode & VDIN_GAME_MODE_1)) {
devp->last_wr_vfe = curr_wr_vfe;
- } else {
+ } else if (!(devp->game_mode & VDIN_GAME_MODE_2)) {
/*dolby vision metadata process*/
if (dv_dbg_mask & DV_UPDATE_DATA_MODE_DELBY_WORK
&& devp->dv.dv_config) {
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;
+ if (skip_frame_debug) {
+ pr_info("vdin.%d: vdin_irq_flag=%d\n",
+ devp->index, devp->vdin_irq_flag);
+ }
vdin_drop_cnt++;
goto irq_handled;
}
if (devp->vfp->skip_vf_num > 0)
vdin_vf_disp_mode_update(curr_wr_vfe, devp->vfp);
}
+ /*switch to game mode 2 from game mode 1,otherwise may appear blink*/
+ if (is_meson_tl1_cpu() || is_meson_tm2_cpu()) {
+ if (devp->game_mode & VDIN_GAME_MODE_SWITCH_EN) {
+ /* make sure phase lock for next few frames */
+ if (vlock_get_phlock_flag())
+ phase_lock_flag++;
+ if (phase_lock_flag >= game_mode_phlock_switch_frames) {
+ if (vdin_dbg_en) {
+ pr_info("switch game mode (%d-->5), frame_cnt=%d\n",
+ devp->game_mode,
+ devp->frame_cnt);
+ }
+ devp->game_mode = (VDIN_GAME_MODE_0 |
+ VDIN_GAME_MODE_2);
+ }
+ }
+#if 0
+ if (phase_lock_flag >= game_mode_phlock_switch_frames) {
+ if (!vlock_get_phlock_flag())
+ phase_lock_flag = 0;
+ if (vdin_dbg_en) {
+ pr_info(
+ "switch game mode to %d, frame_cnt=%d\n",
+ devp->game_mode, devp->frame_cnt);
+ }
+ devp->game_mode = (VDIN_GAME_MODE_0 | VDIN_GAME_MODE_1 |
+ VDIN_GAME_MODE_SWITCH_EN);
+ }
+#endif
+ } else {
+ if ((devp->frame_cnt >= game_mode_switch_frames) &&
+ (devp->game_mode & VDIN_GAME_MODE_SWITCH_EN)) {
+ if (vdin_dbg_en) {
+ pr_info("switch game mode (%d-->5), frame_cnt=%d\n",
+ devp->game_mode, devp->frame_cnt);
+ }
+ devp->game_mode = (VDIN_GAME_MODE_0 | VDIN_GAME_MODE_2);
+ }
+ }
+
/* prepare for next input data */
next_wr_vfe = provider_vf_get(devp->vfp);
- if (devp->afbce_mode == 0)
+ if (devp->afbce_mode == 0) {
vdin_set_canvas_id(devp, (devp->flags&VDIN_FLAG_RDMA_ENABLE),
(next_wr_vfe->vf.canvas0Addr&0xff));
- else if (devp->afbce_mode == 1)
+
+ /* 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);
+ } else if (devp->afbce_mode == 1) {
vdin_afbce_set_next_frame(devp,
(devp->flags&VDIN_FLAG_RDMA_ENABLE), next_wr_vfe);
-
- /* 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->curr_wr_vfe = next_wr_vfe;
+ next_wr_vfe->vf.type = vdin_get_curr_field_type(devp);
/* debug for video latency */
next_wr_vfe->vf.ready_jiffies64 = jiffies_64;
next_wr_vfe->vf.ready_clock[0] = sched_clock();
if (!(devp->flags&VDIN_FLAG_RDMA_ENABLE) ||
- (devp->game_mode & (1 << 1))) {
+ (devp->game_mode & VDIN_GAME_MODE_1)) {
+ /* not RDMA, or game mode 1 */
#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION
if (((devp->dv.dolby_input & (1 << devp->index)) ||
- (devp->dv.dv_flag && is_dolby_vision_enable())) &&
- (devp->dv.dv_config == true))
+ (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
+ else {
+#endif
+ if (vdin_recycle_frame_check(devp)) {
+ devp->vdin_irq_flag = 17;
+ if (skip_frame_debug) {
+ pr_info("vdin.%d: vdin_irq_flag=%d\n",
+ devp->index,
+ devp->vdin_irq_flag);
+ }
+ vdin_drop_cnt++;
+ } else {
+ vf_notify_receiver(devp->name,
+ VFRAME_EVENT_PROVIDER_VFRAME_READY,
+ NULL);
+ }
+#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION
+ }
#endif
+ } else if (devp->game_mode & VDIN_GAME_MODE_2) {
+ /* game mode 2 */
+ provider_vf_put(next_wr_vfe, devp->vfp);
+ if (vdin_recycle_frame_check(devp)) {
+ devp->vdin_irq_flag = 18;
+ if (skip_frame_debug) {
+ pr_info("vdin.%d: vdin_irq_flag=%d\n",
+ devp->index, devp->vdin_irq_flag);
+ }
+ vdin_drop_cnt++;
+ } else {
vf_notify_receiver(devp->name,
VFRAME_EVENT_PROVIDER_VFRAME_READY, NULL);
+ if (vdin_dbg_en) {
+ next_wr_vfe->vf.ready_clock[1] = sched_clock();
+ pr_info("vdin put latency %lld us.first %lld us\n",
+ func_div(next_wr_vfe->vf.ready_clock[1], 1000),
+ func_div(next_wr_vfe->vf.ready_clock[0], 1000));
+ }
+ }
}
+ devp->frame_cnt++;
irq_handled:
- /*hdmi skip policy should adapt to all drop vframe case*/
+ /*hdmi skip policy should adapt to all drop front 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
+#ifdef CONFIG_AMLOGIC_MEDIA_RDMA
if (devp->flags & VDIN_FLAG_RDMA_ENABLE)
rdma_config(devp->rdma_handle,
(devp->rdma_enable&1) ?
MODULE_PARM_DESC(skip_ratio,
"\n vdin skip frame ratio 1/ratio will reserved.\n");
+static struct vf_entry *check_vdin_readlist(struct vdin_dev_s *devp)
+{
+ struct vf_entry *vfe;
+
+ vfe = receiver_vf_peek(devp->vfp);
+
+ return vfe;
+}
+
irqreturn_t vdin_v4l2_isr(int irq, void *dev_id)
{
ulong flags;
struct tvin_decoder_ops_s *decops;
struct tvin_state_machine_ops_s *sm_ops;
int ret = 0;
- int offset;
+ unsigned int offset;
if (!devp)
return IRQ_HANDLED;
spin_lock_irqsave(&devp->isr_lock, flags);
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 ((devp->set_canvas_manual == 1) && check_vdin_readlist(devp)) {
+ devp->keystone_vframe_ready = 1;
+ wake_up_interruptible(&vframe_waitq);
+ }
+
if (devp->last_wr_vfe) {
provider_vf_put(devp->last_wr_vfe, devp->vfp);
devp->last_wr_vfe = NULL;
- vf_notify_receiver(devp->name,
+
+ if (devp->set_canvas_manual != 1) {
+ vf_notify_receiver(devp->name,
VFRAME_EVENT_PROVIDER_VFRAME_READY, NULL);
+ }
}
+
/*check vs is valid base on the time during continuous vs*/
vdin_check_cycle(devp);
vdin_set_vframe_prop_info(curr_wr_vf, devp);
vdin_backup_histgram(curr_wr_vf, devp);
+ vdin_hist_tgt(devp, curr_wr_vf);
if (devp->frontend && devp->frontend->dec_ops) {
decops = devp->frontend->dec_ops;
goto irq_handled;
}
}
+
if (curr_wr_vfe) {
curr_wr_vfe->flag |= VF_FLAG_NORMAL_FRAME;
/* provider_vf_put(curr_wr_vfe, devp->vfp); */
/* prepare for next input data */
next_wr_vfe = provider_vf_get(devp->vfp);
- if (devp->afbce_mode == 0)
+ if (devp->afbce_mode == 0) {
vdin_set_canvas_id(devp, (devp->flags&VDIN_FLAG_RDMA_ENABLE),
(next_wr_vfe->vf.canvas0Addr&0xff));
- else if (devp->afbce_mode == 1)
- vdin_afbce_set_next_frame(devp,
- (devp->flags&VDIN_FLAG_RDMA_ENABLE), next_wr_vfe);
- if ((devp->prop.dest_cfmt == TVIN_NV12) ||
+ 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);
+ vdin_set_chma_canvas_id(devp,
+ (devp->flags&VDIN_FLAG_RDMA_ENABLE),
+ (next_wr_vfe->vf.canvas0Addr>>8)&0xff);
+ } else if (devp->afbce_mode == 1) {
+ vdin_afbce_set_next_frame(devp,
+ (devp->flags&VDIN_FLAG_RDMA_ENABLE), next_wr_vfe);
+ }
devp->curr_wr_vfe = next_wr_vfe;
- vf_notify_receiver(devp->name, VFRAME_EVENT_PROVIDER_VFRAME_READY,
- NULL);
+
+ if (devp->set_canvas_manual != 1)
+ vf_notify_receiver(devp->name,
+ VFRAME_EVENT_PROVIDER_VFRAME_READY, NULL);
irq_handled:
spin_unlock_irqrestore(&devp->isr_lock, flags);
-#ifdef CONFIG_AML_RDMA
+#ifdef CONFIG_AMLOGIC_MEDIA_RDMA
if (devp->flags & VDIN_FLAG_RDMA_ENABLE)
rdma_config(devp->rdma_handle,
(devp->rdma_enable&1) ?
devp = container_of(inode->i_cdev, struct vdin_dev_s, cdev);
file->private_data = devp;
+ if (devp->set_canvas_manual == 1)
+ return 0;
+
if (devp->index >= VDIN_MAX_DEVS)
return -ENXIO;
return 0;
}
+ if ((is_meson_tl1_cpu() || is_meson_tm2_cpu()))
+ switch_vpu_mem_pd_vmod(VPU_AFBCE, VPU_MEM_POWER_ON);
+
devp->flags |= VDIN_FLAG_FS_OPENED;
/* request irq */
return 0;
}
+ if ((is_meson_tl1_cpu() || is_meson_tm2_cpu()))
+ switch_vpu_mem_pd_vmod(VPU_AFBCE, VPU_MEM_POWER_DOWN);
+
devp->flags &= (~VDIN_FLAG_FS_OPENED);
if (devp->flags & VDIN_FLAG_DEC_STARTED) {
devp->flags |= VDIN_FLAG_DEC_STOP_ISR;
static long vdin_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
long ret = 0;
+ int i;
int callmaster_status = 0;
struct vdin_dev_s *devp = NULL;
void __user *argp = (void __user *)arg;
+ struct vdin_parm_s param;
+ ulong flags;
+ struct vdin_hist_s vdin1_hist_temp;
+ struct page *page;
+ struct vdin_set_canvas_s vdinsetcanvas[VDIN_CANVAS_MAX_CNT];
+ unsigned int idx = 0;
+ unsigned int recov_idx = 0;
/* Get the per-device structure that contains this cdev */
devp = file->private_data;
break;
}
if ((devp->parm.info.fmt == TVIN_SIG_FMT_NULL) &&
- (devp->parm.port == TVIN_PORT_CVBS3))
+ (devp->parm.port == TVIN_PORT_CVBS3)) {
+ de_fmt_flag = 1;
fmt = devp->parm.info.fmt = TVIN_SIG_FMT_CVBS_NTSC_M;
- else
+ } else {
+ de_fmt_flag = 0;
fmt = devp->parm.info.fmt = parm.info.fmt;
- devp->fmt_info_p =
+ }
+ devp->fmt_info_p =
(struct tvin_format_s *)tvin_get_fmt_info(fmt);
if (!devp->fmt_info_p) {
pr_err("TVIN_IOC_START_DEC(%d) error, fmt is null\n",
break;
}
vdin_start_dec(devp);
+
+ if ((devp->parm.port != TVIN_PORT_VIU1) ||
+ (viu_hw_irq != 0)) {
+ /*enable irq */
+ enable_irq(devp->irq);
+ if (vdin_dbg_en)
+ pr_info("****[%s]enable_irq ifdef VDIN_V2****\n",
+ __func__);
+ }
+
devp->flags |= VDIN_FLAG_DEC_STARTED;
if (vdin_dbg_en)
pr_info("TVIN_IOC_START_DEC port %s, decode started ok\n\n",
}
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",
if (vdin_dbg_en)
pr_info("TVIN_IOC_STOP_DEC(%d) port %s, decode stop ok\n\n",
parm->index, tvin_port_str(parm->port));
+
mutex_unlock(&devp->fe_lock);
reset_tvin_smr(parm->index);
break;
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",
pr_info("TVIN_IOC_CLOSE(%d) port %s closed ok\n\n",
parm->index,
tvin_port_str(port));
+
mutex_unlock(&devp->fe_lock);
break;
}
mutex_unlock(&devp->fe_lock);
break;
}
+ case TVIN_IOC_G_FRONTEND_INFO: {
+ struct tvin_frontend_info_s info;
+
+ if ((!devp) || (!devp->fmt_info_p) || (!devp->curr_wr_vfe)) {
+ ret = -EFAULT;
+ break;
+ }
+
+ memset(&info, 0, sizeof(struct tvin_frontend_info_s));
+ mutex_lock(&devp->fe_lock);
+ info.cfmt = devp->parm.info.cfmt;
+ info.fps = devp->parm.info.fps;
+ info.colordepth = devp->prop.colordepth;
+ info.scan_mode = devp->fmt_info_p->scan_mode;
+ info.height = devp->curr_wr_vfe->vf.height;
+ info.width = devp->curr_wr_vfe->vf.width;
+ if (copy_to_user(argp, &info,
+ sizeof(struct tvin_frontend_info_s)))
+ ret = -EFAULT;
+ mutex_unlock(&devp->fe_lock);
+ break;
+ }
case TVIN_IOC_G_BUF_INFO: {
struct tvin_buf_info_s buf_info;
memset(&buf_info, 0, sizeof(buf_info));
devp->auto_ratio_en);
}
break;
+ case TVIN_IOC_GET_LATENCY_MODE:
+ mutex_unlock(&devp->fe_lock);
+ if (copy_to_user(argp,
+ &(devp->prop.latency),
+ sizeof(struct tvin_latency_s))) {
+ mutex_unlock(&devp->fe_lock);
+ ret = -EFAULT;
+ pr_info("TVIN_IOC_GET_ALLM_MODE err\n\n");
+ break;
+ }
+ pr_info("allm mode-%d,IT=%d,CN=%d\n\n",
+ devp->prop.latency.allm_mode,
+ devp->prop.latency.it_content,
+ devp->prop.latency.cn_type);
+ mutex_unlock(&devp->fe_lock);
+ break;
+ case TVIN_IOC_G_VDIN_HIST:
+ if (devp->index == 0) {
+ pr_info("TVIN_IOC_G_VDIN_HIST cann't be used at vdin0\n");
+ break;
+ }
+
+ spin_lock_irqsave(&devp->hist_lock, flags);
+ vdin1_hist_temp.sum = vdin1_hist.sum;
+ vdin1_hist_temp.width = vdin1_hist.width;
+ vdin1_hist_temp.height = vdin1_hist.height;
+ vdin1_hist_temp.ave = vdin1_hist.ave;
+ spin_unlock_irqrestore(&devp->hist_lock, flags);
+ if (vdin_dbg_en) {
+ if (pr_times++ > 10) {
+ pr_times = 0;
+ pr_info("-:h=%d,w=%d,a=%d\n",
+ vdin1_hist_temp.height,
+ vdin1_hist_temp.width,
+ vdin1_hist_temp.ave);
+ }
+ }
+
+ if ((vdin1_hist.height == 0) || (vdin1_hist.width == 0))
+ ret = -EFAULT;
+ else if (copy_to_user(argp,
+ &vdin1_hist_temp,
+ sizeof(struct vdin_hist_s))) {
+ pr_info("vdin1_hist copy fail\n");
+ ret = -EFAULT;
+ }
+ break;
+ case TVIN_IOC_S_VDIN_V4L2START:
+ if (devp->index == 0) {
+ pr_info("TVIN_IOC_S_VDIN_V4L2START cann't be used at vdin0\n");
+ break;
+ }
+ if (devp->flags & VDIN_FLAG_ISR_REQ)
+ free_irq(devp->irq, (void *)devp);
+
+ if (copy_from_user(&vdin_v4l2_param, argp,
+ sizeof(struct vdin_v4l2_param_s))) {
+ pr_info("vdin_v4l2_param copy fail\n");
+ return -EFAULT;
+ }
+ memset(¶m, 0, sizeof(struct vdin_parm_s));
+ if (is_meson_tl1_cpu() || is_meson_sm1_cpu() ||
+ is_meson_tm2_cpu())
+ param.port = TVIN_PORT_VIU1_WB0_VPP;
+ else
+ param.port = TVIN_PORT_VIU1;
+
+ param.h_active = vdin_v4l2_param.width;
+ param.v_active = vdin_v4l2_param.height;
+
+ if (devp->set_canvas_manual != 1) {
+ param.reserved |= PARAM_STATE_HISTGRAM;
+ /* use 1280X720 for histgram*/
+ if ((vdin_v4l2_param.width > 1280) &&
+ (vdin_v4l2_param.height > 720)) {
+ devp->debug.scaler4w = 1280;
+ devp->debug.scaler4h = 720;
+ devp->debug.dest_cfmt = TVIN_YUV422;
+ devp->flags |= VDIN_FLAG_MANUAL_CONVERSION;
+ }
+ }
+
+ param.frame_rate = vdin_v4l2_param.fps;
+ param.cfmt = TVIN_YUV422;
+
+ if (devp->set_canvas_manual == 1)
+ param.dfmt = TVIN_RGB444;
+ else
+ param.dfmt = TVIN_YUV422;
+
+ param.scan_mode = TVIN_SCAN_MODE_PROGRESSIVE;
+ param.fmt = TVIN_SIG_FMT_MAX;
+ //devp->flags |= VDIN_FLAG_V4L2_DEBUG;
+ devp->hist_bar_enable = 1;
+ start_tvin_service(devp->index, ¶m);
+ break;
+
+ case TVIN_IOC_S_VDIN_V4L2STOP:
+ if (devp->index == 0) {
+ pr_info("TVIN_IOC_S_VDIN_V4L2STOP cann't be used at vdin0\n");
+ break;
+ }
+ devp->parm.reserved &= ~PARAM_STATE_HISTGRAM;
+ devp->flags &= (~VDIN_FLAG_ISR_REQ);
+ devp->flags &= (~VDIN_FLAG_FS_OPENED);
+ stop_tvin_service(devp->index);
+
+ /*release manual set dma-bufs*/
+ if (devp->set_canvas_manual == 1) {
+ for (i = 0; i < 4; i++) {
+ if (vdin_set_canvas_addr[i].dmabuff == 0)
+ continue;
+
+ dma_buf_unmap_attachment(
+ vdin_set_canvas_addr[i].dmabufattach,
+ vdin_set_canvas_addr[i].sgtable,
+ DMA_BIDIRECTIONAL);
+ dma_buf_detach(
+ vdin_set_canvas_addr[i].dmabuff,
+ vdin_set_canvas_addr[i].dmabufattach);
+ dma_buf_put(vdin_set_canvas_addr[i].dmabuff);
+ devp->keystone_entry[i] = NULL;
+ }
+ memset(vdin_set_canvas_addr, 0,
+ sizeof(struct vdin_set_canvas_addr_s) *
+ VDIN_CANVAS_MAX_CNT);
+ }
+ break;
+
+ case TVIN_IOC_S_CANVAS_ADDR:
+ if (devp->index == 0) {
+ pr_info("TVIN_IOC_S_CANVAS_ADDR can't be used at vdin0\n");
+ break;
+ }
+
+ if (copy_from_user(vdinsetcanvas, argp,
+ sizeof(struct vdin_set_canvas_s) * 4)) {
+ pr_info("TVIN_IOC_S_CANVAS_ADDR copy fail\n");
+ return -EFAULT;
+ }
+
+ for (i = 0; i < 4; i++) {
+ /*when fd means, the canvas list reaches end*/
+ if (vdinsetcanvas[i].fd < 0)
+ break;
+
+ if (vdinsetcanvas[i].index >= VDIN_CANVAS_MAX_CNT) {
+ pr_err("vdin buf idx range (0 ~ %d), current idx is too big.\n ",
+ VDIN_CANVAS_MAX_CNT - 1);
+ continue;
+ }
+
+ idx = vdinsetcanvas[i].index;
+
+ vdin_set_canvas_addr[idx].dmabuff =
+ dma_buf_get(vdinsetcanvas[i].fd);
+
+ vdin_set_canvas_addr[idx].dmabufattach =
+ dma_buf_attach(
+ vdin_set_canvas_addr[idx].dmabuff,
+ devp->dev);
+ vdin_set_canvas_addr[idx].sgtable =
+ dma_buf_map_attachment(
+ vdin_set_canvas_addr[idx].dmabufattach,
+ DMA_BIDIRECTIONAL);
+
+ page = sg_page(vdin_set_canvas_addr[idx].sgtable->sgl);
+ vdin_set_canvas_addr[idx].paddr =
+ PFN_PHYS(page_to_pfn(page));
+ vdin_set_canvas_addr[idx].size =
+ vdin_set_canvas_addr[idx].dmabuff->size;
+
+ pr_info("TVIN_IOC_S_CANVAS_ADDR[%d] addr=0x%lx, len=0x%x.\n",
+ i,
+ vdin_set_canvas_addr[idx].paddr,
+ vdin_set_canvas_addr[idx].size);
+
+ __close_fd(current->files, vdinsetcanvas[i].fd);
+ }
+ break;
+
+ case TVIN_IOC_S_CANVAS_RECOVERY:
+ if (devp->index == 0) {
+ pr_info("TVIN_IOC_S_CANVAS_RECOVERY can't be used at vdin0\n");
+ break;
+ }
+
+ if (copy_from_user(&recov_idx, argp, sizeof(unsigned int))) {
+ pr_info("TVIN_IOC_S_CANVAS_RECOVERY copy fail\n");
+ return -EFAULT;
+ }
+
+ if (devp->keystone_entry[recov_idx]) {
+ receiver_vf_put(&devp->keystone_entry[recov_idx]->vf,
+ devp->vfp);
+ devp->keystone_entry[recov_idx] = NULL;
+ } else
+ pr_err("[vdin.%d] idx %d RECOVERY error\n",
+ devp->index, recov_idx);
+ break;
+
default:
ret = -ENOIOCTLCMD;
/* pr_info("%s %d is not supported command\n", __func__, cmd); */
struct vdin_dev_s *devp = file->private_data;
unsigned int mask = 0;
- poll_wait(file, &devp->queue, wait);
- mask = (POLLIN | POLLRDNORM);
+ if (devp->set_canvas_manual == 1) {
+ poll_wait(file, &vframe_waitq, wait);
+
+ if (devp->keystone_vframe_ready == 1)
+ mask = (POLLIN | POLLRDNORM);
+ } else {
+ poll_wait(file, &devp->queue, wait);
+ mask = (POLLIN | POLLRDNORM);
+ }
return mask;
}
+static ssize_t vdin_read(struct file *file, char __user *buf,
+ size_t count, loff_t *ppos)
+{
+ int index;
+ long ret;
+ struct vf_entry *vfe;
+ struct vdin_dev_s *devp = file->private_data;
+
+ vfe = receiver_vf_peek(devp->vfp);
+ if (!vfe)
+ return 0;
+
+ vfe = receiver_vf_get(devp->vfp);
+ /*index = report_canvas_index;*/
+ index = vfe->vf.index;
+ devp->keystone_entry[index] = vfe;
+ ret = copy_to_user(buf, (void *)(&index), sizeof(int));
+ if (ret) {
+ pr_info("vdin_read copy_to_user error\n");
+ return -1;
+ }
+
+ devp->keystone_vframe_ready = 0;
+
+ return sizeof(int);
+}
+
static const struct file_operations vdin_fops = {
- .owner = THIS_MODULE,
- .open = vdin_open,
- .release = vdin_release,
- .unlocked_ioctl = vdin_ioctl,
+ .owner = THIS_MODULE,
+ .open = vdin_open,
+ .read = vdin_read,
+ .release = vdin_release,
+ .unlocked_ioctl = vdin_ioctl,
#ifdef CONFIG_COMPAT
.compat_ioctl = vdin_compat_ioctl,
#endif
- .mmap = vdin_mmap,
- .poll = vdin_poll,
+ .mmap = vdin_mmap,
+ .poll = vdin_poll,
};
}
}
vdin_devp[vdevp->index] = vdevp;
-#ifdef CONFIG_AML_RDMA
- vdin_rdma_op.arg = vdin_devp;
- vdevp->rdma_handle = rdma_register(&vdin_rdma_op,
+#ifdef CONFIG_AMLOGIC_MEDIA_RDMA
+ vdin_rdma_op[vdevp->index].irq_cb = vdin_rdma_irq;
+ vdin_rdma_op[vdevp->index].arg = vdevp;
+ vdevp->rdma_handle = rdma_register(&vdin_rdma_op[vdevp->index],
NULL, RDMA_TABLE_SIZE);
pr_info("%s:vdin.%d rdma hanld %d.\n", __func__, vdevp->index,
vdevp->rdma_handle);
else
vdevp->color_depth_mode = 0;
- /*set afbce mode*/
- ret = of_property_read_u32(pdev->dev.of_node,
- "afbce_bit_mode", &vdevp->afbce_mode);
- if (ret) {
- vdevp->afbce_mode = 0;
- pr_info("no afbce mode found, use normal mode\n");
- } else {
- if ((is_meson_tl1_cpu()) && (vdevp->index == 0)) {
- /* just use afbce at vdin0 */
- pr_info("afbce mode = %d\n", vdevp->afbce_mode);
+ /*set afbce config*/
+ vdevp->afbce_flag = 0;
+ if (vdevp->index == 0) { /* just use afbce at vdin0 */
+ if (is_meson_tl1_cpu() || is_meson_tm2_cpu()) {
vdevp->afbce_info = devm_kzalloc(vdevp->dev,
sizeof(struct vdin_afbce_s), GFP_KERNEL);
if (!vdevp->afbce_info)
goto fail_kzalloc_vdev;
- } else {
- vdevp->afbce_mode = 0;
- pr_info("get afbce from dts, but chip cannot support\n");
+
+ ret = of_property_read_u32(pdev->dev.of_node,
+ "afbce_bit_mode", &vdevp->afbce_flag);
+ if (ret) {
+ vdevp->afbce_flag = 0;
+ } else {
+ pr_info("afbce flag = 0x%x\n",
+ vdevp->afbce_flag);
+ }
}
}
+
+ ret = of_property_read_u32(pdev->dev.of_node,
+ "set_canvas_manual", &vdevp->set_canvas_manual);
+
+ if (ret) {
+ vdevp->set_canvas_manual = 0;
+ pr_info("set_canvas_manual = 0\n");
+ } else {
+ pr_info("set_canvas_manual = %d\n", vdevp->set_canvas_manual);
+ }
+
/*vdin urgent en*/
ret = of_property_read_u32(pdev->dev.of_node,
"urgent_en", &urgent_en);
vdevp->flags &= (~VDIN_FLAG_FS_OPENED);
mutex_init(&vdevp->fe_lock);
spin_lock_init(&vdevp->isr_lock);
+ spin_lock_init(&vdevp->hist_lock);
vdevp->frontend = NULL;
/* @todo vdin_addr_offset */
if (is_meson_gxbb_cpu() && vdevp->index)
vdin_addr_offset[vdevp->index] = 0x70;
- else if ((is_meson_g12a_cpu() || is_meson_g12b_cpu() ||
- is_meson_tl1_cpu()) && vdevp->index)
+ else if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A) && vdevp->index)
vdin_addr_offset[vdevp->index] = 0x100;
vdevp->addr_offset = vdin_addr_offset[vdevp->index];
vdevp->flags = 0;
/*canvas align number*/
- if (is_meson_g12a_cpu() || is_meson_g12b_cpu() || is_meson_tl1_cpu())
+ if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A))
vdevp->canvas_align = 64;
else
vdevp->canvas_align = 32;
INIT_DELAYED_WORK(&vdevp->dv.dv_dwork, vdin_dv_dwork);
INIT_DELAYED_WORK(&vdevp->vlock_dwork, vdin_vlock_dwork);
+ vdin_mif_config_init(vdevp); /* 2019-0425 add, ensure mif/afbc bit */
vdin_debugfs_init(vdevp);/*2018-07-18 add debugfs*/
pr_info("%s: driver initialized ok\n", __func__);
return 0;
vdevp = platform_get_drvdata(pdev);
ret = cancel_delayed_work(&vdevp->vlock_dwork);
-#ifdef CONFIG_AML_RDMA
+#ifdef CONFIG_AMLOGIC_MEDIA_RDMA
rdma_unregister(vdevp->rdma_handle);
#endif
mutex_destroy(&vdevp->fe_lock);
#include <linux/amlogic/media/vfm/vframe_receiver.h>
#include <linux/amlogic/media/vfm/vframe_provider.h>
#include <linux/amlogic/media/frame_provider/tvin/tvin_v4l2.h>
-#ifdef CONFIG_AML_RDMA
-#include <linux/amlogic/rdma/rdma_mgr.h>
+#ifdef CONFIG_AMLOGIC_MEDIA_RDMA
+#include <linux/amlogic/media/rdma/rdma_mgr.h>
#endif
/* Local Headers */
#include "vdin_vf.h"
#include "vdin_regs.h"
-#define VDIN_VER "Ref.2018/11/07a"
+/* Ref.2019/04/25: tl1 vdin0 afbce dynamically switch support,
+ * vpp also should support this function
+ */
+#define VDIN_VER "Ref.2019/04/25"
/*the counter of vdin*/
#define VDIN_MAX_DEVS 2
#define VDIN_BYPASS_VGA_CHECK 0x00000008
#define VDIN_CANVAS_MAX_CNT 9
+/*values of vdin game mode process flag */
+#define VDIN_GAME_MODE_0 (1 << 0)
+#define VDIN_GAME_MODE_1 (1 << 1)
+#define VDIN_GAME_MODE_2 (1 << 2)
+#define VDIN_GAME_MODE_SWITCH_EN (1 << 3)
+
/*flag for flush vdin buff*/
#define VDIN_FLAG_BLACK_SCREEN_ON 1
#define VDIN_FLAG_BLACK_SCREEN_OFF 0
/*TXL new add*/
#define VDIN_WR_COLOR_DEPTH_10BIT_FULL_PCAK_MODE (1 << 4)
+/* vdin afbce flag */
+#define VDIN_AFBCE_EN (1 << 0)
+#define VDIN_AFBCE_EN_LOOSY (1 << 1)
+#define VDIN_AFBCE_EN_4K (1 << 4)
+#define VDIN_AFBCE_EN_1080P (1 << 5)
+#define VDIN_AFBCE_EN_720P (1 << 6)
+#define VDIN_AFBCE_EN_SMALL (1 << 7)
static inline const char *vdin_fmt_convert_str(
enum vdin_format_convert_e fmt_cvt)
}
}
+struct vdin_set_canvas_s {
+ int fd;
+ int index;
+};
+
+struct vdin_set_canvas_addr_s {
+ long paddr;
+ int size;
+
+ struct dma_buf *dmabuff;
+ struct dma_buf_attachment *dmabufattach;
+ struct sg_table *sgtable;
+};
+extern struct vdin_set_canvas_addr_s vdin_set_canvas_addr[VDIN_CANVAS_MAX_CNT];
+
/*******for debug **********/
struct vdin_debug_s {
struct tvin_cutwin_s cutwin;
bool dv_flag;
bool dv_config;
bool dv_crc_check;/*0:fail;1:ok*/
+ unsigned int dv_mem_alloced;
};
struct vdin_afbce_s {
struct timer_list timer;
spinlock_t isr_lock;
+ spinlock_t hist_lock;
struct mutex fe_lock;
struct clk *msr_clk;
unsigned int msr_clk_val;
*game_mode:
*bit0:enable/disable
*bit1:for true bypas and put vframe in advance one vsync
+ *bit2:for true bypas and put vframe in advance two vsync,
+ *vdin & vpp read/write same buffer may happen
*/
unsigned int game_mode;
unsigned int rdma_enable;
* 1: use afbce non-mmu mode: head/body addr set by code
* 2: use afbce mmu mode: head set by code, body addr assigning by hw
*/
+ /*afbce_flag:
+ *bit[0]: enable afbce
+ *bit[1]: enable afbce_loosy
+ *bit[4]: afbce enable for 4k
+ *bit[5]: afbce enable for 1080p
+ *bit[6]: afbce enable for 720p
+ *bit[7]: afbce enable for other small resolution
+ */
+ unsigned int afbce_flag;
+ unsigned int afbce_mode_pre;
unsigned int afbce_mode;
+ unsigned int afbce_valid;
+
+ /*fot 'T correction' on projector*/
+ unsigned int set_canvas_manual;
+ unsigned int keystone_vframe_ready;
+ struct vf_entry *keystone_entry[VDIN_CANVAS_MAX_CNT];
unsigned int canvas_config_mode;
bool prehsc_en;
bool vshrk_en;
bool urgent_en;
bool black_bar_enable;
bool hist_bar_enable;
+ unsigned int ignore_frames;
+ unsigned int recycle_frames;
/*use frame rate to cal duraton*/
unsigned int use_frame_rate;
unsigned int irq_cnt;
+ unsigned int frame_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;
-
struct dentry *dbg_root; /*dbg_fs*/
};
+struct vdin_hist_s {
+ ulong sum;
+ int width;
+ int height;
+ int ave;
+};
+
+struct vdin_v4l2_param_s {
+ int width;
+ int height;
+ int fps;
+};
+
+extern unsigned int max_recycle_frame_cnt;
+extern unsigned int max_ignore_frame_cnt;
+extern unsigned int skip_frame_debug;
+
+extern unsigned int vdin0_afbce_debug_force;
+
extern struct vframe_provider_s *vf_get_provider_by_name(
const char *provider_name);
extern bool enable_reset;
extern void ldim_set_matrix(int *data, int reg_sel);
extern void tvafe_snow_config(unsigned int onoff);
extern void tvafe_snow_config_clamp(unsigned int onoff);
-extern void tvafe_snow_config_acd(void);
-extern void tvafe_snow_config_acd_resume(void);
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_debugfs_init(struct vdin_dev_s *vdevp);
extern void vdin_debugfs_exit(struct vdin_dev_s *vdevp);
+extern bool vlock_get_phlock_flag(void);
+
+extern struct vdin_dev_s *vdin_get_dev(unsigned int index);
+extern void vdin_mif_config_init(struct vdin_dev_s *devp);
+
#endif /* __TVIN_VDIN_DRV_H */
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 manual_unstable_out_cnt = 30;
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;
+bool manual_flag;
#ifdef DEBUG_SUPPORT
module_param(back_nosig_max_cnt, int, 0664);
++sm_p->state_cnt;
#ifdef CONFIG_AMLOGIC_MEDIA_TVIN_AFE
if ((port == TVIN_PORT_CVBS3) &&
- (devp->flags & VDIN_FLAG_SNOW_FLAG)) {
+ (devp->flags & VDIN_FLAG_SNOW_FLAG))
tvafe_snow_config_clamp(1);
- /*fix black side when config atv snow*/
- tvafe_snow_config_acd();
- }
#endif
if (sm_ops->nosig(devp->frontend)) {
sm_p->exit_nosig_cnt = 0;
(port == TVIN_PORT_CVBS0)) &&
(devp->flags & VDIN_FLAG_SNOW_FLAG))
unstb_in = sm_p->atv_unstable_out_cnt;
+ else if ((port == TVIN_PORT_CVBS3) &&
+ manual_flag)
+ unstb_in = manual_unstable_out_cnt;
else if ((port >= TVIN_PORT_HDMI0) &&
(port <= TVIN_PORT_HDMI7))
unstb_in = sm_p->hdmi_unstable_out_cnt;
devp->unstable_flag = true;
#ifdef CONFIG_AMLOGIC_MEDIA_TVIN_AFE
if ((port == TVIN_PORT_CVBS3) &&
- (devp->flags & VDIN_FLAG_SNOW_FLAG)) {
+ (devp->flags & VDIN_FLAG_SNOW_FLAG))
tvafe_snow_config_clamp(0);
- /*fix black side when config atv snow*/
- tvafe_snow_config_acd_resume();
- }
#endif
if (sm_ops->nosig(devp->frontend)) {
nosig = true;
int atv_stable_out_cnt;
int hdmi_unstable_out_cnt;
};
+
+extern bool manual_flag;
+
void tvin_smr(struct vdin_dev_s *pdev);
void tvin_smr_init(int index);
void reset_tvin_smr(unsigned int index);
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 < VFRAME_DISP_MAX_NUM; i--)
- p->disp_mode[p->disp_index[i]] = VFRAME_DISP_MODE_UNKNOWN;
+ if (p->disp_mode[p->disp_index[p->skip_vf_num]] !=
+ VFRAME_DISP_MODE_SKIP)
+ p->disp_mode[p->disp_index[p->skip_vf_num]] =
+ VFRAME_DISP_MODE_OK;
+ p->disp_mode[p->disp_index[0]] = VFRAME_DISP_MODE_UNKNOWN;
}
/*disp mode skip
*skip_vf_num
pr_info("**************%s,vencv_line_cur:%d,cnt:%d***********\n",
__func__, vencv_line_cur, cnt);
}
+
+/*g12a/g12b and before: use viu_loop encl/encp*/
+/*tl1: use viu_loop vpp */
static int viuin_open(struct tvin_frontend_s *fe, enum tvin_port_e port)
{
struct viuin_s *devp = container_of(fe, struct viuin_s, frontend);
/*open the venc to vdin path*/
switch (rd_bits_viu(VPU_VIU_VENC_MUX_CTRL, 0, 2)) {
case 0:
- if (is_meson_g12a_cpu() || is_meson_g12b_cpu()
- || is_meson_tl1_cpu())
+ if (is_meson_g12a_cpu() || is_meson_g12b_cpu() ||
+ is_meson_tl1_cpu() || is_meson_sm1_cpu() ||
+ is_meson_tm2_cpu())
viu_mux = 0x4;
else
viu_mux = 0x8;
wr_viu(VPU_VIU2VDIN_HDN_CTRL, 0x40f00);
} else
wr_bits_viu(VPU_VIU2VDIN_HDN_CTRL, devp->parm.h_active, 0, 14);
- if (is_meson_g12a_cpu() || is_meson_g12b_cpu() || is_meson_tl1_cpu()) {
+ if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A)) {
if (((port >= TVIN_PORT_VIU1_WB0_VD1) &&
(port <= TVIN_PORT_VIU1_WB0_POST_BLEND)) ||
((port >= TVIN_PORT_VIU2_WB0_VD1) &&
else if ((port == TVIN_PORT_VIU1_WB0_POST_BLEND) ||
(port == TVIN_PORT_VIU2_WB0_POST_BLEND))
wr_bits_viu(VPP_WRBAK_CTRL, 5, 0, 3);
- else
+ else if ((port == TVIN_PORT_VIU1_WB0_VPP) ||
+ (port == TVIN_PORT_VIU2_WB0_VPP)) {
+ wr_bits_viu(VPP_WRBAK_CTRL, 6, 0, 3);
+ /*increase h banking in case vdin afifo overflow*/
+ wr_bits_viu(VPP_WRBAK_CTRL, 0xff, 16, 8);
+ } else
wr_bits_viu(VPP_WRBAK_CTRL, 0, 4, 3);
+
if ((port == TVIN_PORT_VIU1_WB1_VD1) ||
(port == TVIN_PORT_VIU2_WB1_VD1))
wr_bits_viu(VPP_WRBAK_CTRL, 1, 4, 3);
else if ((port == TVIN_PORT_VIU1_WB1_POST_BLEND) ||
(port == TVIN_PORT_VIU2_WB1_POST_BLEND))
wr_bits_viu(VPP_WRBAK_CTRL, 5, 4, 3);
+ else if ((port == TVIN_PORT_VIU1_WB1_VPP) ||
+ (port == TVIN_PORT_VIU2_WB1_VPP))
+ wr_bits_viu(VPP_WRBAK_CTRL, 6, 4, 3);
else
wr_bits_viu(VPP_WRBAK_CTRL, 0, 4, 3);
+
/*wrback hsync en*/
if (((port >= TVIN_PORT_VIU1_WB0_VD1) &&
(port <= TVIN_PORT_VIU1_WB0_POST_BLEND)) ||
if (open_cnt)
open_cnt--;
if (open_cnt == 0) {
- if (is_meson_g12a_cpu() || is_meson_g12b_cpu()
- || is_meson_tl1_cpu()) {
+ if (is_meson_g12a_cpu() || is_meson_g12b_cpu() ||
+ is_meson_tl1_cpu() || is_meson_sm1_cpu() ||
+ is_meson_tm2_cpu()) {
wr_viu(VPU_VIU_VDIN_IF_MUX_CTRL, 0);
wr_viu(VPP_WRBAK_CTRL, 0);
static const struct vinfo_s *vinfo;
struct viuin_s *devp = container_of(fe, struct viuin_s, frontend);
- if (devp->parm.port == TVIN_PORT_VIU1_VIDEO)
+ switch (devp->parm.port) {
+ case TVIN_PORT_VIU1_VIDEO:
+ case TVIN_PORT_VIU1_WB0_POST_BLEND:
prop->color_format = TVIN_YUV444;
- else if ((devp->parm.port == TVIN_PORT_VIU1) ||
- (devp->parm.port == TVIN_PORT_VIU2)) {
+ break;
+
+ case TVIN_PORT_VIU1:
+ case TVIN_PORT_VIU2:
+ case TVIN_PORT_VIU1_WB0_VPP:
+ case TVIN_PORT_VIU1_WB1_VPP:
+ case TVIN_PORT_VIU2_WB0_VPP:
+ case TVIN_PORT_VIU2_WB1_VPP:
vinfo = get_current_vinfo();
prop->color_format = vinfo->viu_color_fmt;
- } else
+ break;
+
+ default:
prop->color_format = devp->parm.cfmt;
+ break;
+ }
+
prop->dest_cfmt = devp->parm.dfmt;
prop->scaling4w = devp->parm.dest_hactive;
.name = "meson-sm1-cvbsout",
};
+struct meson_cvbsout_data meson_tm2_cvbsout_data = {
+ .cntl0_val = 0x906001,
+ .cpu_id = CVBS_CPU_TYPE_TM2,
+ .name = "meson-tm2-cvbsout",
+};
+
static const struct of_device_id meson_cvbsout_dt_match[] = {
{
.compatible = "amlogic, cvbsout-gxl",
}, {
.compatible = "amlogic, cvbsout-sm1",
.data = &meson_sm1_cvbsout_data,
+ }, {
+ .compatible = "amlogic, cvbsout-tm2",
+ .data = &meson_tm2_cvbsout_data,
},
{},
};
CVBS_CPU_TYPE_G12B = 5,
CVBS_CPU_TYPE_TL1 = 6,
CVBS_CPU_TYPE_SM1 = 7,
+ CVBS_CPU_TYPE_TM2 = 8,
};
struct meson_cvbsout_data {
/*G12A*/
#define HHI_HDMI_PLL_CNTL7 0xce
+/* TL1 */
+#define HHI_TCON_PLL_CNTL0 0x020
+#define HHI_TCON_PLL_CNTL1 0x021
+#define HHI_TCON_PLL_CNTL2 0x022
+#define HHI_TCON_PLL_CNTL3 0x023
+#define HHI_TCON_PLL_CNTL4 0x0df
+
#define HHI_GP0_PLL_CNTL0 0x10
#define HHI_GP0_PLL_CNTL1 0x11
#define HHI_GP0_PLL_CNTL2 0x12
}
if (ret)
pr_info("[error]:hdmi_pll lock failed\n");
+ } else if (cvbs_cpu_type() == CVBS_CPU_TYPE_TL1 ||
+ cvbs_cpu_type() == CVBS_CPU_TYPE_TM2) {
+ cvbs_out_hiu_write(HHI_TCON_PLL_CNTL0, 0x202f04f7);
+ udelay(100);
+ cvbs_out_hiu_write(HHI_TCON_PLL_CNTL0, 0x302f04f7);
+ udelay(100);
+ cvbs_out_hiu_write(HHI_TCON_PLL_CNTL1, 0x10110000);
+ cvbs_out_hiu_write(HHI_TCON_PLL_CNTL2, 0x00001108);
+ cvbs_out_hiu_write(HHI_TCON_PLL_CNTL3, 0x10051400);
+ cvbs_out_hiu_write(HHI_TCON_PLL_CNTL4, 0x010100c0);
+ udelay(100);
+ cvbs_out_hiu_write(HHI_TCON_PLL_CNTL4, 0x038300c0);
+ udelay(100);
+ cvbs_out_hiu_write(HHI_TCON_PLL_CNTL0, 0x342f04f7);
+ udelay(100);
+ cvbs_out_hiu_write(HHI_TCON_PLL_CNTL0, 0x142f04f7);
+ udelay(100);
+ cvbs_out_hiu_write(HHI_TCON_PLL_CNTL2, 0x00003008);
+ udelay(100);
+ ret = pll_wait_lock(HHI_TCON_PLL_CNTL0, 31);
+ if (ret)
+ pr_info("[error]:tl1 tcon_pll lock failed\n");
} else {
pr_info("config eqafter gxl hdmi pll\n");
cvbs_out_hiu_write(HHI_HDMI_PLL_CNTL, 0x4000027b);
cvbs_set_vid1_clk(cvbs_clk_path & 0x1);
else
cvbs_set_vid2_clk(cvbs_clk_path & 0x1);
+ } else if (cvbs_cpu_type() == CVBS_CPU_TYPE_TL1 ||
+ cvbs_cpu_type() == CVBS_CPU_TYPE_TM2) {
+ if (cvbs_clk_path & 0x2)
+ cvbs_set_vid1_clk(0);
+ else
+ cvbs_set_vid2_clk(0);
} else {
cvbs_set_vid2_clk(0);
}
break;
vdac_out_cntl1_bit3(0, VDAC_MODULE_TVAFE);
vdac_out_cntl0_bit10(1, VDAC_MODULE_TVAFE);
- if (s_vdac_data->cpu_id == VDAC_CPU_TL1) {
+ if (s_vdac_data->cpu_id == VDAC_CPU_TL1 ||
+ s_vdac_data->cpu_id == VDAC_CPU_TM2) {
/*[6][8]bypass buffer enable*/
vdac_hiu_reg_setb(HHI_VDAC_CNTL1_G12A, 1, 6, 1);
vdac_hiu_reg_setb(HHI_VDAC_CNTL1_G12A, 1, 8, 1);
}
} else {
ana_ref_cntl0_bit9(0, VDAC_MODULE_TVAFE);
- if (s_vdac_data->cpu_id == VDAC_CPU_TL1) {
+ if (s_vdac_data->cpu_id == VDAC_CPU_TL1 ||
+ s_vdac_data->cpu_id == VDAC_CPU_TM2) {
/*[6][8]bypass buffer disable*/
vdac_hiu_reg_setb(HHI_VDAC_CNTL1_G12A, 0, 6, 1);
vdac_hiu_reg_setb(HHI_VDAC_CNTL1_G12A, 0, 8, 1);
.name = "meson-sm1-vdac",
};
+struct meson_vdac_data meson_tm2_vdac_data = {
+ .cpu_id = VDAC_CPU_TM2,
+ .name = "meson-tm2-vdac",
+};
+
static const struct of_device_id meson_vdac_dt_match[] = {
{
.compatible = "amlogic, vdac-gxtvbb",
}, {
.compatible = "amlogic, vdac-sm1",
.data = &meson_sm1_vdac_data,
+ }, {
+ .compatible = "amlogic, vdac-tm2",
+ .data = &meson_tm2_vdac_data,
},
{},
};
if (s_vdac_data->cpu_id == VDAC_CPU_TXL ||
s_vdac_data->cpu_id == VDAC_CPU_TXLX)
vdac_hiu_reg_write(HHI_VDAC_CNTL0, 0);
+ else if (s_vdac_data->cpu_id == VDAC_CPU_TL1 ||
+ s_vdac_data->cpu_id == VDAC_CPU_TM2)
+ vdac_hiu_reg_setb(HHI_VDAC_CNTL1_G12A, 1, 7, 1);
pr_info("%s: suspend module\n", __func__);
return 0;
}
static int amvdac_drv_resume(struct platform_device *pdev)
{
+ /*0xbc[7] for bandgap enable: 0:enable,1:disable*/
+ if (s_vdac_data->cpu_id == VDAC_CPU_TL1 ||
+ s_vdac_data->cpu_id == VDAC_CPU_TM2)
+ vdac_hiu_reg_setb(HHI_VDAC_CNTL1_G12A, 0, 7, 1);
pr_info("%s: resume module\n", __func__);
return 0;
}
TIMING_MAX,
};
+enum vlock_hw_ver_e {
+ /*gxtvbb*/
+ vlock_hw_org,
+ /*
+ *txl
+ *txlx
+ */
+ vlock_hw_ver1,
+ /* tl1 later
+ * fix bug:i problem
+ * fix bug:affect ss function
+ * add: phase lock
+ */
+ vlock_hw_ver2,
+};
+
+struct vecm_match_data_s {
+ u32 vlk_support;
+ u32 vlk_new_fsm;
+ enum vlock_hw_ver_e vlk_hwver;
+ u32 vlk_phlock_en;
+};
+
/*overscan:
*length 0~31bit :number of crop;
*src_timing: bit31: on: load/save all crop
TVIN_PORT_VIU1_WB0_VD2,
TVIN_PORT_VIU1_WB0_OSD1,
TVIN_PORT_VIU1_WB0_OSD2,
+ TVIN_PORT_VIU1_WB0_VPP,
TVIN_PORT_VIU1_WB0_POST_BLEND,
TVIN_PORT_VIU1_WB1_VD1,
TVIN_PORT_VIU1_WB1_VD2,
TVIN_PORT_VIU1_WB1_OSD1,
TVIN_PORT_VIU1_WB1_OSD2,
+ TVIN_PORT_VIU1_WB1_VPP,
TVIN_PORT_VIU1_WB1_POST_BLEND,
TVIN_PORT_VIU2 = 0x0000C000,
TVIN_PORT_VIU2_VIDEO,
TVIN_PORT_VIU2_WB0_VD2,
TVIN_PORT_VIU2_WB0_OSD1,
TVIN_PORT_VIU2_WB0_OSD2,
+ TVIN_PORT_VIU2_WB0_VPP,
TVIN_PORT_VIU2_WB0_POST_BLEND,
TVIN_PORT_VIU2_WB1_VD1,
TVIN_PORT_VIU2_WB1_VD2,
TVIN_PORT_VIU2_WB1_OSD1,
TVIN_PORT_VIU2_WB1_OSD2,
+ TVIN_PORT_VIU2_WB1_VPP,
TVIN_PORT_VIU2_WB1_POST_BLEND,
TVIN_PORT_MIPI = 0x00010000,
TVIN_PORT_ISP = 0x00020000,
unsigned int is_dvi;
};
+struct tvin_frontend_info_s {
+ enum tvin_scan_mode_e scan_mode;
+ enum tvin_color_fmt_e cfmt;
+ unsigned int fps;
+ unsigned int width;
+ unsigned int height;
+ unsigned int colordepth;
+};
+
struct tvin_buf_info_s {
unsigned int vf_size;
unsigned int buf_count;
enum tvin_force_color_range_e)
#define TVIN_IOC_GAME_MODE _IOW(_TM_T, 0x4b, unsigned int)
#define TVIN_IOC_SET_AUTO_RATIO_EN _IOW(_TM_T, 0x4c, unsigned int)
-
+#define TVIN_IOC_GET_LATENCY_MODE _IOR(_TM_T, 0x4d,\
+ struct tvin_latency_s)
+#define TVIN_IOC_G_FRONTEND_INFO _IOR(_TM_T, 0x4e,\
+ struct tvin_frontend_info_s)
+#define TVIN_IOC_S_CANVAS_ADDR _IOW(_TM_T, 0x4f,\
+ struct vdin_set_canvas_s)
+#define TVIN_IOC_S_CANVAS_RECOVERY _IO(_TM_T, 0x0a)
/* TVAFE */
#define TVIN_IOC_S_AFE_VGA_PARM _IOW(_TM_T, 0x16, struct tvafe_vga_parm_s)
#define TVIN_IOC_G_AFE_VGA_PARM _IOR(_TM_T, 0x17, struct tvafe_vga_parm_s)
#define TVIN_IOC_LOAD_REG _IOW(_TM_T, 0x20, struct am_regs_s)
#define TVIN_IOC_S_AFE_SONWON _IO(_TM_T, 0x22)
#define TVIN_IOC_S_AFE_SONWOFF _IO(_TM_T, 0x23)
+#define TVIN_IOC_G_VDIN_HIST _IOW(_TM_T, 0x24, struct vdin_hist_s)
+#define TVIN_IOC_S_VDIN_V4L2START _IOW(_TM_T, 0x25, struct vdin_v4l2_param_s)
+#define TVIN_IOC_S_VDIN_V4L2STOP _IO(_TM_T, 0x26)
+#define TVIN_IOC_S_AFE_SONWCFG _IOW(_TM_T, 0x27, unsigned int)
/*
*function defined applied for other driver
CAM_MIPI,
};
+#define PARAM_STATE_NULL 0x00000000
+#define PARAM_STATE_HISTGRAM 0x00000001
+#define PARAM_STATE_SCREENCAP 0x00000002
+
/* *********************************************************************** */
/* *** IOCTL command definitions ***************************************** */
unsigned short skip_count; /* for skip frame */
struct csi_parm_s csi_hw_info;
+
/*for reserved */
uintptr_t reserved;
};
#define VIDTYPE_COMPRESS 0x100000
#define VIDTYPE_PIC 0x200000
#define VIDTYPE_SCATTER 0x400000
-#define VIDTYPE_VD2 0x800000
+#define VIDTYPE_VD2 0x800000
#define VIDTYPE_COMPRESS_LOSS 0x1000000
+#define VIDTYPE_COMB_MODE 0x2000000
+#define VIDTYPE_NO_DW 0x4000000
+#define VIDTYPE_SUPPORT_COMPRESS 0x8000000
#define DISP_RATIO_FORCECONFIG 0x80000000
#define DISP_RATIO_FORCE_NORMALWIDE 0x40000000
#define VFRAME_EVENT_RECEIVER_GET_AUX_DATA 0x80
#define VFRAME_EVENT_RECEIVER_DISP_MODE 0x100
#define VFRAME_EVENT_RECEIVER_DOLBY_BYPASS_EL 0x200
+#define VFRAME_EVENT_RECEIVER_NEED_NO_COMP 0x400
/* for VFRAME_EVENT_RECEIVER_GET_AUX_DATA*/
struct provider_aux_req_s {
VDAC_CPU_G12AB = 6,
VDAC_CPU_TL1 = 7,
VDAC_CPU_SM1 = 8,
+ VDAC_CPU_TM2 = 9,
VDAC_CPU_MAX,
};