kopia lustrzana https://github.com/hoglet67/RGBtoHDMI
Pi Firmware: Added pllh control (623-627 lines)
Change-Id: If1efa170a547aa2afbc5a2e108331b2f479f4092soft_delitch
rodzic
fad4c55e76
commit
ee07893a3d
25
src/osd.c
25
src/osd.c
|
@ -84,6 +84,15 @@ static const char *machine_names[] = {
|
|||
"Elk"
|
||||
};
|
||||
|
||||
static const char *pllh_names[] = {
|
||||
"Original",
|
||||
"623",
|
||||
"624",
|
||||
"625",
|
||||
"626",
|
||||
"627",
|
||||
};
|
||||
|
||||
// =============================================================
|
||||
// Feature definitions for OSD
|
||||
// =============================================================
|
||||
|
@ -95,6 +104,7 @@ enum {
|
|||
F_MUX,
|
||||
F_ELK,
|
||||
F_VSYNC,
|
||||
F_PLLH,
|
||||
F_DEBUG
|
||||
};
|
||||
|
||||
|
@ -105,6 +115,7 @@ static param_t features[] = {
|
|||
{ "Input Mux", 0, 1 },
|
||||
{ "Elk", 0, 1 },
|
||||
{ "Vsync", 0, 1 },
|
||||
{ "PLLH", 0, 5 },
|
||||
{ "Debug", 0, 1 },
|
||||
{ NULL, 0, 0 },
|
||||
};
|
||||
|
@ -234,7 +245,7 @@ static int get_feature(int num) {
|
|||
return info;
|
||||
case F_PALETTE:
|
||||
return palette;
|
||||
case F_SCANLINES:
|
||||
case F_SCANLINES:
|
||||
return scanlines;
|
||||
case F_MUX:
|
||||
return mux;
|
||||
|
@ -242,6 +253,8 @@ static int get_feature(int num) {
|
|||
return get_elk();
|
||||
case F_VSYNC:
|
||||
return get_vsync();
|
||||
case F_PLLH:
|
||||
return get_pllh();
|
||||
case F_DEBUG:
|
||||
return debug;
|
||||
}
|
||||
|
@ -271,6 +284,9 @@ static void set_feature(int num, int value) {
|
|||
case F_VSYNC:
|
||||
set_vsync(value);
|
||||
break;
|
||||
case F_PLLH:
|
||||
set_pllh(value);
|
||||
break;
|
||||
case F_DEBUG:
|
||||
debug = value;
|
||||
update_palette();
|
||||
|
@ -286,6 +302,7 @@ static void show_feature(int num) {
|
|||
const char *valstr =
|
||||
(num == F_INFO) ? info_names[value] :
|
||||
(num == F_PALETTE) ? palette_names[value] :
|
||||
(num == F_PLLH) ? pllh_names[value] :
|
||||
value ? "On" : "Off";
|
||||
// Clear lines 2 onwards
|
||||
memset(buffer + 2 * LINELEN, 0, (NLINES - 2) * LINELEN);
|
||||
|
@ -535,6 +552,12 @@ void osd_init() {
|
|||
set_feature(F_ELK, val);
|
||||
log_info("config.txt: elk = %d", val);
|
||||
}
|
||||
prop = get_cmdline_prop("pllh");
|
||||
if (prop) {
|
||||
int val = atoi(prop);
|
||||
set_feature(F_PLLH, val);
|
||||
log_info("config.txt: pllh = %d", val);
|
||||
}
|
||||
prop = get_cmdline_prop("vsync");
|
||||
if (prop) {
|
||||
int val = atoi(prop);
|
||||
|
|
|
@ -26,5 +26,7 @@ void set_elk(int on);
|
|||
int get_elk();
|
||||
void set_vsync(int on);
|
||||
int get_vsync();
|
||||
void set_pllh(int mode);
|
||||
int get_pllh();
|
||||
|
||||
#endif
|
||||
|
|
|
@ -51,6 +51,8 @@ static int height = 0;
|
|||
static uint32_t cpld_version_id;
|
||||
static volatile int delay;
|
||||
static int vsync;
|
||||
static int pllh;
|
||||
static double pllh_clock = 0;
|
||||
static int elk;
|
||||
static int mode7;
|
||||
static int clear;
|
||||
|
@ -328,57 +330,14 @@ static int calibrate_clock() {
|
|||
gpioreg[PLLH_STS]);
|
||||
|
||||
// Dump the original PLLH frequency
|
||||
double f1 = 19.2 * ((double)(gpioreg[PLLH_CTRL] & 0x3ff) + ((double)gpioreg[PLLH_FRAC]) / ((double)(1 << 20)));
|
||||
log_info("Original PLLH: %lf MHz", f1);
|
||||
pllh_clock = 19.2 * ((double)(gpioreg[PLLH_CTRL] & 0x3ff) + ((double)gpioreg[PLLH_FRAC]) / ((double)(1 << 20)));
|
||||
|
||||
// Correct for the Beeb's clock
|
||||
double f2 = f1 / error;
|
||||
|
||||
// Correct for non-interlaced mode
|
||||
if (!(frame_time & INTERLACED_FLAG)) {
|
||||
f2 *= 626.0 / 624.0;
|
||||
}
|
||||
|
||||
// Dump the target PLL frequency
|
||||
log_info(" Target PLLH: %lf MHz", f2);
|
||||
|
||||
// Calculate the new fraction
|
||||
double div = gpioreg[PLLH_CTRL] & 0x3ff;
|
||||
int fract = (int) ((double)(1<<20) * (f2 / 19.2 - div));
|
||||
if (fract < 0) {
|
||||
log_warn("PLLH fraction < 0");
|
||||
fract = 0;
|
||||
}
|
||||
if (fract > (1<<20) - 1) {
|
||||
log_warn("PLLH fraction > 1");
|
||||
fract = (1<<20) - 1;
|
||||
}
|
||||
|
||||
// Update the PLL
|
||||
int old_fract = gpioreg[PLLH_FRAC];
|
||||
gpioreg[PLLH_FRAC] = 0x5A000000 | fract;
|
||||
int new_fract = gpioreg[PLLH_FRAC];
|
||||
|
||||
log_info("Old fract = %d (when read back)", old_fract);
|
||||
log_info("New fract = %d", fract);
|
||||
log_info("New fract = %d (when read back)", new_fract);
|
||||
|
||||
log_info("PLLH: PDIV=%d NDIV=%d FRAC=%d AUX=%d RCAL=%d PIX=%d STS=%d",
|
||||
(gpioreg[PLLH_CTRL] >> 12) & 0x7,
|
||||
gpioreg[PLLH_CTRL] & 0x3ff,
|
||||
gpioreg[PLLH_FRAC],
|
||||
gpioreg[PLLH_AUX],
|
||||
gpioreg[PLLH_RCAL],
|
||||
gpioreg[PLLH_PIX],
|
||||
gpioreg[PLLH_STS]);
|
||||
|
||||
// Dump the the actual PLL frequency
|
||||
double f3 = 19.2 * ((double)(gpioreg[PLLH_CTRL] & 0x3ff) + ((double)gpioreg[PLLH_FRAC]) / ((double)(1 << 20)));
|
||||
log_info(" Actual PLLH: %lf MHz", f3);
|
||||
log_info("Original PLLH: %lf MHz", pllh_clock);
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
|
||||
static void init_hardware() {
|
||||
int i;
|
||||
for (i = 0; i < 12; i++) {
|
||||
|
@ -768,6 +727,63 @@ int get_vsync() {
|
|||
return vsync;
|
||||
}
|
||||
|
||||
int get_pllh() {
|
||||
return pllh;
|
||||
}
|
||||
|
||||
void set_pllh(int mode) {
|
||||
|
||||
pllh = mode;
|
||||
|
||||
double error = 1.0 + (clock_error_ppm / 1e6);
|
||||
|
||||
double f2 = pllh_clock;
|
||||
|
||||
if (mode > 0) {
|
||||
// Correct for clock error
|
||||
f2 /= error;
|
||||
// Correct for specified number of lines (mode 1..5)
|
||||
f2 *= 625.0 / (622.0 + mode);
|
||||
}
|
||||
|
||||
// Dump the target PLL frequency
|
||||
log_info(" Target PLLH: %lf MHz", f2);
|
||||
|
||||
// Calculate the new fraction
|
||||
double div = gpioreg[PLLH_CTRL] & 0x3ff;
|
||||
int fract = (int) ((double)(1<<20) * (f2 / 19.2 - div));
|
||||
if (fract < 0) {
|
||||
log_warn("PLLH fraction < 0");
|
||||
fract = 0;
|
||||
}
|
||||
if (fract > (1<<20) - 1) {
|
||||
log_warn("PLLH fraction > 1");
|
||||
fract = (1<<20) - 1;
|
||||
}
|
||||
|
||||
// Update the PLL
|
||||
int old_fract = gpioreg[PLLH_FRAC];
|
||||
gpioreg[PLLH_FRAC] = 0x5A000000 | fract;
|
||||
int new_fract = gpioreg[PLLH_FRAC];
|
||||
|
||||
log_info("Old fract = %d (when read back)", old_fract);
|
||||
log_info("New fract = %d", fract);
|
||||
log_info("New fract = %d (when read back)", new_fract);
|
||||
|
||||
log_info("PLLH: PDIV=%d NDIV=%d FRAC=%d AUX=%d RCAL=%d PIX=%d STS=%d",
|
||||
(gpioreg[PLLH_CTRL] >> 12) & 0x7,
|
||||
gpioreg[PLLH_CTRL] & 0x3ff,
|
||||
gpioreg[PLLH_FRAC],
|
||||
gpioreg[PLLH_AUX],
|
||||
gpioreg[PLLH_RCAL],
|
||||
gpioreg[PLLH_PIX],
|
||||
gpioreg[PLLH_STS]);
|
||||
|
||||
// Dump the the actual PLL frequency
|
||||
double f3 = 19.2 * ((double)(gpioreg[PLLH_CTRL] & 0x3ff) + ((double)gpioreg[PLLH_FRAC]) / ((double)(1 << 20)));
|
||||
log_info(" Actual PLLH: %lf MHz", f3);
|
||||
}
|
||||
|
||||
void action_scanlines(int on) {
|
||||
if (on) {
|
||||
scanlines = BIT_SCANLINES;
|
||||
|
|
|
@ -58,10 +58,18 @@
|
|||
# - 0 is vsync off
|
||||
# - 1 is vsync on
|
||||
#
|
||||
# pllh: controls the HDMI clock correction mode
|
||||
# - 0 is no correction
|
||||
# - 1 is correct for 623 lines
|
||||
# - 2 is correct for 623 lines
|
||||
# - 3 is correct for 625 lines
|
||||
# - 4 is correct for 626 lines
|
||||
# - 5 is correct for 627 lines
|
||||
#
|
||||
# debug: enables debug mode
|
||||
# - 0 is debug off
|
||||
# - 1 is debug on
|
||||
#
|
||||
# Important: All the properties must be on a single line, and no blank lines!
|
||||
#
|
||||
sampling06=3 sampling7=0,2,2,2,2,2,2,0 info=1 palette=0 scanlines=0 mux=0 elk=0 vsync=0 debug=0
|
||||
sampling06=3 sampling7=0,2,2,2,2,2,2,0 info=1 palette=0 scanlines=0 mux=0 elk=0 vsync=0 pllh=0 debug=0
|
||||
|
|
Ładowanie…
Reference in New Issue