diff --git a/drivers/media/vin/tvin/dsc_dec/dsc_dec_config.c b/drivers/media/vin/tvin/dsc_dec/dsc_dec_config.c index da0060ec3..e9b91ad56 100644 --- a/drivers/media/vin/tvin/dsc_dec/dsc_dec_config.c +++ b/drivers/media/vin/tvin/dsc_dec/dsc_dec_config.c @@ -7,11 +7,12 @@ #include "dsc_dec_hw.h" #include "dsc_dec_debug.h" #include "dsc_dec_reg.h" +#include "../tvin_global.h" #define MHz 1000000 #define PIX_BAND0 (333 * MHz) -#define PIX_BAND1 (370 * MHz) -#define PIX_BAND2 (408 * MHz) +#define PIX_BAND1 (358 * MHz) +#define PIX_BAND2 (406 * MHz) #define VPU_CLK_DIV_2 1 #define FPLL_DIV3 2 @@ -946,6 +947,15 @@ void dsc_dec_clk_calculate(unsigned int integer, unsigned int frac) void dsc_clk_config(struct aml_dsc_dec_drv_s *dsc_dec_drv) { struct hdmi_dsc_pps_data_s *pps_data = &dsc_dec_drv->pps_data; + u32 tmp; + u32 clk; + + if (pps_data->native_420 == 1 || pps_data->native_422 == 1) + tmp = 2; + else + tmp = 1; + + clk = pps_data->pixel_clk / (pps_data->bits_per_pixel / tmp) * 192; if (dsc_dec_drv->data->chip_type == DSC_DEC_CHIP_T3X) { dsc_dec_config_fix_pll_clk(DSC_CLK_BAND0); @@ -978,7 +988,7 @@ void dsc_clk_config(struct aml_dsc_dec_drv_s *dsc_dec_drv) } } else { if (pps_data->pic_width == 7680 && pps_data->pic_height == 4320) { - set_dsc_clk_cntl(FPLL_DIV3); + set_dsc_clk_cntl(FPLL_DIV3, clk); if (pps_data->pixel_clk <= PIX_BAND0) { //yuv420 ppc setting is different from others. if (dsc_dec_drv->pps_data.native_420) @@ -989,13 +999,20 @@ void dsc_clk_config(struct aml_dsc_dec_drv_s *dsc_dec_drv) dsc_dec_drv->pix_per_clk = 2; } } else { - if ((pps_data->pixel_clk / pps_data->bits_per_pixel * 192 > PIX_BAND0) || + if (clk > PIX_BAND0 || pps_data->dsc_force_4ppc) { dsc_dec_drv->pix_per_clk = 2; - set_dsc_clk_cntl(VPU_CLK_DIV_2); + if (clk <= PIX_BAND1) + dsc_dec_config_fix_pll_clk(DSC_CLK_BAND1); + else if (clk <= PIX_BAND2) + dsc_dec_config_fix_pll_clk(DSC_CLK_BAND2); + else + dsc_dec_config_fix_pll_clk(DSC_CLK_BAND4); + //need vpu clk enhance + set_dsc_clk_cntl(DSC_PIX_PLL, clk); } else { dsc_dec_drv->pix_per_clk = 1; - set_dsc_clk_cntl(FPLL_DIV3); + set_dsc_clk_cntl(FPLL_DIV3, clk); } } } diff --git a/drivers/media/vin/tvin/dsc_dec/dsc_dec_hw.c b/drivers/media/vin/tvin/dsc_dec/dsc_dec_hw.c index 02939c685..b180b58f2 100644 --- a/drivers/media/vin/tvin/dsc_dec/dsc_dec_hw.c +++ b/drivers/media/vin/tvin/dsc_dec/dsc_dec_hw.c @@ -15,12 +15,13 @@ #include "dsc_dec_debug.h" #include "dsc_dec_hw.h" -const unsigned int ctrl0_vals[5][3] = { +const unsigned int ctrl0_vals[6][3] = { [DSC_CLK_BAND0] = {0x20020cc6, 0x30020cc6, 0x10020cc6}, [DSC_CLK_BAND1] = {0x2001083c, 0x3001083c, 0x1001083c}, [DSC_CLK_BAND2] = {0x20010c88, 0x30010c88, 0x10010c88}, [DSC_CLK_BAND3] = {0x20010cc6, 0x30010cc6, 0x10010cc6}, - [DSC_CLK_BAND4] = {0x20010c8c, 0x30010c8c, 0x10010c8c} + [DSC_CLK_BAND4] = {0x20010c8f, 0x30010c8f, 0x10010c8f}, + [DSC_CLK_BAND5] = {0x20010844, 0x30010844, 0x10010844}, }; unsigned int R_DSC_DEC_CLKCTRL_REG(unsigned int reg) diff --git a/drivers/media/vin/tvin/dsc_dec/dsc_dec_hw.h b/drivers/media/vin/tvin/dsc_dec/dsc_dec_hw.h index 47ab9b631..0cbc850a0 100644 --- a/drivers/media/vin/tvin/dsc_dec/dsc_dec_hw.h +++ b/drivers/media/vin/tvin/dsc_dec/dsc_dec_hw.h @@ -11,9 +11,10 @@ enum dsc_clk_band { DSC_CLK_BAND0, //297M DSC_CLK_BAND1, //360M - DSC_CLK_BAND2, //410M - DSC_CLK_BAND3,//594M - DSC_CLK_BAND4 + DSC_CLK_BAND2, //408M + DSC_CLK_BAND3, //594M + DSC_CLK_BAND4, //429M + DSC_CLK_BAND5, //408M }; unsigned int R_DSC_DEC_CLKCTRL_REG(unsigned int reg); diff --git a/drivers/media/vin/tvin/hdmirx/hdmi_rx_drv.c b/drivers/media/vin/tvin/hdmirx/hdmi_rx_drv.c index 9a637c51e..11418859c 100644 --- a/drivers/media/vin/tvin/hdmirx/hdmi_rx_drv.c +++ b/drivers/media/vin/tvin/hdmirx/hdmi_rx_drv.c @@ -29,6 +29,8 @@ #include #include #include +#include + /* #include */ #include #include @@ -124,6 +126,8 @@ struct work_struct clkmsr_dwork; struct workqueue_struct *clkmsr_wq; struct work_struct earc_hpd_dwork; struct workqueue_struct *earc_hpd_wq; +struct work_struct vpu_dwork; +struct workqueue_struct *vpu_wq; struct edid_delayed_work_data edid_reset_work; // edid updata @@ -634,6 +638,8 @@ void hdmirx_dec_stop(struct tvin_frontend_s *fe, enum tvin_port_e port, /* parm->info.fmt = TVIN_SIG_FMT_NULL; */ /* parm->info.status = TVIN_SIG_STATUS_NULL; */ rx_pr("%s port:%d, port_type:%d ok\n", __func__, port - TVIN_PORT_HDMI0, port_type); + if (rx_info.chip_id == CHIP_ID_T6X) + rx_switch_vpu_clk(0); } /* @@ -1738,7 +1744,10 @@ void hdmirx_get_spd_info(struct tvin_frontend_s *fe, port = rx_get_port_from_type(port_type); memcpy(&prop->spd_data, &rx_pkt[port].spd_info, sizeof(struct tvin_spd_data_s)); +} +void __weak dsc_update_vstart(int vstart, int vend, int odd) +{ } void hdmirx_get_pps_info(struct tvin_sig_property_s *prop, u8 port)//todo) @@ -4590,6 +4599,9 @@ static int hdmirx_probe(struct platform_device *pdev) earc_hpd_wq = create_workqueue(hdevp->frontend.name); INIT_WORK(&earc_hpd_dwork, rx_earc_hpd_handler); + vpu_wq = create_workqueue(hdevp->frontend.name); + INIT_WORK(&vpu_dwork, rx_vpu_handler); + INIT_DELAYED_WORK(&edid_reset_work.delayed_work, rx_edid_reset_handler); /* create for frl training */ kthread_init_worker(&frl_worker); diff --git a/drivers/media/vin/tvin/hdmirx/hdmi_rx_drv.h b/drivers/media/vin/tvin/hdmirx/hdmi_rx_drv.h index 9aba6284d..85939c1d5 100644 --- a/drivers/media/vin/tvin/hdmirx/hdmi_rx_drv.h +++ b/drivers/media/vin/tvin/hdmirx/hdmi_rx_drv.h @@ -1217,6 +1217,9 @@ extern struct workqueue_struct *clkmsr_wq; extern struct edid_delayed_work_data edid_reset_work; extern struct work_struct earc_hpd_dwork; extern struct workqueue_struct *earc_hpd_wq; +extern struct work_struct vpu_dwork; +extern struct workqueue_struct *vpu_wq; + extern struct workqueue_struct *repeater_wq; extern struct edid_update_work_s edid_update_dwork; extern struct workqueue_struct *edid_update_wq; diff --git a/drivers/media/vin/tvin/hdmirx/hdmi_rx_frl.c b/drivers/media/vin/tvin/hdmirx/hdmi_rx_frl.c index 2944e6d53..eb02b695b 100644 --- a/drivers/media/vin/tvin/hdmirx/hdmi_rx_frl.c +++ b/drivers/media/vin/tvin/hdmirx/hdmi_rx_frl.c @@ -29,6 +29,8 @@ #include #include #include +#include "../tvin_global.h" + /* Local Include */ #include "hdmi_rx_repeater.h" #include "hdmi_rx_drv.h" @@ -1271,10 +1273,12 @@ void rx_set_dsc_hdmi_cntl(unsigned int val) hdmirx_wr_top_common(TOP_DSC_HDMI_CNTL, val); } -void set_dsc_clk_cntl(int clk_select) +void set_dsc_clk_cntl(int clk_select, int clk) { if (rx_info.chip_id != CHIP_ID_T6X) return; + if (clk >= 406 * MHz && clk_select == H_DSC_PIX_PLL) + schedule_work(&vpu_dwork); if (clk_select == H_VPU_CLK_DIV_2) wr_reg_clk_ctl(CLKCTRL_DSC_CLK_CTRL, 0x343); else if (clk_select == H_FPLL_DIV3) diff --git a/drivers/media/vin/tvin/hdmirx/hdmi_rx_hw.c b/drivers/media/vin/tvin/hdmirx/hdmi_rx_hw.c index 230e0a447..4b95f5aab 100644 --- a/drivers/media/vin/tvin/hdmirx/hdmi_rx_hw.c +++ b/drivers/media/vin/tvin/hdmirx/hdmi_rx_hw.c @@ -30,6 +30,7 @@ #include #include #include +#include /* Local include */ #include "hdmi_rx_eq.h" @@ -8997,3 +8998,9 @@ void hdmi_rx_cor_reset(u8 port) udelay(1); hdmirx_wr_top(TOP_SW_RESET, 0, port); } + +void rx_vpu_handler(struct work_struct *work) +{ + rx_switch_vpu_clk(1); +} + diff --git a/drivers/media/vin/tvin/hdmirx/hdmi_rx_hw.h b/drivers/media/vin/tvin/hdmirx/hdmi_rx_hw.h index ace34ea7c..9b8ff0d98 100644 --- a/drivers/media/vin/tvin/hdmirx/hdmi_rx_hw.h +++ b/drivers/media/vin/tvin/hdmirx/hdmi_rx_hw.h @@ -3799,4 +3799,6 @@ bool hdmi_rx_is_fifo_unnormal(u8 port); void hdmi_rx_frl_pix_chg(u8 port); u32 hdmirx_rd_ee_vol(u32 addr); void hdmirx_wr_ee_vol(u32 addr, u32 data); +void rx_vpu_handler(struct work_struct *work); + #endif diff --git a/drivers/media/vin/tvin/hdmirx/hdmi_rx_wrapper.c b/drivers/media/vin/tvin/hdmirx/hdmi_rx_wrapper.c index 408529abb..cd3087288 100644 --- a/drivers/media/vin/tvin/hdmirx/hdmi_rx_wrapper.c +++ b/drivers/media/vin/tvin/hdmirx/hdmi_rx_wrapper.c @@ -28,6 +28,7 @@ #include #include #include +#include /* Local include */ #include "hdmi_rx_repeater.h" @@ -4281,6 +4282,11 @@ void wait_ddc_idle(u8 port) } } +unsigned int __weak rx_switch_vpu_clk(int over_clock_flag) +{ + return 0; +} + void hdmirx_open_main_port_t3x(u8 port) { if (rx_info.main_port_open && port == rx_info.main_port) @@ -4405,6 +4411,8 @@ void hdmirx_close_port_t3x(u8 port) } rx_emp_hw_enable(false); rx_irq_en(0, port); + if (rx_info.chip_id == CHIP_ID_T6X) + rx_switch_vpu_clk(0); } void hdmirx_close_port(u8 port) diff --git a/drivers/media/vin/tvin/hdmirx/hdmi_rx_wrapper.h b/drivers/media/vin/tvin/hdmirx/hdmi_rx_wrapper.h index dd0199262..ccbad2951 100644 --- a/drivers/media/vin/tvin/hdmirx/hdmi_rx_wrapper.h +++ b/drivers/media/vin/tvin/hdmirx/hdmi_rx_wrapper.h @@ -225,6 +225,8 @@ void rx_edid_update_handler(struct work_struct *dwork); void frate_monitor(void); void frate_monitor1(void); +unsigned int rx_switch_vpu_clk(int over_clock_flag); + void __weak set_video_mute(u32 owner, bool on) { } diff --git a/drivers/media/vin/tvin/tvin_global.h b/drivers/media/vin/tvin/tvin_global.h index d578545fd..5b1585334 100644 --- a/drivers/media/vin/tvin/tvin_global.h +++ b/drivers/media/vin/tvin/tvin_global.h @@ -618,8 +618,5 @@ struct tvin_sig_property_s { #define BT656IN_ANCI_DATA_SIZE 0x4000 /* save anci data from bt656in */ #define CAMERA_IN_ANCI_DATA_SIZE 0x4000 /* save anci data from bt656in */ void dsc_update_vstart(int vstart, int vend, int odd); -void __weak dsc_update_vstart(int vstart, int vend, int odd) -{ -} - +void set_dsc_clk_cntl(int clk_select, int clk); #endif /* __TVIN_GLOBAL_H */ diff --git a/include/uapi/amlogic/hdmi_rx.h b/include/uapi/amlogic/hdmi_rx.h index 75769a3e9..c24398695 100644 --- a/include/uapi/amlogic/hdmi_rx.h +++ b/include/uapi/amlogic/hdmi_rx.h @@ -262,7 +262,6 @@ struct hdmirx_scdc_info { #define HDMI_IOC_AUDIO_DATA_DUMP _IO(HDMI_IOC_MAGIC, 0x1b) void rx_set_dsc_hdmi_cntl(unsigned int val); -void set_dsc_clk_cntl(int clk_select); #endif