diff --git a/arch/arm/boot/dts/amlogic/t6d_pxp.dts b/arch/arm/boot/dts/amlogic/t6d_pxp.dts index 58ef4ed5c..e7247df67 100644 --- a/arch/arm/boot/dts/amlogic/t6d_pxp.dts +++ b/arch/arm/boot/dts/amlogic/t6d_pxp.dts @@ -416,6 +416,7 @@ horizontal_dir1 = <148 168 166 160 148>; horizontal_stp0 = <0 0 0 0 0>; horizontal_stp1 = <0 0 0 0 0>; + macrovision = <1>; }; vbi { diff --git a/arch/arm/boot/dts/amlogic/t6d_t950d5_br301_1.5g.dts b/arch/arm/boot/dts/amlogic/t6d_t950d5_br301_1.5g.dts index 66a4b8acc..6bd0b7c89 100644 --- a/arch/arm/boot/dts/amlogic/t6d_t950d5_br301_1.5g.dts +++ b/arch/arm/boot/dts/amlogic/t6d_t950d5_br301_1.5g.dts @@ -311,6 +311,7 @@ horizontal_dir1 = <148 168 166 160 148>; horizontal_stp0 = <0 0 0 0 0>; horizontal_stp1 = <0 0 0 0 0>; + macrovision = <1>; }; vbi { diff --git a/arch/arm/boot/dts/amlogic/t6d_t950d5_br301_1.5g_linux.dts b/arch/arm/boot/dts/amlogic/t6d_t950d5_br301_1.5g_linux.dts index bce047983..ff9e65dda 100644 --- a/arch/arm/boot/dts/amlogic/t6d_t950d5_br301_1.5g_linux.dts +++ b/arch/arm/boot/dts/amlogic/t6d_t950d5_br301_1.5g_linux.dts @@ -308,6 +308,7 @@ horizontal_dir1 = <148 168 166 160 148>; horizontal_stp0 = <0 0 0 0 0>; horizontal_stp1 = <0 0 0 0 0>; + macrovision = <1>; }; vbi { diff --git a/arch/arm/boot/dts/amlogic/t6d_t950d5_br301_1g.dts b/arch/arm/boot/dts/amlogic/t6d_t950d5_br301_1g.dts index d6bb0a255..7070c8569 100644 --- a/arch/arm/boot/dts/amlogic/t6d_t950d5_br301_1g.dts +++ b/arch/arm/boot/dts/amlogic/t6d_t950d5_br301_1g.dts @@ -311,6 +311,7 @@ horizontal_dir1 = <148 168 166 160 148>; horizontal_stp0 = <0 0 0 0 0>; horizontal_stp1 = <0 0 0 0 0>; + macrovision = <1>; }; vbi { diff --git a/arch/arm/boot/dts/amlogic/t6d_t950d5_br301_1g_linux.dts b/arch/arm/boot/dts/amlogic/t6d_t950d5_br301_1g_linux.dts index edc68990c..e71ade887 100644 --- a/arch/arm/boot/dts/amlogic/t6d_t950d5_br301_1g_linux.dts +++ b/arch/arm/boot/dts/amlogic/t6d_t950d5_br301_1g_linux.dts @@ -305,6 +305,7 @@ horizontal_dir1 = <148 168 166 160 148>; horizontal_stp0 = <0 0 0 0 0>; horizontal_stp1 = <0 0 0 0 0>; + macrovision = <1>; }; vbi { diff --git a/arch/arm/boot/dts/amlogic/t6d_t950d5_br309_1.5g.dts b/arch/arm/boot/dts/amlogic/t6d_t950d5_br309_1.5g.dts index ce697d2e2..76f9d3f2d 100644 --- a/arch/arm/boot/dts/amlogic/t6d_t950d5_br309_1.5g.dts +++ b/arch/arm/boot/dts/amlogic/t6d_t950d5_br309_1.5g.dts @@ -320,6 +320,7 @@ horizontal_dir1 = <148 168 166 160 148>; horizontal_stp0 = <0 0 0 0 0>; horizontal_stp1 = <0 0 0 0 0>; + macrovision = <1>; }; vbi { diff --git a/arch/arm/boot/dts/amlogic/t6d_t950d5_br309_1g.dts b/arch/arm/boot/dts/amlogic/t6d_t950d5_br309_1g.dts index 79e4c8f18..bfb19f6b8 100644 --- a/arch/arm/boot/dts/amlogic/t6d_t950d5_br309_1g.dts +++ b/arch/arm/boot/dts/amlogic/t6d_t950d5_br309_1g.dts @@ -321,6 +321,7 @@ horizontal_dir1 = <148 168 166 160 148>; horizontal_stp0 = <0 0 0 0 0>; horizontal_stp1 = <0 0 0 0 0>; + macrovision = <1>; }; vbi { diff --git a/arch/arm64/boot/dts/amlogic/t6d_t950d5_br301_1.5g.dts b/arch/arm64/boot/dts/amlogic/t6d_t950d5_br301_1.5g.dts index be5b4e355..65fd81fc1 100644 --- a/arch/arm64/boot/dts/amlogic/t6d_t950d5_br301_1.5g.dts +++ b/arch/arm64/boot/dts/amlogic/t6d_t950d5_br301_1.5g.dts @@ -305,6 +305,7 @@ horizontal_dir1 = <148 168 166 160 148>; horizontal_stp0 = <0 0 0 0 0>; horizontal_stp1 = <0 0 0 0 0>; + macrovision = <1>; }; vbi { diff --git a/arch/arm64/boot/dts/amlogic/t6d_t950d5_br301_1g.dts b/arch/arm64/boot/dts/amlogic/t6d_t950d5_br301_1g.dts index aa237b58b..c0aacec35 100644 --- a/arch/arm64/boot/dts/amlogic/t6d_t950d5_br301_1g.dts +++ b/arch/arm64/boot/dts/amlogic/t6d_t950d5_br301_1g.dts @@ -305,6 +305,7 @@ horizontal_dir1 = <148 168 166 160 148>; horizontal_stp0 = <0 0 0 0 0>; horizontal_stp1 = <0 0 0 0 0>; + macrovision = <1>; }; vbi { diff --git a/drivers/media/vin/tvin/hdmirx/hdmi_rx_hw.h b/drivers/media/vin/tvin/hdmirx/hdmi_rx_hw.h index ba94a1c0e..16ee28a6c 100644 --- a/drivers/media/vin/tvin/hdmirx/hdmi_rx_hw.h +++ b/drivers/media/vin/tvin/hdmirx/hdmi_rx_hw.h @@ -1239,7 +1239,7 @@ #define HDCP14_RX_SETKEY 0x8200002d #define HDMIRX_WR_SEC_TOP_NEW 0x8200008c #define HDMIRX_RSV0 0x8200008d -#define HDMIRX_RSV1 0x8200008e +//#define HDMIRX_RSV1 0x8200008e #define HDMIRX_RSV2 0x8200008f #define HDMIRX_RSV3 0x82000091 #define HDMI_RX_HDCP_CFG 0x820000aa diff --git a/drivers/media/vin/tvin/tvafe/tvafe.c b/drivers/media/vin/tvin/tvafe/tvafe.c index 6a752d7c4..eecd1e34a 100644 --- a/drivers/media/vin/tvin/tvafe/tvafe.c +++ b/drivers/media/vin/tvin/tvafe/tvafe.c @@ -37,6 +37,7 @@ /*#include */ #include #include +#include /* Local include */ #include @@ -179,6 +180,7 @@ static struct tvafe_user_param_s tvafe_user_param = { .unlock_cnt_max = 3, .avout_en = 1, + .macrovision = 0, /* cutwin_test_en: * bit[3]: test_vcut @@ -344,6 +346,20 @@ static int tvafe_work_mode(bool mode) return 0; } +u32 tvafe_smc_cmd_handler(u32 index, u32 value) +{ + struct arm_smccc_res res; + + arm_smccc_smc(TVAFE_SMC_CMD, index, + value, 0, 0, 0, 0, 0, &res); + return (u32)((res.a0) & 0xffffffff); +} + +static bool tvafe_cvbs_efuse_macrov_en(void) +{ + return tvafe_smc_cmd_handler(TVAFE_GET_MACROV_STS, 0); +} + static int tvafe_get_v_fmt(void) { int fmt = 0; @@ -1264,6 +1280,10 @@ static void tvafe_get_sig_property(struct tvin_frontend_s *fe, prop->decimation_ratio = 0; prop->dvi_info = 0; prop->skip_vf_num = user_param->skip_vf_num; + if (!user_param->macrovision || !tvafe_cvbs_efuse_macrov_en()) + prop->macrovision_sts = 0; + else + prop->macrovision_sts = tvafe->cvd2.hw.mv_state; } /* @@ -1733,6 +1753,12 @@ static void tvafe_user_parameters_config(struct device_node *of_node) tvafe_user_param.nostd_dmd_clp_step, tvafe_user_param.nostd_bypass_iir); } + ret = of_property_read_u32(of_node, "macrovision", &val[0]); + if (ret == 0) { + tvafe_pr_info("find macrovision: 0x%x\n", val[0]); + tvafe_user_param.macrovision = val[0]; + } + } #ifndef CONFIG_AMLOGIC_REMOVE_OLD diff --git a/drivers/media/vin/tvin/tvafe/tvafe.h b/drivers/media/vin/tvin/tvafe/tvafe.h index d43006647..5cf94822b 100644 --- a/drivers/media/vin/tvin/tvafe/tvafe.h +++ b/drivers/media/vin/tvin/tvafe/tvafe.h @@ -53,6 +53,11 @@ #define TVAFE_PORT_AV2 0x2 #define TVAFE_WSS_FUNCTION BIT(0) +/* smc main cmd */ +#define TVAFE_SMC_CMD 0x8200008e +/* smc sub id */ +#define TVAFE_GET_MACROV_STS 1 + /************************************************************ */ /* *** enum definitions ********************************************* */ @@ -126,6 +131,7 @@ struct tvafe_user_param_s { unsigned int avout_en; unsigned int nostd_bypass_iir; unsigned int low_amp_level; + unsigned int macrovision; /* debug */ unsigned int cutwin_test_en; diff --git a/drivers/media/vin/tvin/tvafe/tvafe_cvd.c b/drivers/media/vin/tvin/tvafe/tvafe_cvd.c index 1c80298bb..469cd9730 100644 --- a/drivers/media/vin/tvin/tvafe/tvafe_cvd.c +++ b/drivers/media/vin/tvin/tvafe/tvafe_cvd.c @@ -952,6 +952,9 @@ static void tvafe_cvd2_get_signal_status(struct tvafe_cvd2_s *cvd2) (bool)((data & 0x04) >> VLOCK_BIT); cvd2->hw_data[cvd2->hw_data_cur].chroma_lock = (bool)((data & 0x08) >> CHROMALOCK_BIT); + cvd2->hw_data[cvd2->hw_data_cur].mv_state = + (bool)((data & 0x10) >> MV_VBI_DETECTED_BIT); + if (cvd2->hw_data[cvd2->hw_data_cur].h_lock) cvd2->info.h_unlock_cnt = 0; else @@ -1166,6 +1169,13 @@ static void tvafe_cvd2_get_signal_status(struct tvafe_cvd2_s *cvd2) !cvd2->hw_data[2].chroma_lock) cvd2->hw.chroma_lock = false; + if (cvd2->hw_data[0].mv_state && cvd2->hw_data[1].mv_state && + cvd2->hw_data[2].mv_state) + cvd2->hw.mv_state = true; + if (!cvd2->hw_data[0].mv_state && !cvd2->hw_data[1].mv_state && + !cvd2->hw_data[2].mv_state) + cvd2->hw.mv_state = false; + if ((cvd2->hw_data[0].pal || cvd2->hw_data[1].pal) && cvd2->hw_data[2].pal) cvd2->hw.pal = true; diff --git a/drivers/media/vin/tvin/tvafe/tvafe_cvd.h b/drivers/media/vin/tvin/tvafe/tvafe_cvd.h index b5816ce3b..0cbac252c 100644 --- a/drivers/media/vin/tvin/tvafe/tvafe_cvd.h +++ b/drivers/media/vin/tvin/tvafe/tvafe_cvd.h @@ -87,6 +87,7 @@ struct tvafe_cvd2_hw_data_s { bool vcrtrick; bool vcrff; bool vcrrew; + bool mv_state; /* microvision state */ unsigned char cordic; unsigned char acc4xx_cnt; diff --git a/drivers/media/vin/tvin/tvafe/tvafe_debug.c b/drivers/media/vin/tvin/tvafe/tvafe_debug.c index 5e5f13f56..515bebaad 100644 --- a/drivers/media/vin/tvin/tvafe/tvafe_debug.c +++ b/drivers/media/vin/tvin/tvafe/tvafe_debug.c @@ -182,7 +182,7 @@ static void tvafe_state(struct tvafe_dev_s *devp) tvafe_pr_info("tvafe_cvd2_hw_data_s->noise_level:%d\n", hw->noise_level); tvafe_pr_info("tvafe_cvd2_hw_data_s->low_amp:%d\n", hw->low_amp); - + tvafe_pr_info("tvafe_cvd2_hw_data_s->mv_state:%d\n", hw->mv_state); tvafe_pr_info("tvafe_cvd2_info_s->isr_cnt:%d\n", cvd2_info->isr_cnt); tvafe_pr_info("tvafe_cvd2_info_s->unlock_cnt:%d\n\n", @@ -239,6 +239,7 @@ static void tvafe_state(struct tvafe_dev_s *devp) tvafe_pr_info("try_fmt_max_atv:%d\n", try_fmt_max_atv); tvafe_pr_info("try_fmt_max_av:%d\n", try_fmt_max_av); tvafe_pr_info("avout_en:%d\n", user_param->avout_en); + tvafe_pr_info("macrovision:%d\n", user_param->macrovision); tvafe_pr_info("tvafe_function_sel:%#x\n", devp->tvafe_function_sel); tvafe_pr_info("tvafe version : %s\n", TVAFE_VER); } diff --git a/drivers/media/vin/tvin/tvin_global.h b/drivers/media/vin/tvin/tvin_global.h index 6a46e7436..9e1e49797 100644 --- a/drivers/media/vin/tvin/tvin_global.h +++ b/drivers/media/vin/tvin/tvin_global.h @@ -599,6 +599,7 @@ struct tvin_sig_property_s { /* only use for loopback, 0=positive, 1=negative */ unsigned int polarity_vs; unsigned int hdcp_sts; /* protected content src. 1:protected 0:not*/ + unsigned int macrovision_sts; }; #define TVAFE_VF_POOL_SIZE 6 /* 8 */ diff --git a/drivers/media/vin/tvin/vdin/vdin_ctl.c b/drivers/media/vin/tvin/vdin/vdin_ctl.c index 47b12e4a4..ccd7e811a 100644 --- a/drivers/media/vin/tvin/vdin/vdin_ctl.c +++ b/drivers/media/vin/tvin/vdin/vdin_ctl.c @@ -7595,8 +7595,11 @@ void vdin_set_matrix_color(struct vdin_dev_s *devp) return; } #endif - /*vdin bist mode RGB:black*/ - wr(offset, VDIN_MATRIX_CTRL, 0x4); + /*vdin bist mode RGB:black, for T6D, vdin0 use matrix0*/ + if (is_meson_t6d_cpu() && devp->hw_core == VDIN_HW_CORE_NORMAL) + wr(offset, VDIN_MATRIX_CTRL, 0x0); + else + wr(offset, VDIN_MATRIX_CTRL, 0x4); wr(offset, VDIN_MATRIX_COEF00_01, 0x0); wr(offset, VDIN_MATRIX_COEF02_10, 0x0); wr(offset, VDIN_MATRIX_COEF11_12, 0x0); @@ -7632,7 +7635,10 @@ void vdin_set_matrix_color(struct vdin_dev_s *devp) } if (mode) { - wr(offset, VDIN_MATRIX_CTRL, 0x6); + if (is_meson_t6d_cpu() && devp->hw_core == VDIN_HW_CORE_NORMAL) + wr(offset, VDIN_MATRIX_CTRL, 0x1); + else + wr(offset, VDIN_MATRIX_CTRL, 0x6); } else { if (vdin_is_rgb_input(devp->prop.color_format)) vdin_set_matrix(devp); diff --git a/drivers/media/vin/tvin/vdin/vdin_debug.c b/drivers/media/vin/tvin/vdin/vdin_debug.c index 4a8a85605..04d56bd2e 100644 --- a/drivers/media/vin/tvin/vdin/vdin_debug.c +++ b/drivers/media/vin/tvin/vdin/vdin_debug.c @@ -1141,6 +1141,7 @@ static void vdin_dump_state(struct vdin_dev_s *devp) pr_info("color_depth_config:0x%x\n", devp->color_depth_config); pr_info("matrix_pattern_mode:0x%x\n", devp->matrix_pattern_mode); pr_info("hdcp_sts:0x%x\n", devp->prop.hdcp_sts); + pr_info("macrovision_sts:0x%x\n", devp->prop.macrovision_sts); pr_info("full_pack:%d\n", devp->full_pack); pr_info("force_malloc_yuv_422_to_444:%d\n", devp->force_malloc_yuv_422_to_444); pr_info("color_depth_support:0x%x\n", devp->color_depth_support); diff --git a/drivers/media/vin/tvin/vdin/vdin_drv.c b/drivers/media/vin/tvin/vdin/vdin_drv.c index dbff4072e..97de93a43 100644 --- a/drivers/media/vin/tvin/vdin/vdin_drv.c +++ b/drivers/media/vin/tvin/vdin/vdin_drv.c @@ -1865,6 +1865,7 @@ void vdin_stop_dec(struct vdin_dev_s *devp) devp->unreliable_vs_cnt_pre = 0; devp->unreliable_vs_idx = 0; devp->prop.hdcp_sts = 0; + devp->prop.macrovision_sts = 0; devp->starting_chg = 0; devp->vdin_stable_cnt = 0; devp->game_mode = 0; @@ -1980,28 +1981,28 @@ int start_tvin_service(int no, struct vdin_parm_s *para) } if (!IS_ERR_OR_NULL(vdin0_devp)) { - vdin0_devp->pre_prop.hdcp_sts = vdin0_devp->prop.hdcp_sts; devp->matrix_pattern_mode = 0; /* check input content is protected */ if ((vdin0_devp->flags & VDIN_FLAG_DEC_OPENED) && (vdin0_devp->flags & VDIN_FLAG_DEC_STARTED) && !devp->set_canvas_manual) { - if (vdin0_devp->prop.hdcp_sts && !devp->mem_protected) { - pr_err("hdmi hdcp en, non-secure buffer\n"); - devp->matrix_pattern_mode = VDIN_HDCP_PATTERN; + if ((vdin0_devp->prop.hdcp_sts || vdin0_devp->prop.macrovision_sts) && + !devp->mem_protected) { + pr_err("hdmi or tvafe secure en, non-secure buffer\n"); + devp->matrix_pattern_mode = VDIN_SECURE_PATTERN; } else { - pr_err("non-hdcp or hdcp with secure buffer.sts:%d,flg:%d\n", - vdin0_devp->prop.hdcp_sts, devp->mem_protected); + pr_info("non-hdcp or hdcp with secure buffer.sts:%d, macrovision_sts:%d, protected:%d\n", + vdin0_devp->prop.hdcp_sts, vdin0_devp->prop.macrovision_sts, + devp->mem_protected); devp->matrix_pattern_mode = 0; } } else { - vdin0_devp->prop.hdcp_sts = 0; devp->matrix_pattern_mode = 0; } if (vdin_dbg_en) - pr_info("vdin0 port:0x%x, flag:0x%x, hdcp sts:%d matrix:%d\n", - vdin0_devp->parm.port, vdin0_devp->flags, - vdin0_devp->prop.hdcp_sts, devp->matrix_pattern_mode); + pr_info("vdin0 port:0x%x, flag:0x%x, hdcp sts:%d, macrovision_sts:%d, matrix:%d\n", + vdin0_devp->parm.port, vdin0_devp->flags, vdin0_devp->prop.hdcp_sts, + vdin0_devp->prop.macrovision_sts, devp->matrix_pattern_mode); } mutex_lock(&devp->fe_lock); @@ -3231,7 +3232,10 @@ static void vdin_handle_secure_content(struct vdin_dev_s *devp) return; /* check input content is protected */ - protect_mode = devp->prop.hdcp_sts ? VDIN_HDCP_PATTERN : 0; + if (devp->prop.hdcp_sts || devp->prop.macrovision_sts) + protect_mode = VDIN_SECURE_PATTERN; + else + protect_mode = 0; if (protect_mode != devp->matrix_pattern_mode && !loopback_devp->mem_protected && loopback_devp->set_canvas_manual && (loopback_devp->flags & VDIN_FLAG_DEC_STARTED)) { @@ -3957,23 +3961,27 @@ static void vdin_set_vfe_type(struct vdin_dev_s *devp, struct vf_entry *vfe) vfe->vf.type_ext &= ~VIDTYPE_EXT_VDIN_HDCP; } -/* hdcp state change,set or recovery vdin1 matrix */ -static void vdin_handle_hdcp_chg(struct vdin_dev_s *devp) +/* hdcp or macrovision state change,set or recovery vdin1 matrix */ +static void vdin_v4l2_handle_secure_chg(struct vdin_dev_s *devp) { struct vdin_dev_s *vdin0_devp = vdin_devp[0]; unsigned int protect_mode = 0; if (vdin0_devp) { /* May not probe vdin0 */ - protect_mode = vdin0_devp->prop.hdcp_sts ? VDIN_HDCP_PATTERN : 0; + if (vdin0_devp->prop.hdcp_sts || vdin0_devp->prop.macrovision_sts) + protect_mode = VDIN_SECURE_PATTERN; + else + protect_mode = 0; if (protect_mode != devp->matrix_pattern_mode && !devp->mem_protected && !devp->set_canvas_manual && (vdin0_devp->flags & VDIN_FLAG_DEC_OPENED) && (vdin0_devp->flags & VDIN_FLAG_DEC_STARTED)) { devp->matrix_pattern_mode = protect_mode; - pr_debug("vdin0:hdcp chg to %d,protect_mode:%d\n", - vdin0_devp->prop.hdcp_sts, protect_mode); + pr_debug("vdin0:hdcp chg to %d, macrovision chg to %d, protect_mode:%d\n", + vdin0_devp->prop.hdcp_sts, vdin0_devp->prop.macrovision_sts, + protect_mode); vdin_set_matrix(devp); - } else if ((devp->matrix_pattern_mode == VDIN_HDCP_PATTERN) && + } else if ((devp->matrix_pattern_mode == VDIN_SECURE_PATTERN) && !(vdin0_devp->flags & VDIN_FLAG_DEC_STARTED)) { devp->matrix_pattern_mode = 0; pr_debug("set vdin1 matrix to normal\n"); @@ -4047,7 +4055,7 @@ irqreturn_t vdin_v4l2_isr(int irq, void *dev_id) /* avoid null pointer oops */ stamp = vdin_get_meas_v_stamp(devp); - vdin_handle_hdcp_chg(devp); + vdin_v4l2_handle_secure_chg(devp); /* if win_size changed for video only */ if (!(devp->flags & VDIN_FLAG_V4L2_DEBUG)) diff --git a/drivers/media/vin/tvin/vdin/vdin_drv.h b/drivers/media/vin/tvin/vdin/vdin_drv.h index b638c84f6..cfee3cbfe 100644 --- a/drivers/media/vin/tvin/vdin/vdin_drv.h +++ b/drivers/media/vin/tvin/vdin/vdin_drv.h @@ -460,7 +460,7 @@ enum vdin_vf_put_md { #define CURRENT_FRAME_GET_PROP BIT(0) //pattern 4 used for protect hdcp content,others for debug -#define VDIN_HDCP_PATTERN 4 +#define VDIN_SECURE_PATTERN 4 /* *********************************************************************** */ /* *** enum definitions ********************************************* */