summaryrefslogtreecommitdiffstats
path: root/board/gdsys/common/osd.c
diff options
context:
space:
mode:
Diffstat (limited to 'board/gdsys/common/osd.c')
-rw-r--r--board/gdsys/common/osd.c194
1 files changed, 130 insertions, 64 deletions
diff --git a/board/gdsys/common/osd.c b/board/gdsys/common/osd.c
index 55ecdf1012..7444bee129 100644
--- a/board/gdsys/common/osd.c
+++ b/board/gdsys/common/osd.c
@@ -9,11 +9,10 @@
#include <i2c.h>
#include <malloc.h>
+#include "ch7301.h"
#include "dp501.h"
#include <gdsys_fpga.h>
-#define CH7301_I2C_ADDR 0x75
-
#define ICS8N3QV01_I2C_ADDR 0x6E
#define ICS8N3QV01_FREF 114285000
#define ICS8N3QV01_FREF_LL 114285000LL
@@ -28,43 +27,53 @@
#define DP501_I2C_ADDR 0x08
#define PIXCLK_640_480_60 25180000
+#define MAX_X_CHARS 53
+#define MAX_Y_CHARS 26
+
+#ifdef CONFIG_SYS_OSD_DH
+#define MAX_OSD_SCREEN 8
+#define OSD_DH_BASE 4
+#else
+#define MAX_OSD_SCREEN 4
+#endif
+
+#ifdef CONFIG_SYS_OSD_DH
+#define OSD_SET_REG(screen, fld, val) \
+ do { \
+ if (screen >= OSD_DH_BASE) \
+ FPGA_SET_REG(screen - OSD_DH_BASE, osd1.fld, val); \
+ else \
+ FPGA_SET_REG(screen, osd0.fld, val); \
+ } while (0)
+#else
+#define OSD_SET_REG(screen, fld, val) \
+ FPGA_SET_REG(screen, osd0.fld, val)
+#endif
-enum {
- CH7301_CM = 0x1c, /* Clock Mode Register */
- CH7301_IC = 0x1d, /* Input Clock Register */
- CH7301_GPIO = 0x1e, /* GPIO Control Register */
- CH7301_IDF = 0x1f, /* Input Data Format Register */
- CH7301_CD = 0x20, /* Connection Detect Register */
- CH7301_DC = 0x21, /* DAC Control Register */
- CH7301_HPD = 0x23, /* Hot Plug Detection Register */
- CH7301_TCTL = 0x31, /* DVI Control Input Register */
- CH7301_TPCP = 0x33, /* DVI PLL Charge Pump Ctrl Register */
- CH7301_TPD = 0x34, /* DVI PLL Divide Register */
- CH7301_TPVT = 0x35, /* DVI PLL Supply Control Register */
- CH7301_TPF = 0x36, /* DVI PLL Filter Register */
- CH7301_TCT = 0x37, /* DVI Clock Test Register */
- CH7301_TSTP = 0x48, /* Test Pattern Register */
- CH7301_PM = 0x49, /* Power Management register */
- CH7301_VID = 0x4a, /* Version ID Register */
- CH7301_DID = 0x4b, /* Device ID Register */
- CH7301_DSP = 0x56, /* DVI Sync polarity Register */
-};
+#ifdef CONFIG_SYS_OSD_DH
+#define OSD_GET_REG(screen, fld, val) \
+ do { \
+ if (screen >= OSD_DH_BASE) \
+ FPGA_GET_REG(screen - OSD_DH_BASE, osd1.fld, val); \
+ else \
+ FPGA_GET_REG(screen, osd0.fld, val); \
+ } while (0)
+#else
+#define OSD_GET_REG(screen, fld, val) \
+ FPGA_GET_REG(screen, osd0.fld, val)
+#endif
unsigned int base_width;
unsigned int base_height;
size_t bufsize;
u16 *buf;
-unsigned int max_osd_screen = CONFIG_SYS_OSD_SCREENS - 1;
+unsigned int osd_screen_mask = 0;
#ifdef CONFIG_SYS_ICS8N3QV01_I2C
int ics8n3qv01_i2c[] = CONFIG_SYS_ICS8N3QV01_I2C;
#endif
-#ifdef CONFIG_SYS_CH7301_I2C
-int ch7301_i2c[] = CONFIG_SYS_CH7301_I2C;
-#endif
-
#ifdef CONFIG_SYS_SIL1178_I2C
int sil1178_i2c[] = CONFIG_SYS_SIL1178_I2C;
#endif
@@ -73,6 +82,9 @@ int sil1178_i2c[] = CONFIG_SYS_SIL1178_I2C;
int dp501_i2c[] = CONFIG_SYS_DP501_I2C;
#endif
+#ifdef CONFIG_SYS_DP501_BASE
+int dp501_base[] = CONFIG_SYS_DP501_BASE;
+#endif
#ifdef CONFIG_SYS_MPC92469AC
static void mpc92469ac_calc_parameters(unsigned int fout,
@@ -242,7 +254,15 @@ static int osd_write_videomem(unsigned screen, unsigned offset,
for (k = 0; k < charcount; ++k) {
if (offset + k >= bufsize)
return -1;
- FPGA_SET_REG(screen, videomem[offset + k], data[k]);
+#ifdef CONFIG_SYS_OSD_DH
+ if (screen >= OSD_DH_BASE)
+ FPGA_SET_REG(screen - OSD_DH_BASE,
+ videomem1[offset + k], data[k]);
+ else
+ FPGA_SET_REG(screen, videomem0[offset + k], data[k]);
+#else
+ FPGA_SET_REG(screen, videomem0[offset + k], data[k]);
+#endif
}
return charcount;
@@ -252,7 +272,12 @@ static int osd_print(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
unsigned screen;
- for (screen = 0; screen <= max_osd_screen; ++screen) {
+ if (argc < 5) {
+ cmd_usage(cmdtp);
+ return 1;
+ }
+
+ for (screen = 0; screen < MAX_OSD_SCREEN; ++screen) {
unsigned x;
unsigned y;
unsigned charcount;
@@ -262,10 +287,8 @@ static int osd_print(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
char *text;
int res;
- if (argc < 5) {
- cmd_usage(cmdtp);
- return 1;
- }
+ if (!(osd_screen_mask & (1 << screen)))
+ continue;
x = simple_strtoul(argv[1], NULL, 16);
y = simple_strtoul(argv[2], NULL, 16);
@@ -280,6 +303,8 @@ static int osd_print(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
res = osd_write_videomem(screen, y * base_width + x, buf, len);
if (res < 0)
return res;
+
+ OSD_SET_REG(screen, control, 0x0049);
}
return 0;
@@ -292,9 +317,16 @@ int osd_probe(unsigned screen)
int old_bus = i2c_get_bus_num();
bool pixclock_present = false;
bool output_driver_present = false;
+#ifdef CONFIG_SYS_DP501_I2C
+#ifdef CONFIG_SYS_DP501_BASE
+ uint8_t dp501_addr = dp501_base[screen];
+#else
+ uint8_t dp501_addr = DP501_I2C_ADDR;
+#endif
+#endif
- FPGA_GET_REG(0, osd.version, &version);
- FPGA_GET_REG(0, osd.features, &features);
+ OSD_GET_REG(0, version, &version);
+ OSD_GET_REG(0, features, &features);
base_width = ((features & 0x3f00) >> 8) + 1;
base_height = (features & 0x001f) + 1;
@@ -303,9 +335,15 @@ int osd_probe(unsigned screen)
if (!buf)
return -1;
+#ifdef CONFIG_SYS_OSD_DH
+ printf("OSD%d-%d: Digital-OSD version %01d.%02d, %d" "x%d characters\n",
+ (screen >= OSD_DH_BASE) ? (screen - OSD_DH_BASE) : screen,
+ (screen > 3) ? 1 : 0, version/100, version%100, base_width,
+ base_height);
+#else
printf("OSD%d: Digital-OSD version %01d.%02d, %d" "x%d characters\n",
- screen, version/100, version%100, base_width, base_height);
-
+ screen, version/100, version%100, base_width, base_height);
+#endif
/* setup pixclock */
#ifdef CONFIG_SYS_MPC92469AC
@@ -327,19 +365,8 @@ int osd_probe(unsigned screen)
/* setup output driver */
#ifdef CONFIG_SYS_CH7301_I2C
- i2c_set_bus_num(ch7301_i2c[screen]);
- if (!i2c_probe(CH7301_I2C_ADDR)) {
- u8 value = i2c_reg_read(CH7301_I2C_ADDR, CH7301_DID);
-
- if (value == 0x17) {
- i2c_reg_write(CH7301_I2C_ADDR, CH7301_TPCP, 0x08);
- i2c_reg_write(CH7301_I2C_ADDR, CH7301_TPD, 0x16);
- i2c_reg_write(CH7301_I2C_ADDR, CH7301_TPF, 0x60);
- i2c_reg_write(CH7301_I2C_ADDR, CH7301_DC, 0x09);
- i2c_reg_write(CH7301_I2C_ADDR, CH7301_PM, 0xc0);
- output_driver_present = true;
- }
- }
+ if (!ch7301_probe(screen, true))
+ output_driver_present = true;
#endif
#ifdef CONFIG_SYS_SIL1178_I2C
@@ -367,8 +394,8 @@ int osd_probe(unsigned screen)
#ifdef CONFIG_SYS_DP501_I2C
i2c_set_bus_num(dp501_i2c[screen]);
- if (!i2c_probe(DP501_I2C_ADDR)) {
- dp501_powerup(DP501_I2C_ADDR);
+ if (!i2c_probe(dp501_addr)) {
+ dp501_powerup(dp501_addr);
output_driver_present = true;
}
#endif
@@ -376,14 +403,12 @@ int osd_probe(unsigned screen)
if (!output_driver_present)
printf(" no output driver found\n");
- FPGA_SET_REG(screen, osd.control, 0x0049);
-
- FPGA_SET_REG(screen, osd.xy_size, ((32 - 1) << 8) | (16 - 1));
- FPGA_SET_REG(screen, osd.x_pos, 0x007f);
- FPGA_SET_REG(screen, osd.y_pos, 0x005f);
+ OSD_SET_REG(screen, xy_size, ((32 - 1) << 8) | (16 - 1));
+ OSD_SET_REG(screen, x_pos, 0x007f);
+ OSD_SET_REG(screen, y_pos, 0x005f);
- if (screen > max_osd_screen)
- max_osd_screen = screen;
+ if (pixclock_present && output_driver_present)
+ osd_screen_mask |= 1 << screen;
i2c_set_bus_num(old_bus);
@@ -394,7 +419,12 @@ int osd_write(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
unsigned screen;
- for (screen = 0; screen <= max_osd_screen; ++screen) {
+ if ((argc < 4) || (strlen(argv[3]) % 4)) {
+ cmd_usage(cmdtp);
+ return 1;
+ }
+
+ for (screen = 0; screen < MAX_OSD_SCREEN; ++screen) {
unsigned x;
unsigned y;
unsigned k;
@@ -404,10 +434,8 @@ int osd_write(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
unsigned count = (argc > 4) ?
simple_strtoul(argv[4], NULL, 16) : 1;
- if ((argc < 4) || (strlen(argv[3]) % 4)) {
- cmd_usage(cmdtp);
- return 1;
- }
+ if (!(osd_screen_mask & (1 << screen)))
+ continue;
x = simple_strtoul(argv[1], NULL, 16);
y = simple_strtoul(argv[2], NULL, 16);
@@ -433,6 +461,37 @@ int osd_write(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
osd_write_videomem(screen, offset, buffer,
wp - buffer);
}
+
+ OSD_SET_REG(screen, control, 0x0049);
+ }
+
+ return 0;
+}
+
+int osd_size(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+ unsigned screen;
+ unsigned x;
+ unsigned y;
+
+ if (argc < 3) {
+ cmd_usage(cmdtp);
+ return 1;
+ }
+
+ x = simple_strtoul(argv[1], NULL, 16);
+ y = simple_strtoul(argv[2], NULL, 16);
+
+ if (!x || (x > 64) || (x > MAX_X_CHARS) ||
+ !y || (y > 32) || (y > MAX_Y_CHARS)) {
+ cmd_usage(cmdtp);
+ return 1;
+ }
+
+ for (screen = 0; screen < MAX_OSD_SCREEN; ++screen) {
+ OSD_SET_REG(screen, xy_size, ((x - 1) << 8) | (y - 1));
+ OSD_SET_REG(screen, x_pos, 32767 * (640 - 12 * x) / 65535);
+ OSD_SET_REG(screen, y_pos, 32767 * (480 - 18 * y) / 65535);
}
return 0;
@@ -449,3 +508,10 @@ U_BOOT_CMD(
"write ASCII buffer to osd memory",
"pos_x pos_y color text\n"
);
+
+U_BOOT_CMD(
+ osdsize, 3, 0, osd_size,
+ "set OSD XY size in characters",
+ "size_x(max. " __stringify(MAX_X_CHARS)
+ ") size_y(max. " __stringify(MAX_Y_CHARS) ")\n"
+);
OpenPOWER on IntegriCloud