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"
|
"Elk"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const char *pllh_names[] = {
|
||||||
|
"Original",
|
||||||
|
"623",
|
||||||
|
"624",
|
||||||
|
"625",
|
||||||
|
"626",
|
||||||
|
"627",
|
||||||
|
};
|
||||||
|
|
||||||
// =============================================================
|
// =============================================================
|
||||||
// Feature definitions for OSD
|
// Feature definitions for OSD
|
||||||
// =============================================================
|
// =============================================================
|
||||||
|
@ -95,6 +104,7 @@ enum {
|
||||||
F_MUX,
|
F_MUX,
|
||||||
F_ELK,
|
F_ELK,
|
||||||
F_VSYNC,
|
F_VSYNC,
|
||||||
|
F_PLLH,
|
||||||
F_DEBUG
|
F_DEBUG
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -105,6 +115,7 @@ static param_t features[] = {
|
||||||
{ "Input Mux", 0, 1 },
|
{ "Input Mux", 0, 1 },
|
||||||
{ "Elk", 0, 1 },
|
{ "Elk", 0, 1 },
|
||||||
{ "Vsync", 0, 1 },
|
{ "Vsync", 0, 1 },
|
||||||
|
{ "PLLH", 0, 5 },
|
||||||
{ "Debug", 0, 1 },
|
{ "Debug", 0, 1 },
|
||||||
{ NULL, 0, 0 },
|
{ NULL, 0, 0 },
|
||||||
};
|
};
|
||||||
|
@ -234,7 +245,7 @@ static int get_feature(int num) {
|
||||||
return info;
|
return info;
|
||||||
case F_PALETTE:
|
case F_PALETTE:
|
||||||
return palette;
|
return palette;
|
||||||
case F_SCANLINES:
|
case F_SCANLINES:
|
||||||
return scanlines;
|
return scanlines;
|
||||||
case F_MUX:
|
case F_MUX:
|
||||||
return mux;
|
return mux;
|
||||||
|
@ -242,6 +253,8 @@ static int get_feature(int num) {
|
||||||
return get_elk();
|
return get_elk();
|
||||||
case F_VSYNC:
|
case F_VSYNC:
|
||||||
return get_vsync();
|
return get_vsync();
|
||||||
|
case F_PLLH:
|
||||||
|
return get_pllh();
|
||||||
case F_DEBUG:
|
case F_DEBUG:
|
||||||
return debug;
|
return debug;
|
||||||
}
|
}
|
||||||
|
@ -271,6 +284,9 @@ static void set_feature(int num, int value) {
|
||||||
case F_VSYNC:
|
case F_VSYNC:
|
||||||
set_vsync(value);
|
set_vsync(value);
|
||||||
break;
|
break;
|
||||||
|
case F_PLLH:
|
||||||
|
set_pllh(value);
|
||||||
|
break;
|
||||||
case F_DEBUG:
|
case F_DEBUG:
|
||||||
debug = value;
|
debug = value;
|
||||||
update_palette();
|
update_palette();
|
||||||
|
@ -286,6 +302,7 @@ static void show_feature(int num) {
|
||||||
const char *valstr =
|
const char *valstr =
|
||||||
(num == F_INFO) ? info_names[value] :
|
(num == F_INFO) ? info_names[value] :
|
||||||
(num == F_PALETTE) ? palette_names[value] :
|
(num == F_PALETTE) ? palette_names[value] :
|
||||||
|
(num == F_PLLH) ? pllh_names[value] :
|
||||||
value ? "On" : "Off";
|
value ? "On" : "Off";
|
||||||
// Clear lines 2 onwards
|
// Clear lines 2 onwards
|
||||||
memset(buffer + 2 * LINELEN, 0, (NLINES - 2) * LINELEN);
|
memset(buffer + 2 * LINELEN, 0, (NLINES - 2) * LINELEN);
|
||||||
|
@ -535,6 +552,12 @@ void osd_init() {
|
||||||
set_feature(F_ELK, val);
|
set_feature(F_ELK, val);
|
||||||
log_info("config.txt: elk = %d", 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");
|
prop = get_cmdline_prop("vsync");
|
||||||
if (prop) {
|
if (prop) {
|
||||||
int val = atoi(prop);
|
int val = atoi(prop);
|
||||||
|
|
|
@ -26,5 +26,7 @@ void set_elk(int on);
|
||||||
int get_elk();
|
int get_elk();
|
||||||
void set_vsync(int on);
|
void set_vsync(int on);
|
||||||
int get_vsync();
|
int get_vsync();
|
||||||
|
void set_pllh(int mode);
|
||||||
|
int get_pllh();
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -51,6 +51,8 @@ static int height = 0;
|
||||||
static uint32_t cpld_version_id;
|
static uint32_t cpld_version_id;
|
||||||
static volatile int delay;
|
static volatile int delay;
|
||||||
static int vsync;
|
static int vsync;
|
||||||
|
static int pllh;
|
||||||
|
static double pllh_clock = 0;
|
||||||
static int elk;
|
static int elk;
|
||||||
static int mode7;
|
static int mode7;
|
||||||
static int clear;
|
static int clear;
|
||||||
|
@ -328,57 +330,14 @@ static int calibrate_clock() {
|
||||||
gpioreg[PLLH_STS]);
|
gpioreg[PLLH_STS]);
|
||||||
|
|
||||||
// Dump the original PLLH frequency
|
// Dump the original PLLH frequency
|
||||||
double f1 = 19.2 * ((double)(gpioreg[PLLH_CTRL] & 0x3ff) + ((double)gpioreg[PLLH_FRAC]) / ((double)(1 << 20)));
|
pllh_clock = 19.2 * ((double)(gpioreg[PLLH_CTRL] & 0x3ff) + ((double)gpioreg[PLLH_FRAC]) / ((double)(1 << 20)));
|
||||||
log_info("Original PLLH: %lf MHz", f1);
|
|
||||||
|
|
||||||
// Correct for the Beeb's clock
|
log_info("Original PLLH: %lf MHz", pllh_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);
|
|
||||||
|
|
||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void init_hardware() {
|
static void init_hardware() {
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < 12; i++) {
|
for (i = 0; i < 12; i++) {
|
||||||
|
@ -768,6 +727,63 @@ int get_vsync() {
|
||||||
return 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) {
|
void action_scanlines(int on) {
|
||||||
if (on) {
|
if (on) {
|
||||||
scanlines = BIT_SCANLINES;
|
scanlines = BIT_SCANLINES;
|
||||||
|
|
|
@ -58,10 +58,18 @@
|
||||||
# - 0 is vsync off
|
# - 0 is vsync off
|
||||||
# - 1 is vsync on
|
# - 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
|
# debug: enables debug mode
|
||||||
# - 0 is debug off
|
# - 0 is debug off
|
||||||
# - 1 is debug on
|
# - 1 is debug on
|
||||||
#
|
#
|
||||||
# Important: All the properties must be on a single line, and no blank lines!
|
# 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