dsc dec: choose dsc pll as dsc clk [1/1]

PD#SWPL-239956

Problem:
vpu clk div 2 unnormal.

Solution:
choose dsc pll as dsc clk.

Verify:
T6X

Change-Id: I19017414876ac33601a6793e9a54fedaeb17e7c0
Signed-off-by: yaoyu.xu <yaoyu.xu@amlogic.com>
(cherry picked from commit ff91423113b6fb002b3b4b5677a95d347c1fbd92)
This commit is contained in:
yaoyu.xu
2025-11-17 05:38:38 +00:00
committed by gerrit autosubmit
parent 7f95fe2d5e
commit aff4c40127
12 changed files with 70 additions and 17 deletions
@@ -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);
}
}
}
+3 -2
View File
@@ -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)
+4 -3
View File
@@ -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);
@@ -29,6 +29,8 @@
#include <linux/io.h>
#include <linux/compat.h>
#include <linux/suspend.h>
#include <linux/amlogic/media/vpu/vpu.h>
/* #include <linux/earlysuspend.h> */
#include <linux/delay.h>
#include <linux/of.h>
@@ -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);
@@ -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;
+5 -1
View File
@@ -29,6 +29,8 @@
#include <linux/amlogic/clk_measure.h>
#include <linux/amlogic/media/video_sink/video.h>
#include <uapi/amlogic/hdmi_rx.h>
#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)
@@ -30,6 +30,7 @@
#include <linux/dma-mapping.h>
#include <linux/highmem.h>
#include <linux/amlogic/clk_measure.h>
#include <linux/amlogic/media/vpu/vpu.h>
/* 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);
}
@@ -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
@@ -28,6 +28,7 @@
#include <linux/sched/clock.h>
#include <linux/amlogic/clk_measure.h>
#include <linux/hrtimer.h>
#include <linux/amlogic/media/vpu/vpu.h>
/* 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)
@@ -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)
{
}
+1 -4
View File
@@ -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 */
-1
View File
@@ -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