diff --git a/software/sys_controller/av_controller.c b/software/sys_controller/av_controller.c index 860e323..771f3fa 100644 --- a/software/sys_controller/av_controller.c +++ b/software/sys_controller/av_controller.c @@ -392,7 +392,7 @@ status_t get_status(tvp_sync_input_t syncinput) status = (status < MODE_CHANGE) ? MODE_CHANGE : status; } - if (memcmp(&tc, &cm.cc, offsetof(avconfig_t, sl_mode)) || (update_cur_vm == 1)) + if (memcmp(&tc, &cm.cc, offsetof(avconfig_t, sl_mode)) || (update_cur_vm == 1) || (tc.pc_sog_coast != cm.cc.pc_sog_coast)) status = (status < MODE_CHANGE) ? MODE_CHANGE : status; cm.totlines = totlines; @@ -714,6 +714,12 @@ void program_mode() (alt_u8)h_synclen_px, (alt_8)(cm.cc.clamp_offset-SIGNED_NUMVAL_ZERO), vmode_changed); + + // tvp_source_setup() disables the internal coast signal for PC-type presets, which is correct for RGBHV but + // leaves the H-PLL exposed to vsync serration pulses on sync-on-green / composite-sync inputs. Keep coast + // enabled for those when the option is set (needed e.g. for 13W3 workstation displays). + if ((target_type & VIDEO_PC) && cm.cc.pc_sog_coast && ((target_tvp_sync <= TVP_SOG3) || (target_tvp_sync >= TVP_CS_A))) + tvp_set_coast_enable(1); set_lpf(cm.cc.video_lpf); set_csc(cm.cc.ypbpr_cs); diff --git a/software/sys_controller/ic_drivers/tvp7002/tvp7002.c b/software/sys_controller/ic_drivers/tvp7002/tvp7002.c index 4c67046..2b1b898 100644 --- a/software/sys_controller/ic_drivers/tvp7002/tvp7002.c +++ b/software/sys_controller/ic_drivers/tvp7002/tvp7002.c @@ -180,6 +180,13 @@ inline void tvp_set_hpllcoast(alt_u8 pre, alt_u8 post) tvp_writereg(TVP_HPLLPOSTCOAST, post); } +// Enable/disable the internal H-PLL coast signal (MISCCTRL4 bit 2, "Coast Dis") +void tvp_set_coast_enable(alt_u8 enable) +{ + alt_u8 val = tvp_readreg(TVP_MISCCTRL4) & 0xFB; + tvp_writereg(TVP_MISCCTRL4, val | (enable ? 0x00 : 0x04)); +} + inline void tvp_set_linelen_tol(alt_u8 val) { tvp_writereg(TVP_LINELENTOL, val); } diff --git a/software/sys_controller/ic_drivers/tvp7002/tvp7002.h b/software/sys_controller/ic_drivers/tvp7002/tvp7002.h index f89cb48..0882ddb 100644 --- a/software/sys_controller/ic_drivers/tvp7002/tvp7002.h +++ b/software/sys_controller/ic_drivers/tvp7002/tvp7002.h @@ -90,6 +90,8 @@ inline void tvp_powerup(); inline void tvp_set_hpllcoast(alt_u8 pre, alt_u8 post); +void tvp_set_coast_enable(alt_u8 enable); + inline void tvp_set_linelen_tol(alt_u8 val); inline void tvp_set_ssthold(alt_u8 vsdetect_thold); diff --git a/software/sys_controller/inc/avconfig.h b/software/sys_controller/inc/avconfig.h index de6ed0c..11d54dd 100644 --- a/software/sys_controller/inc/avconfig.h +++ b/software/sys_controller/inc/avconfig.h @@ -159,6 +159,7 @@ typedef struct { alt_u8 full_tx_setup; alt_u8 av3_alt_rgb; avinput_t link_av; + alt_u8 pc_sog_coast; } __attribute__((packed)) avconfig_t; int set_default_profile(int update_cc); diff --git a/software/sys_controller/src/menu.c b/software/sys_controller/src/menu.c index cf6a4bc..a7dbe83 100644 --- a/software/sys_controller/src/menu.c +++ b/software/sys_controller/src/menu.c @@ -248,6 +248,7 @@ MENU(menu_compatibility, P99_PROTECT({ \ { "Default HDMI VIC", OPT_AVCONFIG_NUMVALUE, { .num = { &tc.default_vic, OPT_NOWRAP, 0, HDMI_1080p50, value_disp } } }, { "Panasonic hack", OPT_AVCONFIG_SELECTION, { .sel = { &tc.panasonic_hack, OPT_WRAP, SETTING_ITEM(off_on_desc) } } }, { "Disable PR2x", OPT_AVCONFIG_SELECTION, { .sel = { &tc.hdmi_pr2x_disable, OPT_WRAP, SETTING_ITEM(off_on_desc) } } }, + { "PC SoG/CS coast", OPT_AVCONFIG_SELECTION, { .sel = { &tc.pc_sog_coast, OPT_WRAP, SETTING_ITEM(off_on_desc) } } }, })) MENU(menu_audio, P99_PROTECT({ \ diff --git a/software/sys_controller/src/userdata.c b/software/sys_controller/src/userdata.c index bb61d25..ad43c2c 100644 --- a/software/sys_controller/src/userdata.c +++ b/software/sys_controller/src/userdata.c @@ -144,6 +144,7 @@ const ude_item_map ude_profile_items[] = { UDE_ITEM(67, 120, tc.o480p_pbox), UDE_ITEM(61, 122, tc.hdmi_ar), UDE_ITEM(61, 122, tc.hdmi_pr2x_disable), + UDE_ITEM(68, 122, tc.pc_sog_coast), }; int write_userdata(uint8_t entry) {