1
0
mirror of https://github.com/marqs85/ossc.git synced 2026-04-20 13:16:50 +00:00

Improve lo-res mode processing features

* workaround for phase shift issue on optimized modes
* add hscale option for 256x240 opt Line3x mode
* distribute video modes to groups and allow passthru for all modes
This commit is contained in:
marqs
2017-01-23 00:56:17 +02:00
parent a03c01ca4d
commit 434186d64e
19 changed files with 2485 additions and 1440 deletions
File diff suppressed because it is too large Load Diff
+53 -37
View File
@@ -192,6 +192,7 @@ status_t get_status(tvp_input_t input, video_format format)
static alt_8 act_ctr;
alt_u32 ctr;
int valid_linecnt;
alt_u8 h_mult;
status = NO_CHANGE;
@@ -264,10 +265,16 @@ status_t get_status(tvp_input_t input, video_format format)
status = (status < MODE_CHANGE) ? MODE_CHANGE : status;
}
if ((tc.linemult_target != cm.cc.linemult_target) || (tc.l3_mode != cm.cc.l3_mode))
if ((tc.pm_240p != cm.cc.pm_240p) ||
(tc.pm_384p != cm.cc.pm_384p) ||
(tc.pm_480i != cm.cc.pm_480i) ||
(tc.pm_480p != cm.cc.pm_480p) ||
(tc.l3_mode != cm.cc.l3_mode) ||
(tc.l4_mode != cm.cc.l4_mode) ||
(tc.l5_mode != cm.cc.l5_mode))
status = (status < MODE_CHANGE) ? MODE_CHANGE : status;
if ((tc.s480p_mode != cm.cc.s480p_mode) && (video_modes[cm.id].flags & (MODE_DTV480P|MODE_VGA480P)))
if ((tc.s480p_mode != cm.cc.s480p_mode) && ((video_modes[cm.id].group == GROUP_DTV480P) || (video_modes[cm.id].group == GROUP_VGA480P)))
status = (status < MODE_CHANGE) ? MODE_CHANGE : status;
if (update_cur_vm) {
@@ -278,7 +285,7 @@ status_t get_status(tvp_input_t input, video_format format)
tvp_writereg(TVP_HPLLDIV_LSB, ((h_samplerate & 0xf) << 4));
tvp_writereg(TVP_HPLLDIV_MSB, (h_samplerate >> 4));
tvp_writereg(TVP_HSOUTWIDTH, video_modes[cm.id].h_synclen);
tvp_writereg(TVP_HSOUTWIDTH, cm.sample_mult*video_modes[cm.id].h_synclen);
status = (status < INFO_CHANGE) ? INFO_CHANGE : status;
}
@@ -294,12 +301,13 @@ status_t get_status(tvp_input_t input, video_format format)
(tc.sl_id != cm.cc.sl_id) ||
(tc.h_mask != cm.cc.h_mask) ||
(tc.v_mask != cm.cc.v_mask) ||
(tc.edtv_l2x != cm.cc.edtv_l2x) ||
(tc.interlace_pt != cm.cc.interlace_pt))
(tc.l3m3_hmult != cm.cc.l3m3_hmult))
status = (status < INFO_CHANGE) ? INFO_CHANGE : status;
if (tc.sampler_phase != cm.cc.sampler_phase)
tvp_set_hpll_phase(tc.sampler_phase);
if (tc.sampler_phase != cm.cc.sampler_phase) {
cm.sample_sel = tvp_set_hpll_phase(tc.sampler_phase, cm.sample_mult);
status = (status < INFO_CHANGE) ? INFO_CHANGE : status;
}
if (tc.sync_vth != cm.cc.sync_vth)
tvp_set_sog_thold(tc.sync_vth);
@@ -342,54 +350,58 @@ status_t get_status(tvp_input_t input, video_format format)
return status;
}
// h_info: [31:30] [29:28] [27:22] [21] [20:10] [9:8] [7:0]
// | H_LINEMULT[1:0] | H_L3MODE[1:0] | H_MASK[5:0] | | H_ACTIVE[10:0] | | H_BACKPORCH[7:0] |
// h_info: [31:28] [27:26] [25:20] [19:9] [8] [7:0]
// | H_SCANLINESTR[3:0] | H_MULTMODE[1:0] | H_MASK[5:0] | H_ACTIVE[10:0] | | H_BACKPORCH[7:0] |
//
// v_info: [31:30] [29:28] [27] [26:24] [23:18] [17:7] [6] [5:0]
// | V_SCANLINEMODE[1:0] | V_SCANLINEID | | V_MULTMODE[2:0] | V_MASK[5:0] | V_ACTIVE[10:0] | | V_BACKPORCH[5:0] |
//
// hscale_info: [31:19] [18:16] [15:13] [12:10] [9:0]
// | | H_OPT_SCALE[2:0] | H_OPT_SAMPLE_SEL[2:0] | H_OPT_SAMPLE_MULT[2:0] | H_OPT_STARTOFF[9:0]
//
// v_info: [31] [30] [29:28] [27:24] [23:18] [17:7] [6] [5:0]
// | V_SCANLINES | V_SCANLINEDIR | V_SCANLINEID | V_SCANLINESTR[3:0] | V_MASK[5:0] | V_ACTIVE[10:0] | | V_BACKPORCH[5:0] |
void set_videoinfo()
{
alt_u8 slid_target;
alt_u8 sl_mode_fpga;
alt_u8 h_opt_scale = 0;
alt_u16 h_opt_startoffs = 0;
if (video_modes[cm.id].flags & MODE_L3ENABLE_MASK) {
cm.linemult = 2;
if (cm.fpga_vmultmode == FPGA_V_MULTMODE_3X)
slid_target = cm.cc.sl_id ? (cm.cc.sl_type == 1 ? 1 : 2) : 0;
} else if ((video_modes[cm.id].flags & MODE_L2ENABLE) || (cm.cc.edtv_l2x && (video_modes[cm.id].type & VIDEO_EDTV))) {
cm.linemult = 1;
else
slid_target = cm.cc.sl_id;
} else {
cm.linemult = 0;
slid_target = cm.cc.sl_id;
}
if (cm.cc.sl_mode == 2) { //manual
sl_mode_fpga = 1+cm.cc.sl_type;
} else if (cm.cc.sl_mode == 1) { //auto
if (video_modes[cm.id].flags & MODE_INTERLACED)
sl_mode_fpga = 3;
else if (video_modes[cm.id].flags & (MODE_L2ENABLE|MODE_L3ENABLE_MASK))
sl_mode_fpga = 1;
sl_mode_fpga = cm.fpga_vmultmode ? FPGA_SCANLINEMODE_ALT : FPGA_SCANLINEMODE_OFF;
else if (cm.fpga_vmultmode)
sl_mode_fpga = FPGA_SCANLINEMODE_H;
else
sl_mode_fpga = 0;
sl_mode_fpga = FPGA_SCANLINEMODE_OFF;
} else {
sl_mode_fpga = 0;
sl_mode_fpga = FPGA_SCANLINEMODE_OFF;
}
if ((cm.cc.interlace_pt) && (video_modes[cm.id].flags & MODE_INTERLACED)) {
cm.linemult = 0;
sl_mode_fpga = 0;
switch (cm.target_lm) {
case MODE_L3_320_COL:
h_opt_scale = 3;
break;
case MODE_L3_256_COL:
h_opt_scale = cm.cc.l3m3_hmult;
break;
default:
break;
}
IOWR_ALTERA_AVALON_PIO_DATA(PIO_2_BASE, (cm.linemult<<30) | (cm.cc.l3_mode<<28) | (cm.cc.h_mask)<<22 | (video_modes[cm.id].h_active<<10) | video_modes[cm.id].h_backporch);
IOWR_ALTERA_AVALON_PIO_DATA(PIO_3_BASE, (sl_mode_fpga<<30) | (slid_target<<28) | (cm.cc.sl_str<<24) | (cm.cc.v_mask<<18) | (video_modes[cm.id].v_active<<7) | video_modes[cm.id].v_backporch);
h_opt_startoffs = (((cm.sample_mult-h_opt_scale)*video_modes[cm.id].h_active)/2) + ((cm.sample_mult-h_opt_scale)*(cm.sample_mult*video_modes[cm.id].h_backporch) / cm.sample_mult);
h_opt_startoffs = (h_opt_startoffs/cm.sample_mult)*cm.sample_mult;
printf("h_opt_startoffs: %u\n", h_opt_startoffs);
if (video_modes[cm.id].type & VIDEO_EDTV)
HDMITX_SetPixelRepetition(cm.cc.edtv_l2x, 0);
else if (video_modes[cm.id].flags & MODE_INTERLACED)
HDMITX_SetPixelRepetition(cm.cc.interlace_pt, (cm.cc.tx_mode==TX_HDMI));
else
HDMITX_SetPixelRepetition(0, 0);
IOWR_ALTERA_AVALON_PIO_DATA(PIO_2_BASE, (cm.cc.sl_str<<28) | (cm.fpga_hmultmode<<26) | (cm.cc.h_mask<<20) | ((cm.sample_mult*video_modes[cm.id].h_active)<<9) | cm.sample_mult*video_modes[cm.id].h_backporch);
IOWR_ALTERA_AVALON_PIO_DATA(PIO_3_BASE, (sl_mode_fpga<<30) | (slid_target<<28) | (cm.fpga_vmultmode<<24) | (cm.cc.v_mask<<18) | (video_modes[cm.id].v_active<<7) | video_modes[cm.id].v_backporch);
IOWR_ALTERA_AVALON_PIO_DATA(PIO_5_BASE, (h_opt_scale<<16) | (cm.sample_sel<<13) | (cm.sample_mult<<10) | h_opt_startoffs);
}
// Configure TVP7002 and scan converter logic based on the video mode
@@ -422,7 +434,7 @@ void program_mode()
lcd_write_status();
//printf ("Get mode id with %u %u %f\n", totlines, progressive, hz);
cm.id = get_mode_id(cm.totlines, cm.progressive, v_hz_x100/100, target_typemask, cm.cc.linemult_target, cm.cc.l3_mode, cm.cc.s480p_mode);
cm.id = get_mode_id(cm.totlines, cm.progressive, v_hz_x100/100, target_typemask);
if (cm.id == -1) {
printf ("Error: no suitable mode found, defaulting to 240p\n");
@@ -435,8 +447,12 @@ void program_mode()
printf("Mode %s selected - hsync width: %upx\n", video_modes[cm.id].name, (unsigned)h_synclen_px);
tvp_source_setup(cm.id, target_type, (cm.progressive ? cm.totlines : cm.totlines/2), v_hz_x100/100, (alt_u8)h_synclen_px, cm.cc.pre_coast, cm.cc.post_coast, cm.cc.vsync_thold);
tvp_source_setup(cm.id, target_type, (cm.progressive ? cm.totlines : cm.totlines/2), v_hz_x100/100, (alt_u8)h_synclen_px, cm.cc.pre_coast, cm.cc.post_coast, cm.cc.vsync_thold, cm.sample_mult);
set_lpf(cm.cc.video_lpf);
cm.sample_sel = tvp_set_hpll_phase(cm.cc.sampler_phase, cm.sample_mult);
HDMITX_SetPixelRepetition(cm.hdmitx_pixelrep, (cm.cc.tx_mode==TX_HDMI) ? cm.hdmitx_pixr_ifr : 0);
set_videoinfo();
#ifdef DIY_AUDIO
+31 -4
View File
@@ -23,9 +23,7 @@
#include "avconfig.h"
#include "sysconfig.h"
#define HDMITX_MODE_MASK 0x00040000
//sys_ctrl bits
// sys_ctrl bits
#define SD_SPI_SS_N (1<<7)
#define LCD_CS_N (1<<6)
#define LCD_RS (1<<5)
@@ -33,6 +31,29 @@
#define VIDGEN_OFF (1<<1)
#define AV_RESET_N (1<<0)
// HDMI_TX definitions
#define HDMITX_MODE_MASK 0x00040000
#define HDMITX_PIXELREP_DISABLE 0
#define HDMITX_PIXELREP_2X 1
#define HDMITX_PIXELREP_4X 2
// FPGA macros
#define FPGA_V_MULTMODE_1X 0
#define FPGA_V_MULTMODE_2X 1
#define FPGA_V_MULTMODE_3X 2
#define FPGA_V_MULTMODE_4X 3
#define FPGA_V_MULTMODE_5X 4
#define FPGA_H_MULTMODE_FULLWIDTH 0
#define FPGA_H_MULTMODE_ASPECTFIX 1
#define FPGA_H_MULTMODE_OPTIMIZED 2
#define FPGA_SCANLINEMODE_OFF 0
#define FPGA_SCANLINEMODE_H 1
#define FPGA_SCANLINEMODE_V 2
#define FPGA_SCANLINEMODE_ALT 3
static const char *avinput_str[] = { "Test pattern", "AV1: RGBS", "AV1: RGsB", "AV1: YPbPr", "AV2: YPbPr", "AV2: RGsB", "AV3: RGBHV", "AV3: RGBS", "AV3: RGsB", "AV3: YPbPr", "Last used" };
typedef enum {
@@ -71,7 +92,13 @@ typedef struct {
alt_u8 macrovis;
alt_8 id;
alt_u8 sync_active;
alt_u8 linemult;
alt_u8 fpga_vmultmode;
alt_u8 fpga_hmultmode;
alt_u8 hdmitx_pixelrep;
alt_u8 hdmitx_pixr_ifr;
alt_u8 sample_mult;
alt_u8 sample_sel;
mode_flags target_lm;
avinput_t avinput;
// Current configuration
avconfig_t cc;
+6
View File
@@ -41,6 +41,12 @@ avconfig_t tc;
// Default configuration
const avconfig_t tc_default = {
.l3_mode = 1,
.l5_mode = 1,
.pm_240p = 1,
.pm_384p = 1,
.pm_480i = 1,
.l3m3_hmult = 4,
.sampler_phase = DEFAULT_SAMPLER_PHASE,
.sync_vth = DEFAULT_SYNC_VTH,
.linelen_tol = DEFAULT_LINELEN_TOL,
+7 -3
View File
@@ -35,7 +35,6 @@
#define SL_MODE_MAX 2
#define SL_TYPE_MAX 2
#define LM_MODE_MAX 1
typedef struct {
alt_u8 sl_mode;
@@ -44,6 +43,13 @@ typedef struct {
alt_u8 sl_id;
alt_u8 linemult_target;
alt_u8 l3_mode;
alt_u8 l4_mode;
alt_u8 l5_mode;
alt_u8 pm_240p;
alt_u8 pm_384p;
alt_u8 pm_480i;
alt_u8 pm_480p;
alt_u8 l3m3_hmult;
alt_u8 h_mask;
alt_u8 v_mask;
alt_u8 tx_mode;
@@ -61,8 +67,6 @@ typedef struct {
alt_u8 audio_dw_sampl;
alt_u8 audio_swap_lr;
#endif
alt_u8 edtv_l2x;
alt_u8 interlace_pt;
alt_u8 def_input;
color_setup_t col;
} __attribute__((packed)) avconfig_t;
+1 -1
View File
@@ -155,7 +155,7 @@ void parse_control()
case RC_SL_TYPE: tc.sl_type = (tc.sl_type < SL_TYPE_MAX) ? (tc.sl_type + 1) : 0; break;
case RC_SL_MINUS: tc.sl_str = tc.sl_str ? (tc.sl_str - 1) : 0; break;
case RC_SL_PLUS: tc.sl_str = (tc.sl_str < SCANLINESTR_MAX) ? (tc.sl_str + 1) : SCANLINESTR_MAX; break;
case RC_LM_MODE: tc.linemult_target = (tc.linemult_target < LM_MODE_MAX) ? (tc.linemult_target + 1) : 0; break;
//case RC_LM_MODE: tc.linemult_target = (tc.linemult_target < LM_MODE_MAX) ? (tc.linemult_target + 1) : 0; break;
case RC_PHASE_PLUS: tc.sampler_phase = (tc.sampler_phase < SAMPLER_PHASE_MAX) ? (tc.sampler_phase + 1) : 0; break;
case RC_PHASE_MINUS: tc.sampler_phase = tc.sampler_phase ? (tc.sampler_phase - 1) : SAMPLER_PHASE_MAX; break;
case RC_PROF_HOTKEY:
+1 -1
View File
@@ -24,7 +24,7 @@
#include "sysconfig.h"
#define FW_VER_MAJOR 0
#define FW_VER_MINOR 75
#define FW_VER_MINOR 76
#ifdef DIY_AUDIO
#define FW_SUFFIX1 "a"
+14 -4
View File
@@ -49,6 +49,12 @@ static const char *ypbpr_cs_desc[] = { "Rec. 601", "Rec. 709" };
static const char *s480p_mode_desc[] = { LNG("Auto","ジドウ"), "DTV 480p", "VESA 640x480@60" };
static const char *sync_lpf_desc[] = { LNG("Off","オフ"), LNG("33MHz (min)","33MHz (サイショウ)"), LNG("10MHz (med)","10MHz (チュウイ)"), LNG("2.5MHz (max)","2.5MHz (サイダイ)") };
static const char *l3_mode_desc[] = { LNG("Generic 16:9","ハンヨウ 16:9"), LNG("Generic 4:3","ハンヨウ 4:3"), LNG("320x240 optim.","320x240 サイテキ."), LNG("256x240 optim.","256x240 サイテキ.") };
static const char *l4_mode_desc[] = { LNG("Generic 4:3","ハンヨウ 4:3"), LNG("320x240 optim.","320x240 サイテキ."), LNG("256x240 optim.","256x240 サイテキ.") };
//static const char *pm_240p_desc[] = { "Passthru", "Line2x", "Line3x", "Line4x", "Line5x" };
static const char *pm_240p_desc[] = { "Passthru", "Line2x", "Line3x" };
static const char *pm_384p_desc[] = { "Passthru", "Line2x" };
static const char *pm_480i_desc[] = { "Passthru", "Line2x" };
static const char *pm_480p_desc[] = { "Passthru", "Line2x" };
static const char *tx_mode_desc[] = { "HDMI", "DVI" };
static const char *sl_mode_desc[] = { LNG("Off","オフ"), LNG("Auto","ジドウ"), LNG("Manual","シュドウ") };
static const char *sl_type_desc[] = { LNG("Horizontal","スイヘイ"), LNG("Vertical","スイチョク"), LNG("Alternating","コウゴ") };
@@ -101,10 +107,14 @@ MENU(menu_sync, P99_PROTECT({ \
}))
MENU(menu_output, P99_PROTECT({ \
{ LNG("240p/288p lineX3","240p/288pラインX3"), OPT_AVCONFIG_SELECTION, { .sel = { &tc.linemult_target, OPT_WRAP, SETTING_ITEM(off_on_desc) } } },
{ LNG("Linetriple mode","ライントリプルモード"), OPT_AVCONFIG_SELECTION, { .sel = { &tc.l3_mode, OPT_WRAP, SETTING_ITEM(l3_mode_desc) } } },
{ LNG("480p/576p lineX2","480p/576pラインX2"), OPT_AVCONFIG_SELECTION, { .sel = { &tc.edtv_l2x, OPT_WRAP, SETTING_ITEM(off_on_desc) } } },
{ LNG("480i/576i passtr","480i/576iパススルー"), OPT_AVCONFIG_SELECTION, { .sel = { &tc.interlace_pt, OPT_WRAP, SETTING_ITEM(off_on_desc) } } },
{ "240p/288p proc", OPT_AVCONFIG_SELECTION, { .sel = { &tc.pm_240p, OPT_WRAP, SETTING_ITEM(pm_240p_desc) } } },
{ "384p proc", OPT_AVCONFIG_SELECTION, { .sel = { &tc.pm_384p, OPT_WRAP, SETTING_ITEM(pm_384p_desc) } } },
{ "480i/576i proc", OPT_AVCONFIG_SELECTION, { .sel = { &tc.pm_480i, OPT_WRAP, SETTING_ITEM(pm_480i_desc) } } },
{ "480p/576p proc", OPT_AVCONFIG_SELECTION, { .sel = { &tc.pm_480p, OPT_WRAP, SETTING_ITEM(pm_480p_desc) } } },
{ "Line3x mode", OPT_AVCONFIG_SELECTION, { .sel = { &tc.l3_mode, OPT_WRAP, SETTING_ITEM(l3_mode_desc) } } },
{ "Line4x mode", OPT_AVCONFIG_SELECTION, { .sel = { &tc.l4_mode, OPT_WRAP, SETTING_ITEM(l4_mode_desc) } } },
{ "Line5x mode", OPT_AVCONFIG_SELECTION, { .sel = { &tc.l5_mode, OPT_WRAP, SETTING_ITEM(l3_mode_desc) } } },
{ "256x240 L3_Hmult", OPT_AVCONFIG_NUMVALUE, { .num = { &tc.l3m3_hmult, OPT_NOWRAP, 1, 5, value_disp } } },
{ LNG("TX mode","TXモード"), OPT_AVCONFIG_SELECTION, { .sel = { &tc.tx_mode, OPT_WRAP, SETTING_ITEM(tx_mode_desc) } } },
{ LNG("Initial input","ショキニュウリョク"), OPT_AVCONFIG_SELECTION, { .sel = { &tc.def_input, OPT_WRAP, SETTING_ITEM(avinput_str) } } },
}))
+11 -5
View File
@@ -163,7 +163,7 @@ void tvp_init()
tvp_sel_csc(&csc_coeffs[0]);
// Set default phase
tvp_set_hpll_phase(0x10);
tvp_set_hpll_phase(0x10, 1);
// Set min LPF
tvp_set_lpf(0);
@@ -298,11 +298,17 @@ void tvp_set_sync_lpf(alt_u8 val)
printf("Sync LPF value set to 0x%x\n", (3-val));
}
void tvp_set_hpll_phase(alt_u8 val)
alt_u8 tvp_set_hpll_phase(alt_u8 val, alt_u8 sample_mult)
{
alt_u8 sample_sel;
alt_u8 status = tvp_readreg(TVP_HPLLPHASE) & 0x07;
sample_sel = (val*sample_mult)/32;
val = val*sample_mult % 32;
tvp_writereg(TVP_HPLLPHASE, (val<<3)|status);
printf("Phase value set to 0x%x\n", val);
printf("Phase selection: %u/%u (FPGA), %u/32 (TVP)\n", sample_sel+1, sample_mult, val+1);
return sample_sel;
}
void tvp_set_sog_thold(alt_u8 val)
@@ -337,7 +343,7 @@ void tvp_set_alc(alt_u8 en_alc, video_type type, alt_u8 h_syncinlen)
}
}
void tvp_source_setup(alt_8 modeid, video_type type, alt_u32 vlines, alt_u8 hz, alt_u8 h_syncinlen, alt_u8 pre_coast, alt_u8 post_coast, alt_u8 vsync_thold)
void tvp_source_setup(alt_8 modeid, video_type type, alt_u32 vlines, alt_u8 hz, alt_u8 h_syncinlen, alt_u8 pre_coast, alt_u8 post_coast, alt_u8 vsync_thold, alt_u8 sample_mult)
{
// Clamp position and ALC
tvp_set_clamp_position(type, h_syncinlen);
@@ -367,7 +373,7 @@ void tvp_source_setup(alt_8 modeid, video_type type, alt_u32 vlines, alt_u8 hz,
tvp_set_hpllcoast(pre_coast, post_coast);
// Hsync output width
tvp_writereg(TVP_HSOUTWIDTH, video_modes[modeid].h_synclen);
tvp_writereg(TVP_HSOUTWIDTH, sample_mult*video_modes[modeid].h_synclen);
}
void tvp_source_sel(tvp_input_t input, video_format fmt)
+2 -2
View File
@@ -94,13 +94,13 @@ void tvp_set_lpf(alt_u8 val);
void tvp_set_sync_lpf(alt_u8 val);
void tvp_set_hpll_phase(alt_u8 val);
alt_u8 tvp_set_hpll_phase(alt_u8 val, alt_u8 sample_mult);
void tvp_set_sog_thold(alt_u8 val);
void tvp_set_alc(alt_u8 en_alc, video_type type, alt_u8 h_syncinlen);
void tvp_source_setup(alt_8 modeid, video_type type, alt_u32 vlines, alt_u8 hz, alt_u8 h_syncinlen, alt_u8 pre_coast, alt_u8 post_coast, alt_u8 vsync_thold);
void tvp_source_setup(alt_8 modeid, video_type type, alt_u32 vlines, alt_u8 hz, alt_u8 h_syncinlen, alt_u8 pre_coast, alt_u8 post_coast, alt_u8 vsync_thold, alt_u8 sample_mult);
void tvp_source_sel(tvp_input_t input, video_format fmt);
+104 -16
View File
@@ -20,43 +20,131 @@
#include <stdio.h>
#include <unistd.h>
#include "system.h"
#include "av_controller.h"
#include "video_modes.h"
#define LINECNT_MAX_TOLERANCE 30
extern avmode_t cm;
const mode_data_t video_modes_default[] = VIDEO_MODES_DEF;
mode_data_t video_modes[VIDEO_MODES_CNT];
/* TODO: rewrite, check hz etc. */
alt_8 get_mode_id(alt_u32 totlines, alt_u8 progressive, alt_u32 hz, video_type typemask, alt_u8 linemult_target, alt_u8 l3_mode, alt_u8 s480p_mode)
alt_8 get_mode_id(alt_u32 totlines, alt_u8 progressive, alt_u32 hz, video_type typemask)
{
alt_8 i;
alt_u8 num_modes = sizeof(video_modes)/sizeof(mode_data_t);
video_type mode_type;
mode_flags valid_lm[] = { MODE_PT, MODE_L2, (MODE_L3_GEN_16_9<<cm.cc.l3_mode), (MODE_L4_GEN_4_3<<cm.cc.l4_mode), (MODE_L5_GEN_16_9<<cm.cc.l5_mode) };
mode_flags target_lm;
alt_u8 pt_only = 0;
// one for each video_group
alt_u8* group_ptr[] = { &pt_only, &cm.cc.pm_240p, &cm.cc.pm_384p, &cm.cc.pm_480i, &cm.cc.pm_480p, &cm.cc.pm_480p };
// TODO: a better check
for (i=0; i<num_modes; i++) {
mode_type = video_modes[i].type;
// disable particular 480p mode based on input and user preference
if (video_modes[i].flags & MODE_DTV480P) {
if (s480p_mode == 0) // auto
// disable particular mode based on input and user preference
if (video_modes[i].group == GROUP_DTV480P) {
if (cm.cc.s480p_mode == 0) // auto
mode_type &= ~VIDEO_PC;
else if (s480p_mode == 2) // VGA 640x480
mode_type = 0;
} else if (video_modes[i].flags & MODE_VGA480P) {
if (s480p_mode == 0) // auto
else if (cm.cc.s480p_mode == 2) // VGA 640x480
continue;
} else if (video_modes[i].group == GROUP_VGA480P) {
if (cm.cc.s480p_mode == 0) // auto
mode_type &= ~VIDEO_EDTV;
else if (s480p_mode == 1) // DTV 480P
mode_type = 0;
else if (cm.cc.s480p_mode == 1) // DTV 480P
continue;
} else if (video_modes[i].group > GROUP_VGA480P) {
printf("WARNING: Corrupted mode (id %d)\n", i);
continue;
}
if ((typemask & mode_type) && (progressive == !(video_modes[i].flags & MODE_INTERLACED)) && (totlines <= (video_modes[i].v_total+LINECNT_MAX_TOLERANCE))) {
if (linemult_target && (video_modes[i].flags & MODE_L3ENABLE_MASK) && ((video_modes[i].flags & MODE_L3ENABLE_MASK) == (1<<l3_mode))) {
return i;
} else if (!(video_modes[i].flags & MODE_L3ENABLE_MASK)) {
return i;
target_lm = valid_lm[*group_ptr[video_modes[i].group]];
if ((typemask & mode_type) && (target_lm & video_modes[i].flags) && (progressive == !(video_modes[i].flags & MODE_INTERLACED)) && (totlines <= (video_modes[i].v_total+LINECNT_MAX_TOLERANCE))) {
// defaults
cm.hdmitx_pixelrep = HDMITX_PIXELREP_DISABLE;
cm.hdmitx_pixr_ifr = HDMITX_PIXELREP_2X;
cm.sample_mult = 1;
cm.target_lm = target_lm;
switch (target_lm) {
case MODE_PT:
cm.fpga_vmultmode = FPGA_V_MULTMODE_1X;
cm.fpga_hmultmode = FPGA_H_MULTMODE_FULLWIDTH;
cm.hdmitx_pixelrep = ((video_modes[i].group == GROUP_240P) || (video_modes[i].group == GROUP_480I)) ? HDMITX_PIXELREP_2X : HDMITX_PIXELREP_DISABLE;
cm.hdmitx_pixr_ifr = cm.hdmitx_pixelrep;
break;
case MODE_L2:
cm.fpga_vmultmode = FPGA_V_MULTMODE_2X;
cm.fpga_hmultmode = FPGA_H_MULTMODE_FULLWIDTH;
cm.hdmitx_pixelrep = ((video_modes[i].group == GROUP_DTV480P) || (video_modes[i].group == GROUP_VGA480P)) ? HDMITX_PIXELREP_2X : HDMITX_PIXELREP_DISABLE;
break;
case MODE_L3_GEN_16_9:
cm.fpga_vmultmode = FPGA_V_MULTMODE_3X;
cm.fpga_hmultmode = FPGA_H_MULTMODE_FULLWIDTH;
break;
case MODE_L3_GEN_4_3:
cm.fpga_vmultmode = FPGA_V_MULTMODE_3X;
cm.fpga_hmultmode = FPGA_H_MULTMODE_ASPECTFIX;
break;
case MODE_L3_320_COL:
cm.fpga_vmultmode = FPGA_V_MULTMODE_3X;
cm.fpga_hmultmode = FPGA_H_MULTMODE_OPTIMIZED;
cm.sample_mult = 4;
break;
case MODE_L3_256_COL:
cm.fpga_vmultmode = FPGA_V_MULTMODE_3X;
cm.fpga_hmultmode = FPGA_H_MULTMODE_OPTIMIZED;
cm.sample_mult = 5;
break;
case MODE_L4_GEN_4_3:
cm.fpga_vmultmode = FPGA_V_MULTMODE_4X;
cm.fpga_hmultmode = FPGA_H_MULTMODE_FULLWIDTH;
break;
case MODE_L4_320_COL:
cm.fpga_vmultmode = FPGA_V_MULTMODE_4X;
cm.fpga_hmultmode = FPGA_H_MULTMODE_OPTIMIZED;
cm.sample_mult = 4;
break;
case MODE_L4_256_COL:
cm.fpga_vmultmode = FPGA_V_MULTMODE_4X;
cm.fpga_hmultmode = FPGA_H_MULTMODE_OPTIMIZED;
cm.sample_mult = 5;
break;
case MODE_L5_GEN_16_9:
cm.fpga_vmultmode = FPGA_V_MULTMODE_5X;
cm.fpga_hmultmode = FPGA_H_MULTMODE_FULLWIDTH;
cm.hdmitx_pixelrep = HDMITX_PIXELREP_2X;
break;
case MODE_L5_GEN_4_3:
cm.fpga_vmultmode = FPGA_V_MULTMODE_5X;
cm.fpga_hmultmode = FPGA_H_MULTMODE_ASPECTFIX;
cm.hdmitx_pixelrep = HDMITX_PIXELREP_2X;
break;
case MODE_L5_320_COL:
cm.fpga_vmultmode = FPGA_V_MULTMODE_5X;
cm.fpga_hmultmode = FPGA_H_MULTMODE_OPTIMIZED;
cm.hdmitx_pixelrep = HDMITX_PIXELREP_2X;
cm.sample_mult = 3;
break;
case MODE_L5_256_COL:
cm.fpga_vmultmode = FPGA_V_MULTMODE_5X;
cm.fpga_hmultmode = FPGA_H_MULTMODE_OPTIMIZED;
cm.hdmitx_pixelrep = HDMITX_PIXELREP_2X;
cm.sample_mult = 3;
break;
default:
printf("WARNING: invalid target_lm\n");
continue;
break;
}
return i;
}
}
+58 -43
View File
@@ -44,25 +44,39 @@ typedef enum {
} video_format;
typedef enum {
VIDEO_LDTV = (1<<0),
VIDEO_SDTV = (1<<1),
VIDEO_EDTV = (1<<2),
VIDEO_HDTV = (1<<3),
VIDEO_PC = (1<<4)
VIDEO_LDTV = (1<<0),
VIDEO_SDTV = (1<<1),
VIDEO_EDTV = (1<<2),
VIDEO_HDTV = (1<<3),
VIDEO_PC = (1<<4),
} video_type;
#define MODE_L3ENABLE_MASK 0xf
typedef enum {
GROUP_NONE = 0,
GROUP_240P = 1,
GROUP_384P = 2,
GROUP_480I = 3,
GROUP_DTV480P = 4,
GROUP_VGA480P = 5,
} video_group;
typedef enum {
MODE_L3_MODE0 = (1<<0),
MODE_L3_MODE1 = (1<<1),
MODE_L3_MODE2 = (1<<2),
MODE_L3_MODE3 = (1<<3),
MODE_L2ENABLE = (1<<4),
MODE_INTERLACED = (1<<5),
MODE_PLLDIVBY2 = (1<<6),
MODE_DTV480P = (1<<7),
MODE_VGA480P = (1<<8)
MODE_INTERLACED = (1<<0),
MODE_PLLDIVBY2 = (1<<1),
//at least one of the flags below must be set for each mode
MODE_PT = (1<<2),
MODE_L2 = (1<<3),
MODE_L3_GEN_16_9 = (1<<4),
MODE_L3_GEN_4_3 = (1<<5),
MODE_L3_320_COL = (1<<6),
MODE_L3_256_COL = (1<<7),
MODE_L4_GEN_4_3 = (1<<8),
MODE_L4_320_COL = (1<<9),
MODE_L4_256_COL = (1<<10),
MODE_L5_GEN_16_9 = (1<<11),
MODE_L5_GEN_4_3 = (1<<12),
MODE_L5_320_COL = (1<<13),
MODE_L5_256_COL = (1<<14),
} mode_flags;
typedef struct {
@@ -77,42 +91,43 @@ typedef struct {
alt_u8 h_synclen;
alt_u8 v_synclen;
video_type type;
video_group group;
mode_flags flags;
} mode_data_t;
#define VIDEO_MODES_DEF { \
{ "240p_L3M0", 1280, 240, 6000, 1560, 262, 170, 16, 72, 3, (VIDEO_SDTV|VIDEO_PC), (MODE_L3_MODE0|MODE_PLLDIVBY2) }, \
{ "240p_L3M1", 960, 240, 6000, 1170, 262, 128, 16, 54, 3, (VIDEO_SDTV|VIDEO_PC), (MODE_L3_MODE1|MODE_PLLDIVBY2) }, \
/*{ "240p_L3M2", 384, 240, 6000, 512, 262, 66, 16, 31, 3, (VIDEO_LDTV|VIDEO_PC), (MODE_L3_MODE2|MODE_PLLDIVBY2) }, //CPS2*/ \
{ "240p_L3M2", 320, 240, 6000, 426, 262, 49, 16, 31, 3, (VIDEO_LDTV|VIDEO_PC), (MODE_L3_MODE2|MODE_PLLDIVBY2) }, \
{ "240p_L3M3", 256, 240, 6000, 341, 262, 39, 16, 25, 3, (VIDEO_LDTV|VIDEO_PC), (MODE_L3_MODE3|MODE_PLLDIVBY2) }, \
{ "240p", 720, 240, 6000, 858, 262, 65, 16, 60, 3, (VIDEO_SDTV|VIDEO_PC), (MODE_L2ENABLE|MODE_PLLDIVBY2) }, \
{ "288p_L3M0", 1280, 288, 5000, 1560, 312, 170, 16, 72, 3, (VIDEO_SDTV|VIDEO_PC), (MODE_L3_MODE0|MODE_PLLDIVBY2) }, \
{ "288p_L3M1", 960, 288, 5000, 1170, 312, 128, 16, 54, 3, (VIDEO_SDTV|VIDEO_PC), (MODE_L3_MODE1|MODE_PLLDIVBY2) }, \
{ "288p_L3M2", 320, 240, 5000, 426, 312, 49, 41, 31, 3, (VIDEO_LDTV|VIDEO_PC), (MODE_L3_MODE2|MODE_PLLDIVBY2) }, \
{ "288p_L3M3", 256, 240, 5000, 341, 312, 39, 41, 25, 3, (VIDEO_LDTV|VIDEO_PC), (MODE_L3_MODE3|MODE_PLLDIVBY2) }, \
{ "288p", 720, 288, 5000, 864, 312, 65, 16, 60, 3, (VIDEO_SDTV|VIDEO_PC), (MODE_L2ENABLE|MODE_PLLDIVBY2) }, \
{ "384p", 496, 384, 5766, 640, 423, 50, 29, 62, 3, VIDEO_EDTV, (MODE_L2ENABLE|MODE_PLLDIVBY2) }, /* Sega Model 2 */ \
{ "640x384", 640, 384, 5500, 800, 492, 48, 63, 96, 2, VIDEO_PC, (MODE_L2ENABLE) }, /* X68k @ 24kHz */ \
{ "480i", 720, 240, 5994, 858, 525, 65, 16, 60, 3, (VIDEO_SDTV|VIDEO_PC), (MODE_L2ENABLE|MODE_PLLDIVBY2|MODE_INTERLACED) }, \
{ "480p", 720, 480, 5994, 858, 525, 60, 30, 62, 6, (VIDEO_EDTV|VIDEO_PC), (MODE_DTV480P) }, \
{ "640x480", 640, 480, 6000, 800, 525, 48, 33, 96, 2, (VIDEO_PC|VIDEO_EDTV), (MODE_VGA480P) }, \
{ "640x512", 640, 512, 6000, 800, 568, 48, 28, 96, 2, VIDEO_PC, 0 }, /* X68k @ 31kHz */ \
{ "576i", 720, 288, 5000, 864, 625, 65, 16, 60, 3, (VIDEO_SDTV|VIDEO_PC), (MODE_L2ENABLE|MODE_PLLDIVBY2|MODE_INTERLACED) }, \
{ "576p", 720, 576, 5000, 864, 625, 65, 32, 60, 6, VIDEO_EDTV, 0 }, \
{ "800x600", 800, 600, 6000, 1056, 628, 88, 23, 128, 4, VIDEO_PC, 0 }, \
{ "720p", 1280, 720, 5994, 1650, 750, 255, 20, 40, 5, VIDEO_HDTV, 0 }, \
{ "1280x720", 1280, 720, 6000, 1650, 750, 220, 20, 40, 5, VIDEO_PC, 0 }, \
{ "1024x768", 1024, 768, 6000, 1344, 806, 160, 29, 136, 6, VIDEO_PC, 0 }, \
{ "1280x1024", 1280, 1024, 6000, 1688, 1066, 248, 38, 112, 3, VIDEO_PC, 0 }, \
{ "1080i", 1920, 1080, 5994, 2200, 1125, 148, 16, 44, 5, VIDEO_HDTV, (MODE_INTERLACED) }, /* Too high freq for L2 PLL */ \
{ "1080p", 1920, 1080, 5994, 2200, 1125, 188, 36, 44, 5, VIDEO_HDTV, 0 }, \
{ "1920x1080", 1920, 1080, 6000, 2200, 1125, 148, 36, 44, 5, VIDEO_PC, 0 }, \
{ "1280x240", 1280, 240, 6000, 1560, 262, 170, 16, 72, 3, (VIDEO_SDTV | VIDEO_PC), GROUP_240P, (MODE_L3_GEN_16_9 | MODE_L4_GEN_4_3 | MODE_PLLDIVBY2) }, \
{ "960x240", 960, 240, 6000, 1170, 262, 128, 16, 54, 3, (VIDEO_SDTV | VIDEO_PC), GROUP_240P, (MODE_L3_GEN_4_3 | MODE_PLLDIVBY2) }, \
/*{ "240p_L3M2", 384, 240, 6000, 512, 262, 66, 16, 31, 3, (VIDEO_LDTV|VIDEO_PC), (MODE_L3_MODE2|MODE_PLLDIVBY2) }, //CPS2*/ \
{ "320x240", 320, 240, 6000, 4*426, 262, 49, 16, 31, 3, (VIDEO_SDTV | VIDEO_PC), GROUP_240P, (MODE_L3_320_COL | MODE_L4_320_COL) }, \
{ "256x240", 256, 240, 6000, 5*341, 262, 39, 16, 25, 3, (VIDEO_SDTV | VIDEO_PC), GROUP_240P, (MODE_L3_256_COL | MODE_L4_256_COL) }, \
{ "240p", 720, 240, 6000, 858, 262, 65, 16, 60, 3, (VIDEO_SDTV | VIDEO_PC), GROUP_240P, (MODE_PT | MODE_L2 | MODE_L5_GEN_4_3 | MODE_PLLDIVBY2) }, \
{ "1280x288", 1280, 288, 5000, 1560, 312, 170, 16, 72, 3, (VIDEO_SDTV | VIDEO_PC), GROUP_240P, (MODE_L3_GEN_16_9 | MODE_L4_GEN_4_3 | MODE_PLLDIVBY2) }, \
{ "960x288", 960, 288, 5000, 1170, 312, 128, 16, 54, 3, (VIDEO_SDTV | VIDEO_PC), GROUP_240P, (MODE_L3_GEN_4_3 | MODE_PLLDIVBY2) }, \
{ "320x240LB", 320, 240, 5000, 4*426, 312, 49, 41, 31, 3, (VIDEO_SDTV | VIDEO_PC), GROUP_240P, (MODE_L3_320_COL | MODE_L4_320_COL) }, \
{ "256x240LB", 256, 240, 5000, 5*341, 312, 39, 41, 25, 3, (VIDEO_SDTV | VIDEO_PC), GROUP_240P, (MODE_L3_256_COL | MODE_L4_256_COL) }, \
{ "288p", 720, 288, 5000, 864, 312, 65, 16, 60, 3, (VIDEO_SDTV | VIDEO_PC), GROUP_240P, (MODE_PT | MODE_L2 | MODE_L5_GEN_4_3 | MODE_PLLDIVBY2) }, \
{ "384p", 496, 384, 5766, 640, 423, 50, 29, 62, 3, (VIDEO_EDTV), GROUP_384P, (MODE_PT | MODE_L2 | MODE_PLLDIVBY2) }, /* Sega Model 2 */ \
{ "640x384", 640, 384, 5500, 800, 492, 48, 63, 96, 2, VIDEO_PC, GROUP_384P, (MODE_PT | MODE_L2) }, /* X68k @ 24kHz */ \
{ "480i", 720, 240, 5994, 858, 525, 65, 16, 60, 3, (VIDEO_SDTV | VIDEO_PC), GROUP_480I, (MODE_PT | MODE_L2 | MODE_PLLDIVBY2 | MODE_INTERLACED) }, \
{ "480p", 720, 480, 5994, 858, 525, 60, 30, 62, 6, (VIDEO_EDTV | VIDEO_PC), GROUP_DTV480P, (MODE_PT | MODE_L2) }, \
{ "640x480", 640, 480, 6000, 800, 525, 48, 33, 96, 2, (VIDEO_PC | VIDEO_EDTV), GROUP_VGA480P, (MODE_PT | MODE_L2) }, \
{ "640x512", 640, 512, 6000, 800, 568, 48, 28, 96, 2, VIDEO_PC, GROUP_NONE, MODE_PT }, /* X68k @ 31kHz */ \
{ "576i", 720, 288, 5000, 864, 625, 65, 16, 60, 3, (VIDEO_SDTV | VIDEO_PC), GROUP_480I, (MODE_PT | MODE_L2 | MODE_PLLDIVBY2 | MODE_INTERLACED) }, \
{ "576p", 720, 576, 5000, 864, 625, 65, 32, 60, 6, VIDEO_EDTV, GROUP_DTV480P, (MODE_PT | MODE_L2) }, \
{ "800x600", 800, 600, 6000, 1056, 628, 88, 23, 128, 4, VIDEO_PC, GROUP_NONE, MODE_PT }, \
{ "720p", 1280, 720, 5994, 1650, 750, 255, 20, 40, 5, VIDEO_HDTV, GROUP_NONE, MODE_PT }, \
{ "1280x720", 1280, 720, 6000, 1650, 750, 220, 20, 40, 5, VIDEO_PC, GROUP_NONE, MODE_PT }, \
{ "1024x768", 1024, 768, 6000, 1344, 806, 160, 29, 136, 6, VIDEO_PC, GROUP_NONE, MODE_PT }, \
{ "1280x1024", 1280, 1024, 6000, 1688, 1066, 248, 38, 112, 3, VIDEO_PC, GROUP_NONE, MODE_PT }, \
{ "1080i", 1920, 1080, 5994, 2200, 1125, 148, 16, 44, 5, VIDEO_HDTV, GROUP_NONE, (MODE_PT | MODE_INTERLACED) }, /* Too high freq for L2 PLL */ \
{ "1080p", 1920, 1080, 5994, 2200, 1125, 188, 36, 44, 5, VIDEO_HDTV, GROUP_NONE, MODE_PT }, \
{ "1920x1080", 1920, 1080, 6000, 2200, 1125, 148, 36, 44, 5, VIDEO_PC, GROUP_NONE, MODE_PT }, \
}
#define VIDEO_MODES_SIZE (sizeof((mode_data_t[])VIDEO_MODES_DEF))
#define VIDEO_MODES_CNT (sizeof((mode_data_t[])VIDEO_MODES_DEF)/sizeof(mode_data_t))
alt_8 get_mode_id(alt_u32 totlines, alt_u8 progressive, alt_u32 hz, video_type typemask, alt_u8 linemult_target, alt_u8 l3_mode, alt_u8 s480p_mode);
alt_8 get_mode_id(alt_u32 totlines, alt_u8 progressive, alt_u32 hz, video_type typemask);
#endif /* VIDEO_MODES_H_ */