diff options
Diffstat (limited to 'board/gdsys')
-rw-r--r-- | board/gdsys/405ep/405ep.c | 22 | ||||
-rw-r--r-- | board/gdsys/405ep/dlvision-10g.c | 18 | ||||
-rw-r--r-- | board/gdsys/405ep/io.c | 16 | ||||
-rw-r--r-- | board/gdsys/405ep/iocon.c | 654 | ||||
-rw-r--r-- | board/gdsys/405ep/neo.c | 13 | ||||
-rw-r--r-- | board/gdsys/405ex/405ex.c | 22 | ||||
-rw-r--r-- | board/gdsys/405ex/io64.c | 34 | ||||
-rw-r--r-- | board/gdsys/common/Makefile | 4 | ||||
-rw-r--r-- | board/gdsys/common/dp501.c | 18 | ||||
-rw-r--r-- | board/gdsys/common/fpga.c | 25 | ||||
-rw-r--r-- | board/gdsys/common/mclink.c | 137 | ||||
-rw-r--r-- | board/gdsys/common/mclink.h | 15 | ||||
-rw-r--r-- | board/gdsys/common/osd.c | 118 |
13 files changed, 936 insertions, 160 deletions
diff --git a/board/gdsys/405ep/405ep.c b/board/gdsys/405ep/405ep.c index f0df2e3..426dc05 100644 --- a/board/gdsys/405ep/405ep.c +++ b/board/gdsys/405ep/405ep.c @@ -18,6 +18,12 @@ #define REFLECTION_TESTPATTERN 0xdede #define REFLECTION_TESTPATTERN_INV (~REFLECTION_TESTPATTERN & 0xffff) +#ifdef CONFIG_SYS_FPGA_NO_RFL_HI +#define REFLECTION_TESTREG reflection_low +#else +#define REFLECTION_TESTREG reflection_high +#endif + DECLARE_GLOBAL_DATA_PTR; int get_fpga_state(unsigned dev) @@ -90,23 +96,17 @@ int board_early_init_r(void) gd405ep_set_fpga_reset(0); for (k = 0; k < CONFIG_SYS_FPGA_COUNT; ++k) { - struct ihs_fpga *fpga = - (struct ihs_fpga *)CONFIG_SYS_FPGA_BASE(k); -#ifdef CONFIG_SYS_FPGA_NO_RFL_HI - u16 *reflection_target = &fpga->reflection_low; -#else - u16 *reflection_target = &fpga->reflection_high; -#endif /* * wait for fpga out of reset */ ctr = 0; while (1) { - out_le16(&fpga->reflection_low, - REFLECTION_TESTPATTERN); + u16 val; + + FPGA_SET_REG(k, reflection_low, REFLECTION_TESTPATTERN); - if (in_le16(reflection_target) == - REFLECTION_TESTPATTERN_INV) + FPGA_GET_REG(k, REFLECTION_TESTREG, &val); + if (val == REFLECTION_TESTPATTERN_INV) break; udelay(100000); diff --git a/board/gdsys/405ep/dlvision-10g.c b/board/gdsys/405ep/dlvision-10g.c index 48d8786..35dfbbc 100644 --- a/board/gdsys/405ep/dlvision-10g.c +++ b/board/gdsys/405ep/dlvision-10g.c @@ -55,6 +55,8 @@ enum { RAM_DDR2_64 = 2, }; +struct ihs_fpga *fpga_ptr[] = CONFIG_SYS_FPGA_PTR; + int misc_init_r(void) { /* startup fans */ @@ -79,10 +81,9 @@ static unsigned int get_mc2_present(void) static void print_fpga_info(unsigned dev) { - struct ihs_fpga *fpga = (struct ihs_fpga *) CONFIG_SYS_FPGA_BASE(dev); - u16 versions = in_le16(&fpga->versions); - u16 fpga_version = in_le16(&fpga->fpga_version); - u16 fpga_features = in_le16(&fpga->fpga_features); + u16 versions; + u16 fpga_version; + u16 fpga_features; unsigned unit_type; unsigned hardware_version; unsigned feature_rs232; @@ -96,6 +97,10 @@ static void print_fpga_info(unsigned dev) printf("FPGA%d: ", dev); + FPGA_GET_REG(dev, versions, &versions); + FPGA_GET_REG(dev, fpga_version, &fpga_version); + FPGA_GET_REG(dev, fpga_features, &fpga_features); + hardware_version = versions & 0x000f; if (fpga_state @@ -247,8 +252,9 @@ int checkboard(void) int last_stage_init(void) { - struct ihs_fpga *fpga = (struct ihs_fpga *) CONFIG_SYS_FPGA_BASE(0); - u16 versions = in_le16(&fpga->versions); + u16 versions; + + FPGA_GET_REG(0, versions, &versions); print_fpga_info(0); if (get_mc2_present()) diff --git a/board/gdsys/405ep/io.c b/board/gdsys/405ep/io.c index eee9ba0..03d796c 100644 --- a/board/gdsys/405ep/io.c +++ b/board/gdsys/405ep/io.c @@ -37,6 +37,8 @@ enum { HWVER_122 = 3, }; +struct ihs_fpga *fpga_ptr[] = CONFIG_SYS_FPGA_PTR; + int misc_init_r(void) { /* startup fans */ @@ -101,15 +103,18 @@ int checkboard(void) static void print_fpga_info(void) { - struct ihs_fpga *fpga = (struct ihs_fpga *) CONFIG_SYS_FPGA_BASE(0); - u16 versions = in_le16(&fpga->versions); - u16 fpga_version = in_le16(&fpga->fpga_version); - u16 fpga_features = in_le16(&fpga->fpga_features); + u16 versions; + u16 fpga_version; + u16 fpga_features; unsigned unit_type; unsigned hardware_version; unsigned feature_channels; unsigned feature_expansion; + FPGA_GET_REG(0, versions, &versions); + FPGA_GET_REG(0, fpga_version, &fpga_version); + FPGA_GET_REG(0, fpga_features, &fpga_features); + unit_type = (versions & 0xf000) >> 12; hardware_version = versions & 0x000f; feature_channels = fpga_features & 0x007f; @@ -163,7 +168,6 @@ static void print_fpga_info(void) */ int last_stage_init(void) { - struct ihs_fpga *fpga = (struct ihs_fpga *) CONFIG_SYS_FPGA_BASE(0); unsigned int k; print_fpga_info(); @@ -175,7 +179,7 @@ int last_stage_init(void) configure_gbit_phy(k); /* take fpga serdes blocks out of reset */ - out_le16(&fpga->quad_serdes_reset, 0); + FPGA_SET_REG(0, quad_serdes_reset, 0); return 0; } diff --git a/board/gdsys/405ep/iocon.c b/board/gdsys/405ep/iocon.c index c728bc7..7a98e41 100644 --- a/board/gdsys/405ep/iocon.c +++ b/board/gdsys/405ep/iocon.c @@ -7,6 +7,7 @@ #include <common.h> #include <command.h> +#include <errno.h> #include <asm/processor.h> #include <asm/io.h> #include <asm/ppc4xx-gpio.h> @@ -15,11 +16,22 @@ #include <gdsys_fpga.h> #include "../common/osd.h" +#include "../common/mclink.h" + +#include <i2c.h> +#include <pca953x.h> +#include <pca9698.h> + +#include <miiphy.h> + +DECLARE_GLOBAL_DATA_PTR; #define LATCH0_BASE (CONFIG_SYS_LATCH_BASE) #define LATCH1_BASE (CONFIG_SYS_LATCH_BASE + 0x100) #define LATCH2_BASE (CONFIG_SYS_LATCH_BASE + 0x200) +#define MAX_MUX_CHANNELS 2 + enum { UNITTYPE_MAIN_SERVER = 0, UNITTYPE_MAIN_USER = 1, @@ -31,11 +43,22 @@ enum { HWVER_100 = 0, HWVER_104 = 1, HWVER_110 = 2, + HWVER_120 = 3, + HWVER_200 = 4, + HWVER_210 = 5, + HWVER_220 = 6, + HWVER_230 = 7, +}; + +enum { + FPGA_HWVER_200 = 0, + FPGA_HWVER_210 = 1, }; enum { COMPRESSION_NONE = 0, - COMPRESSION_TYPE1_DELTA, + COMPRESSION_TYPE1_DELTA = 1, + COMPRESSION_TYPE1_TYPE2_DELTA = 3, }; enum { @@ -51,8 +74,75 @@ enum { enum { RAM_DDR2_32 = 0, + RAM_DDR3_32 = 1, }; +enum { + CARRIER_SPEED_1G = 0, + CARRIER_SPEED_2_5G = 1, +}; + +enum { + MCFPGA_DONE = 1 << 0, + MCFPGA_INIT_N = 1 << 1, + MCFPGA_PROGRAM_N = 1 << 2, + MCFPGA_UPDATE_ENABLE_N = 1 << 3, + MCFPGA_RESET_N = 1 << 4, +}; + +enum { + GPIO_MDC = 1 << 14, + GPIO_MDIO = 1 << 15, +}; + +unsigned int mclink_fpgacount; +struct ihs_fpga *fpga_ptr[] = CONFIG_SYS_FPGA_PTR; + +static int setup_88e1518(const char *bus, unsigned char addr); + +int fpga_set_reg(u32 fpga, u16 *reg, off_t regoff, u16 data) +{ + int res; + + switch (fpga) { + case 0: + out_le16(reg, data); + break; + default: + res = mclink_send(fpga - 1, regoff, data); + if (res < 0) { + printf("mclink_send reg %02lx data %04x returned %d\n", + regoff, data, res); + return res; + } + break; + } + + return 0; +} + +int fpga_get_reg(u32 fpga, u16 *reg, off_t regoff, u16 *data) +{ + int res; + + switch (fpga) { + case 0: + *data = in_le16(reg); + break; + default: + if (fpga > mclink_fpgacount) + return -EINVAL; + res = mclink_receive(fpga - 1, regoff, data); + if (res < 0) { + printf("mclink_receive reg %02lx returned %d\n", + regoff, res); + return res; + } + } + + return 0; +} + /* * Check Board Identity: */ @@ -74,12 +164,11 @@ int checkboard(void) return 0; } -static void print_fpga_info(void) +static void print_fpga_info(unsigned int fpga, bool rgmii2_present) { - struct ihs_fpga *fpga = (struct ihs_fpga *) CONFIG_SYS_FPGA_BASE(0); - u16 versions = in_le16(&fpga->versions); - u16 fpga_version = in_le16(&fpga->fpga_version); - u16 fpga_features = in_le16(&fpga->fpga_features); + u16 versions; + u16 fpga_version; + u16 fpga_features; unsigned unit_type; unsigned hardware_version; unsigned feature_compression; @@ -87,19 +176,29 @@ static void print_fpga_info(void) unsigned feature_audio; unsigned feature_sysclock; unsigned feature_ramconfig; + unsigned feature_carrier_speed; unsigned feature_carriers; unsigned feature_video_channels; + int legacy = get_fpga_state(0) & FPGA_STATE_PLATFORM; + + FPGA_GET_REG(0, versions, &versions); + FPGA_GET_REG(0, fpga_version, &fpga_version); + FPGA_GET_REG(0, fpga_features, &fpga_features); + unit_type = (versions & 0xf000) >> 12; - hardware_version = versions & 0x000f; feature_compression = (fpga_features & 0xe000) >> 13; feature_osd = fpga_features & (1<<11); feature_audio = (fpga_features & 0x0600) >> 9; feature_sysclock = (fpga_features & 0x0180) >> 7; feature_ramconfig = (fpga_features & 0x0060) >> 5; + feature_carrier_speed = fpga_features & (1<<4); feature_carriers = (fpga_features & 0x000c) >> 2; feature_video_channels = fpga_features & 0x0003; + if (legacy) + printf("legacy "); + switch (unit_type) { case UNITTYPE_MAIN_USER: printf("Mainchannel"); @@ -114,27 +213,78 @@ static void print_fpga_info(void) break; } - switch (hardware_version) { - case HWVER_100: - printf(" HW-Ver 1.00\n"); - break; - - case HWVER_104: - printf(" HW-Ver 1.04\n"); - break; - - case HWVER_110: - printf(" HW-Ver 1.10\n"); - break; + if (unit_type == UNITTYPE_MAIN_USER) { + if (legacy) + hardware_version = + (in_le16((void *)LATCH2_BASE)>>8) & 0x0f; + else + hardware_version = + (!!pca9698_get_value(0x20, 24) << 0) + | (!!pca9698_get_value(0x20, 25) << 1) + | (!!pca9698_get_value(0x20, 26) << 2) + | (!!pca9698_get_value(0x20, 27) << 3); + switch (hardware_version) { + case HWVER_100: + printf(" HW-Ver 1.00,"); + break; + + case HWVER_104: + printf(" HW-Ver 1.04,"); + break; + + case HWVER_110: + printf(" HW-Ver 1.10,"); + break; + + case HWVER_120: + printf(" HW-Ver 1.20-1.21,"); + break; + + case HWVER_200: + printf(" HW-Ver 2.00,"); + break; + + case HWVER_210: + printf(" HW-Ver 2.10,"); + break; + + case HWVER_220: + printf(" HW-Ver 2.20,"); + break; + + case HWVER_230: + printf(" HW-Ver 2.30,"); + break; + + default: + printf(" HW-Ver %d(not supported),", + hardware_version); + break; + } + if (rgmii2_present) + printf(" RGMII2,"); + } - default: - printf(" HW-Ver %d(not supported)\n", - hardware_version); - break; + if (unit_type == UNITTYPE_VIDEO_USER) { + hardware_version = versions & 0x000f; + switch (hardware_version) { + case FPGA_HWVER_200: + printf(" HW-Ver 2.00,"); + break; + + case FPGA_HWVER_210: + printf(" HW-Ver 2.10,"); + break; + + default: + printf(" HW-Ver %d(not supported),", + hardware_version); + break; + } } - printf(" FPGA V %d.%02d, features:", - fpga_version / 100, fpga_version % 100); + printf(" FPGA V %d.%02d\n features:", + fpga_version / 100, fpga_version % 100); switch (feature_compression) { @@ -146,6 +296,10 @@ static void print_fpga_info(void) printf(" type1-deltacompression"); break; + case COMPRESSION_TYPE1_TYPE2_DELTA: + printf(" type1-deltacompression, type2-inlinecompression"); + break; + default: printf(" compression %d(not supported)", feature_compression); break; @@ -192,53 +346,145 @@ static void print_fpga_info(void) printf(", RAM 32 bit DDR2"); break; + case RAM_DDR3_32: + printf(", RAM 32 bit DDR3"); + break; + default: printf(", RAM %d(not supported)", feature_ramconfig); break; } - printf(", %d carrier(s)", feature_carriers); + printf(", %d carrier(s) %s", feature_carriers, + feature_carrier_speed ? "2.5Gbit/s" : "1Gbit/s"); printf(", %d video channel(s)\n", feature_video_channels); } int last_stage_init(void) { - print_fpga_info(); + int slaves; + unsigned int k; + unsigned int mux_ch; + unsigned char mclink_controllers[] = { 0x24, 0x25, 0x26 }; + int legacy = get_fpga_state(0) & FPGA_STATE_PLATFORM; + u16 fpga_features; + int feature_carrier_speed = fpga_features & (1<<4); + bool ch0_rgmii2_present = false; + + FPGA_GET_REG(0, fpga_features, &fpga_features); + + if (!legacy) + ch0_rgmii2_present = !pca9698_get_value(0x20, 30); + + print_fpga_info(0, ch0_rgmii2_present); + osd_probe(0); + + /* wait for FPGA done */ + for (k = 0; k < ARRAY_SIZE(mclink_controllers); ++k) { + unsigned int ctr = 0; + + if (i2c_probe(mclink_controllers[k])) + continue; + + while (!(pca953x_get_val(mclink_controllers[k]) + & MCFPGA_DONE)) { + udelay(100000); + if (ctr++ > 5) { + printf("no done for mclink_controller %d\n", k); + break; + } + } + } + + if (!legacy && (feature_carrier_speed == CARRIER_SPEED_1G)) { + miiphy_register(bb_miiphy_buses[0].name, bb_miiphy_read, + bb_miiphy_write); + for (mux_ch = 0; mux_ch < MAX_MUX_CHANNELS; ++mux_ch) { + if ((mux_ch == 1) && !ch0_rgmii2_present) + continue; + + setup_88e1518(bb_miiphy_buses[0].name, mux_ch); + } + } + + /* wait for slave-PLLs to be up and running */ + udelay(500000); + + mclink_fpgacount = CONFIG_SYS_MCLINK_MAX; + slaves = mclink_probe(); + mclink_fpgacount = 0; + + if (slaves <= 0) + return 0; + + mclink_fpgacount = slaves; + + for (k = 1; k <= slaves; ++k) { + FPGA_GET_REG(k, fpga_features, &fpga_features); + feature_carrier_speed = fpga_features & (1<<4); + + print_fpga_info(k, false); + osd_probe(k); + if (feature_carrier_speed == CARRIER_SPEED_1G) { + miiphy_register(bb_miiphy_buses[k].name, + bb_miiphy_read, bb_miiphy_write); + setup_88e1518(bb_miiphy_buses[k].name, 0); + } + } - return osd_probe(0); + return 0; } /* * provide access to fpga gpios (for I2C bitbang) + * (these may look all too simple but make iocon.h much more readable) */ -void fpga_gpio_set(int pin) +void fpga_gpio_set(unsigned int bus, int pin) { - out_le16((void *)(CONFIG_SYS_FPGA0_BASE + 0x18), pin); + FPGA_SET_REG(bus, gpio.set, pin); } -void fpga_gpio_clear(int pin) +void fpga_gpio_clear(unsigned int bus, int pin) { - out_le16((void *)(CONFIG_SYS_FPGA0_BASE + 0x16), pin); + FPGA_SET_REG(bus, gpio.clear, pin); } -int fpga_gpio_get(int pin) +int fpga_gpio_get(unsigned int bus, int pin) { - return in_le16((void *)(CONFIG_SYS_FPGA0_BASE + 0x14)) & pin; + u16 val; + + FPGA_GET_REG(bus, gpio.read, &val); + + return val & pin; } void gd405ep_init(void) { + unsigned int k; + + if (i2c_probe(0x20)) { /* i2c_probe returns 0 on success */ + for (k = 0; k < CONFIG_SYS_FPGA_COUNT; ++k) + gd->arch.fpga_state[k] |= FPGA_STATE_PLATFORM; + } else { + pca9698_direction_output(0x20, 4, 1); + } } void gd405ep_set_fpga_reset(unsigned state) { - if (state) { - out_le16((void *)LATCH0_BASE, CONFIG_SYS_LATCH0_RESET); - out_le16((void *)LATCH1_BASE, CONFIG_SYS_LATCH1_RESET); + int legacy = get_fpga_state(0) & FPGA_STATE_PLATFORM; + + if (legacy) { + if (state) { + out_le16((void *)LATCH0_BASE, CONFIG_SYS_LATCH0_RESET); + out_le16((void *)LATCH1_BASE, CONFIG_SYS_LATCH1_RESET); + } else { + out_le16((void *)LATCH0_BASE, CONFIG_SYS_LATCH0_BOOT); + out_le16((void *)LATCH1_BASE, CONFIG_SYS_LATCH1_BOOT); + } } else { - out_le16((void *)LATCH0_BASE, CONFIG_SYS_LATCH0_BOOT); - out_le16((void *)LATCH1_BASE, CONFIG_SYS_LATCH1_BOOT); + pca9698_set_value(0x20, 4, state ? 0 : 1); } } @@ -253,5 +499,333 @@ void gd405ep_setup_hw(void) int gd405ep_get_fpga_done(unsigned fpga) { - return in_le16((void *)LATCH2_BASE) & CONFIG_SYS_FPGA_DONE(fpga); + int legacy = get_fpga_state(0) & FPGA_STATE_PLATFORM; + + if (legacy) + return in_le16((void *)LATCH2_BASE) + & CONFIG_SYS_FPGA_DONE(fpga); + else + return pca9698_get_value(0x20, 20); +} + +/* + * FPGA MII bitbang implementation + */ + +struct fpga_mii { + unsigned fpga; + int mdio; +} fpga_mii[] = { + { 0, 1}, + { 1, 1}, + { 2, 1}, + { 3, 1}, +}; + +static int mii_dummy_init(struct bb_miiphy_bus *bus) +{ + return 0; +} + +static int mii_mdio_active(struct bb_miiphy_bus *bus) +{ + struct fpga_mii *fpga_mii = bus->priv; + + if (fpga_mii->mdio) + FPGA_SET_REG(fpga_mii->fpga, gpio.set, GPIO_MDIO); + else + FPGA_SET_REG(fpga_mii->fpga, gpio.clear, GPIO_MDIO); + + return 0; +} + +static int mii_mdio_tristate(struct bb_miiphy_bus *bus) +{ + struct fpga_mii *fpga_mii = bus->priv; + + FPGA_SET_REG(fpga_mii->fpga, gpio.set, GPIO_MDIO); + + return 0; +} + +static int mii_set_mdio(struct bb_miiphy_bus *bus, int v) +{ + struct fpga_mii *fpga_mii = bus->priv; + + if (v) + FPGA_SET_REG(fpga_mii->fpga, gpio.set, GPIO_MDIO); + else + FPGA_SET_REG(fpga_mii->fpga, gpio.clear, GPIO_MDIO); + + fpga_mii->mdio = v; + + return 0; +} + +static int mii_get_mdio(struct bb_miiphy_bus *bus, int *v) +{ + u16 gpio; + struct fpga_mii *fpga_mii = bus->priv; + + FPGA_GET_REG(fpga_mii->fpga, gpio.read, &gpio); + + *v = ((gpio & GPIO_MDIO) != 0); + + return 0; +} + +static int mii_set_mdc(struct bb_miiphy_bus *bus, int v) +{ + struct fpga_mii *fpga_mii = bus->priv; + + if (v) + FPGA_SET_REG(fpga_mii->fpga, gpio.set, GPIO_MDC); + else + FPGA_SET_REG(fpga_mii->fpga, gpio.clear, GPIO_MDC); + + return 0; +} + +static int mii_delay(struct bb_miiphy_bus *bus) +{ + udelay(1); + + return 0; +} + +struct bb_miiphy_bus bb_miiphy_buses[] = { + { + .name = "board0", + .init = mii_dummy_init, + .mdio_active = mii_mdio_active, + .mdio_tristate = mii_mdio_tristate, + .set_mdio = mii_set_mdio, + .get_mdio = mii_get_mdio, + .set_mdc = mii_set_mdc, + .delay = mii_delay, + .priv = &fpga_mii[0], + }, + { + .name = "board1", + .init = mii_dummy_init, + .mdio_active = mii_mdio_active, + .mdio_tristate = mii_mdio_tristate, + .set_mdio = mii_set_mdio, + .get_mdio = mii_get_mdio, + .set_mdc = mii_set_mdc, + .delay = mii_delay, + .priv = &fpga_mii[1], + }, + { + .name = "board2", + .init = mii_dummy_init, + .mdio_active = mii_mdio_active, + .mdio_tristate = mii_mdio_tristate, + .set_mdio = mii_set_mdio, + .get_mdio = mii_get_mdio, + .set_mdc = mii_set_mdc, + .delay = mii_delay, + .priv = &fpga_mii[2], + }, + { + .name = "board3", + .init = mii_dummy_init, + .mdio_active = mii_mdio_active, + .mdio_tristate = mii_mdio_tristate, + .set_mdio = mii_set_mdio, + .get_mdio = mii_get_mdio, + .set_mdc = mii_set_mdc, + .delay = mii_delay, + .priv = &fpga_mii[3], + }, +}; + +int bb_miiphy_buses_num = sizeof(bb_miiphy_buses) / + sizeof(bb_miiphy_buses[0]); + +enum { + MIICMD_SET, + MIICMD_MODIFY, + MIICMD_VERIFY_VALUE, + MIICMD_WAIT_FOR_VALUE, +}; + +struct mii_setupcmd { + u8 token; + u8 reg; + u16 data; + u16 mask; + u32 timeout; +}; + +/* + * verify we are talking to a 88e1518 + */ +struct mii_setupcmd verify_88e1518[] = { + { MIICMD_SET, 22, 0x0000 }, + { MIICMD_VERIFY_VALUE, 2, 0x0141, 0xffff }, + { MIICMD_VERIFY_VALUE, 3, 0x0dd0, 0xfff0 }, +}; + +/* + * workaround for erratum mentioned in 88E1518 release notes + */ +struct mii_setupcmd fixup_88e1518[] = { + { MIICMD_SET, 22, 0x00ff }, + { MIICMD_SET, 17, 0x214b }, + { MIICMD_SET, 16, 0x2144 }, + { MIICMD_SET, 17, 0x0c28 }, + { MIICMD_SET, 16, 0x2146 }, + { MIICMD_SET, 17, 0xb233 }, + { MIICMD_SET, 16, 0x214d }, + { MIICMD_SET, 17, 0xcc0c }, + { MIICMD_SET, 16, 0x2159 }, + { MIICMD_SET, 22, 0x00fb }, + { MIICMD_SET, 7, 0xc00d }, + { MIICMD_SET, 22, 0x0000 }, +}; + +/* + * default initialization: + * - set RGMII receive timing to "receive clock transition when data stable" + * - set RGMII transmit timing to "transmit clock internally delayed" + * - set RGMII output impedance target to 78,8 Ohm + * - run output impedance calibration + * - set autonegotiation advertise to 1000FD only + */ +struct mii_setupcmd default_88e1518[] = { + { MIICMD_SET, 22, 0x0002 }, + { MIICMD_MODIFY, 21, 0x0030, 0x0030 }, + { MIICMD_MODIFY, 25, 0x0000, 0x0003 }, + { MIICMD_MODIFY, 24, 0x8000, 0x8000 }, + { MIICMD_WAIT_FOR_VALUE, 24, 0x4000, 0x4000, 2000 }, + { MIICMD_SET, 22, 0x0000 }, + { MIICMD_MODIFY, 4, 0x0000, 0x01e0 }, + { MIICMD_MODIFY, 9, 0x0200, 0x0300 }, +}; + +/* + * turn off CLK125 for PHY daughterboard + */ +struct mii_setupcmd ch1fix_88e1518[] = { + { MIICMD_SET, 22, 0x0002 }, + { MIICMD_MODIFY, 16, 0x0006, 0x0006 }, + { MIICMD_SET, 22, 0x0000 }, +}; + +/* + * perform copper software reset + */ +struct mii_setupcmd swreset_88e1518[] = { + { MIICMD_SET, 22, 0x0000 }, + { MIICMD_MODIFY, 0, 0x8000, 0x8000 }, + { MIICMD_WAIT_FOR_VALUE, 0, 0x0000, 0x8000, 2000 }, +}; + +static int process_setupcmd(const char *bus, unsigned char addr, + struct mii_setupcmd *setupcmd) +{ + int res; + u8 reg = setupcmd->reg; + u16 data = setupcmd->data; + u16 mask = setupcmd->mask; + u32 timeout = setupcmd->timeout; + u16 orig_data; + unsigned long start; + + debug("mii %s:%u reg %2u ", bus, addr, reg); + + switch (setupcmd->token) { + case MIICMD_MODIFY: + res = miiphy_read(bus, addr, reg, &orig_data); + if (res) + break; + debug("is %04x. (value %04x mask %04x) ", orig_data, data, + mask); + data = (orig_data & ~mask) | (data & mask); + case MIICMD_SET: + debug("=> %04x\n", data); + res = miiphy_write(bus, addr, reg, data); + break; + case MIICMD_VERIFY_VALUE: + res = miiphy_read(bus, addr, reg, &orig_data); + if (res) + break; + if ((orig_data & mask) != (data & mask)) + res = -1; + debug("(value %04x mask %04x) == %04x? %s\n", data, mask, + orig_data, res ? "FAIL" : "PASS"); + break; + case MIICMD_WAIT_FOR_VALUE: + res = -1; + start = get_timer(0); + while ((res != 0) && (get_timer(start) < timeout)) { + res = miiphy_read(bus, addr, reg, &orig_data); + if (res) + continue; + if ((orig_data & mask) != (data & mask)) + res = -1; + } + debug("(value %04x mask %04x) == %04x? %s after %lu ms\n", data, + mask, orig_data, res ? "FAIL" : "PASS", + get_timer(start)); + break; + default: + res = -1; + break; + } + + return res; +} + +static int process_setup(const char *bus, unsigned char addr, + struct mii_setupcmd *setupcmd, unsigned int count) +{ + int res = 0; + unsigned int k; + + for (k = 0; k < count; ++k) { + res = process_setupcmd(bus, addr, &setupcmd[k]); + if (res) { + printf("mii cmd %u on bus %s addr %u failed, aborting setup", + setupcmd[k].token, bus, addr); + break; + } + } + + return res; +} + +static int setup_88e1518(const char *bus, unsigned char addr) +{ + int res; + + res = process_setup(bus, addr, + verify_88e1518, ARRAY_SIZE(verify_88e1518)); + if (res) + return res; + + res = process_setup(bus, addr, + fixup_88e1518, ARRAY_SIZE(fixup_88e1518)); + if (res) + return res; + + res = process_setup(bus, addr, + default_88e1518, ARRAY_SIZE(default_88e1518)); + if (res) + return res; + + if (addr) { + res = process_setup(bus, addr, + ch1fix_88e1518, ARRAY_SIZE(ch1fix_88e1518)); + if (res) + return res; + } + + res = process_setup(bus, addr, + swreset_88e1518, ARRAY_SIZE(swreset_88e1518)); + if (res) + return res; + + return 0; } diff --git a/board/gdsys/405ep/neo.c b/board/gdsys/405ep/neo.c index bca7803..ff0edb2 100644 --- a/board/gdsys/405ep/neo.c +++ b/board/gdsys/405ep/neo.c @@ -28,6 +28,8 @@ enum { HWVER_300 = 3, }; +struct ihs_fpga *fpga_ptr[] = CONFIG_SYS_FPGA_PTR; + int misc_init_r(void) { /* startup fans */ @@ -54,10 +56,9 @@ int checkboard(void) static void print_fpga_info(void) { - struct ihs_fpga *fpga = (struct ihs_fpga *) CONFIG_SYS_FPGA_BASE(0); - u16 versions = in_le16(&fpga->versions); - u16 fpga_version = in_le16(&fpga->fpga_version); - u16 fpga_features = in_le16(&fpga->fpga_features); + u16 versions; + u16 fpga_version; + u16 fpga_features; int fpga_state = get_fpga_state(0); unsigned unit_type; unsigned hardware_version; @@ -74,6 +75,10 @@ static void print_fpga_info(void) return; } + FPGA_GET_REG(0, versions, &versions); + FPGA_GET_REG(0, fpga_version, &fpga_version); + FPGA_GET_REG(0, fpga_features, &fpga_features); + unit_type = (versions & 0xf000) >> 12; hardware_version = versions & 0x000f; feature_channels = fpga_features & 0x007f; diff --git a/board/gdsys/405ex/405ex.c b/board/gdsys/405ex/405ex.c index 32e24c0..c1a583f 100644 --- a/board/gdsys/405ex/405ex.c +++ b/board/gdsys/405ex/405ex.c @@ -11,6 +11,12 @@ #define REFLECTION_TESTPATTERN 0xdede #define REFLECTION_TESTPATTERN_INV (~REFLECTION_TESTPATTERN & 0xffff) +#ifdef CONFIG_SYS_FPGA_NO_RFL_HI +#define REFLECTION_TESTREG reflection_low +#else +#define REFLECTION_TESTREG reflection_high +#endif + DECLARE_GLOBAL_DATA_PTR; int get_fpga_state(unsigned dev) @@ -220,23 +226,17 @@ int board_early_init_r(void) gd405ex_set_fpga_reset(0); for (k = 0; k < CONFIG_SYS_FPGA_COUNT; ++k) { - struct ihs_fpga *fpga = - (struct ihs_fpga *)CONFIG_SYS_FPGA_BASE(k); -#ifdef CONFIG_SYS_FPGA_NO_RFL_HI - u16 *reflection_target = &fpga->reflection_low; -#else - u16 *reflection_target = &fpga->reflection_high; -#endif /* * wait for fpga out of reset */ ctr = 0; while (1) { - out_le16(&fpga->reflection_low, - REFLECTION_TESTPATTERN); + u16 val; + + FPGA_SET_REG(k, reflection_low, REFLECTION_TESTPATTERN); - if (in_le16(reflection_target) == - REFLECTION_TESTPATTERN_INV) + FPGA_GET_REG(k, REFLECTION_TESTREG, &val); + if (val == REFLECTION_TESTPATTERN_INV) break; udelay(100000); diff --git a/board/gdsys/405ex/io64.c b/board/gdsys/405ex/io64.c index fa8961a..2f8e306 100644 --- a/board/gdsys/405ex/io64.c +++ b/board/gdsys/405ex/io64.c @@ -51,6 +51,8 @@ enum { HWVER_110 = 1, }; +struct ihs_fpga *fpga_ptr[] = CONFIG_SYS_FPGA_PTR; + static inline void blank_string(int size) { int i; @@ -84,10 +86,9 @@ int misc_init_r(void) static void print_fpga_info(unsigned dev) { - struct ihs_fpga *fpga = (struct ihs_fpga *) CONFIG_SYS_FPGA_BASE(dev); - u16 versions = in_le16(&fpga->versions); - u16 fpga_version = in_le16(&fpga->fpga_version); - u16 fpga_features = in_le16(&fpga->fpga_features); + u16 versions; + u16 fpga_version; + u16 fpga_features; int fpga_state = get_fpga_state(dev); unsigned unit_type; @@ -95,6 +96,10 @@ static void print_fpga_info(unsigned dev) unsigned feature_channels; unsigned feature_expansion; + FPGA_GET_REG(dev, versions, &versions); + FPGA_GET_REG(dev, fpga_version, &fpga_version); + FPGA_GET_REG(dev, fpga_features, &fpga_features); + printf("FPGA%d: ", dev); if (fpga_state & FPGA_STATE_PLATFORM) printf("(legacy) "); @@ -226,8 +231,6 @@ int last_stage_init(void) { unsigned int k; unsigned int fpga; - struct ihs_fpga *fpga0 = (struct ihs_fpga *) CONFIG_SYS_FPGA_BASE(0); - struct ihs_fpga *fpga1 = (struct ihs_fpga *) CONFIG_SYS_FPGA_BASE(1); int failed = 0; char str_phys[] = "Setup PHYs -"; char str_serdes[] = "Start SERDES blocks"; @@ -265,17 +268,16 @@ int last_stage_init(void) /* take fpga serdes blocks out of reset */ puts(str_serdes); udelay(500000); - out_le16(&fpga0->quad_serdes_reset, 0); - out_le16(&fpga1->quad_serdes_reset, 0); + FPGA_SET_REG(0, quad_serdes_reset, 0); + FPGA_SET_REG(1, quad_serdes_reset, 0); blank_string(strlen(str_serdes)); /* take channels out of reset */ puts(str_channels); udelay(500000); for (fpga = 0; fpga < 2; ++fpga) { - u16 *ch0_config_int = &(fpga ? fpga1 : fpga0)->ch0_config_int; for (k = 0; k < 32; ++k) - out_le16(ch0_config_int + 4 * k, 0); + FPGA_SET_REG(fpga, ch[k].config_int, 0); } blank_string(strlen(str_channels)); @@ -283,16 +285,16 @@ int last_stage_init(void) puts(str_locks); udelay(500000); for (fpga = 0; fpga < 2; ++fpga) { - u16 *ch0_status_int = &(fpga ? fpga1 : fpga0)->ch0_status_int; for (k = 0; k < 32; ++k) { - u16 status = in_le16(ch0_status_int + 4*k); + u16 status; + FPGA_GET_REG(k, ch[k].status_int, &status); if (!(status & (1 << 4))) { failed = 1; printf("fpga %d channel %d: no serdes lock\n", fpga, k); } /* reset events */ - out_le16(ch0_status_int + 4*k, status); + FPGA_SET_REG(fpga, ch[k].status_int, 0); } } blank_string(strlen(str_locks)); @@ -300,14 +302,14 @@ int last_stage_init(void) /* verify hicb_status */ puts(str_hicb); for (fpga = 0; fpga < 2; ++fpga) { - u16 *ch0_hicb_status_int = &(fpga ? fpga1 : fpga0)->ch0_hicb_status_int; for (k = 0; k < 32; ++k) { - u16 status = in_le16(ch0_hicb_status_int + 4*k); + u16 status; + FPGA_GET_REG(k, hicb_ch[k].status_int, &status); if (status) printf("fpga %d hicb %d: hicb status %04x\n", fpga, k, status); /* reset events */ - out_le16(ch0_hicb_status_int + 4*k, status); + FPGA_SET_REG(fpga, hicb_ch[k].status_int, 0); } } blank_string(strlen(str_hicb)); diff --git a/board/gdsys/common/Makefile b/board/gdsys/common/Makefile index 43e6a4c..216ad96 100644 --- a/board/gdsys/common/Makefile +++ b/board/gdsys/common/Makefile @@ -13,9 +13,11 @@ endif LIB = $(obj)lib$(VENDOR).o +COBJS-$(CONFIG_SYS_FPGA_COMMON) += fpga.o + COBJS-$(CONFIG_IO) += miiphybb.o COBJS-$(CONFIG_IO64) += miiphybb.o -COBJS-$(CONFIG_IOCON) += osd.o +COBJS-$(CONFIG_IOCON) += osd.o mclink.o COBJS-$(CONFIG_DLVISION_10G) += osd.o COBJS-$(CONFIG_CONTROLCENTERD) += dp501.o diff --git a/board/gdsys/common/dp501.c b/board/gdsys/common/dp501.c index 9aa4e3f..52f3ea1 100644 --- a/board/gdsys/common/dp501.c +++ b/board/gdsys/common/dp501.c @@ -2,23 +2,7 @@ * (C) Copyright 2012 * Dirk Eibach, Guntermann & Drunck GmbH, dirk.eibach@gdsys.cc * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA + * SPDX-License-Identifier: GPL-2.0+ */ /* Parade Technologies Inc. DP501 DisplayPort DVI/HDMI Transmitter */ diff --git a/board/gdsys/common/fpga.c b/board/gdsys/common/fpga.c new file mode 100644 index 0000000..e10c105 --- /dev/null +++ b/board/gdsys/common/fpga.c @@ -0,0 +1,25 @@ +/* + * (C) Copyright 2013 + * Dirk Eibach, Guntermann & Drunck GmbH, eibach@gdsys.de + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <gdsys_fpga.h> + +#include <asm/io.h> + +int fpga_set_reg(u32 fpga, u16 *reg, off_t regoff, u16 data) +{ + out_le16(reg, data); + + return 0; +} + +int fpga_get_reg(u32 fpga, u16 *reg, off_t regoff, u16 *data) +{ + *data = in_le16(reg); + + return 0; +} diff --git a/board/gdsys/common/mclink.c b/board/gdsys/common/mclink.c new file mode 100644 index 0000000..9f230c9 --- /dev/null +++ b/board/gdsys/common/mclink.c @@ -0,0 +1,137 @@ +/* + * (C) Copyright 2012 + * Dirk Eibach, Guntermann & Drunck GmbH, dirk.eibach@gdsys.cc + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/io.h> +#include <errno.h> + +#include <gdsys_fpga.h> + +enum { + MCINT_SLAVE_LINK_CHANGED_EV = 1 << 7, + MCINT_TX_ERROR_EV = 1 << 9, + MCINT_TX_BUFFER_FREE = 1 << 10, + MCINT_TX_PACKET_TRANSMITTED_EV = 1 << 11, + MCINT_RX_ERROR_EV = 1 << 13, + MCINT_RX_CONTENT_AVAILABLE = 1 << 14, + MCINT_RX_PACKET_RECEIVED_EV = 1 << 15, +}; + +int mclink_probe(void) +{ + unsigned int k; + int slaves = 0; + + for (k = 0; k < CONFIG_SYS_MCLINK_MAX; ++k) { + int timeout = 0; + unsigned int ctr = 0; + u16 mc_status; + + FPGA_GET_REG(k, mc_status, &mc_status); + + if (!(mc_status & (1 << 15))) + break; + + FPGA_SET_REG(k, mc_control, 0x8000); + + FPGA_GET_REG(k, mc_status, &mc_status); + while (!(mc_status & (1 << 14))) { + udelay(100); + if (ctr++ > 500) { + timeout = 1; + break; + } + FPGA_GET_REG(k, mc_status, &mc_status); + } + if (timeout) + break; + + printf("waited %d us for mclink %d to come up\n", ctr * 100, k); + + slaves++; + } + + return slaves; +} + +int mclink_send(u8 slave, u16 addr, u16 data) +{ + unsigned int ctr = 0; + u16 int_status; + u16 rx_cmd_status; + u16 rx_cmd; + + /* reset interrupt status */ + FPGA_GET_REG(0, mc_int, &int_status); + FPGA_SET_REG(0, mc_int, int_status); + + /* send */ + FPGA_SET_REG(0, mc_tx_address, addr); + FPGA_SET_REG(0, mc_tx_data, data); + FPGA_SET_REG(0, mc_tx_cmd, (slave & 0x03) << 14); + FPGA_SET_REG(0, mc_control, 0x8001); + + /* wait for reply */ + FPGA_GET_REG(0, mc_int, &int_status); + while (!(int_status & MCINT_RX_PACKET_RECEIVED_EV)) { + udelay(100); + if (ctr++ > 3) + return -ETIMEDOUT; + FPGA_GET_REG(0, mc_int, &int_status); + } + + FPGA_GET_REG(0, mc_rx_cmd_status, &rx_cmd_status); + rx_cmd = (rx_cmd_status >> 12) & 0x03; + if (rx_cmd != 0) + printf("mclink_send: received cmd %d, expected %d\n", rx_cmd, + 0); + + return 0; +} + +int mclink_receive(u8 slave, u16 addr, u16 *data) +{ + u16 rx_cmd_status; + u16 rx_cmd; + u16 int_status; + unsigned int ctr = 0; + + /* send read request */ + FPGA_SET_REG(0, mc_tx_address, addr); + FPGA_SET_REG(0, mc_tx_cmd, + ((slave & 0x03) << 14) | (1 << 12) | (1 << 0)); + FPGA_SET_REG(0, mc_control, 0x8001); + + + /* wait for reply */ + FPGA_GET_REG(0, mc_int, &int_status); + while (!(int_status & MCINT_RX_CONTENT_AVAILABLE)) { + udelay(100); + if (ctr++ > 3) + return -ETIMEDOUT; + FPGA_GET_REG(0, mc_int, &int_status); + } + + /* check reply */ + FPGA_GET_REG(0, mc_rx_cmd_status, &rx_cmd_status); + if ((rx_cmd_status >> 14) != slave) { + printf("mclink_receive: reply from slave %d, expected %d\n", + rx_cmd_status >> 14, slave); + return -EINVAL; + } + + rx_cmd = (rx_cmd_status >> 12) & 0x03; + if (rx_cmd != 1) { + printf("mclink_send: received cmd %d, expected %d\n", + rx_cmd, 1); + return -EIO; + } + + FPGA_GET_REG(0, mc_rx_data, data); + + return 0; +} diff --git a/board/gdsys/common/mclink.h b/board/gdsys/common/mclink.h new file mode 100644 index 0000000..febd46a --- /dev/null +++ b/board/gdsys/common/mclink.h @@ -0,0 +1,15 @@ +/* + * (C) Copyright 2012 + * Dirk Eibach, Guntermann & Drunck GmbH, dirk.eibach@gdsys.cc + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _MCLINK_H_ +#define _MCLINK_H_ + +int mclink_probe(void); +int mclink_send(u8 slave, u16 addr, u16 data); +int mclink_receive(u8 slave, u16 addr, u16 *data); + +#endif diff --git a/board/gdsys/common/osd.c b/board/gdsys/common/osd.c index 45cea5e..c49cd9a 100644 --- a/board/gdsys/common/osd.c +++ b/board/gdsys/common/osd.c @@ -7,7 +7,7 @@ #include <common.h> #include <i2c.h> -#include <asm/io.h> +#include <malloc.h> #include <gdsys_fpga.h> @@ -26,10 +26,6 @@ #define PIXCLK_640_480_60 25180000 -#define BASE_WIDTH 32 -#define BASE_HEIGHT 16 -#define BUFSIZE (BASE_WIDTH * BASE_HEIGHT) - enum { CH7301_CM = 0x1c, /* Clock Mode Register */ CH7301_IC = 0x1d, /* Input Clock Register */ @@ -51,37 +47,55 @@ enum { CH7301_DSP = 0x56, /* DVI Sync polarity Register */ }; +unsigned int base_width; +unsigned int base_height; +size_t bufsize; +u16 *buf; + +unsigned int max_osd_screen = CONFIG_SYS_OSD_SCREENS - 1; + +#ifdef CONFIG_SYS_CH7301 +int ch7301_i2c[] = CONFIG_SYS_CH7301_I2C; +#endif + #if defined(CONFIG_SYS_ICS8N3QV01) || defined(CONFIG_SYS_SIL1178) static void fpga_iic_write(unsigned screen, u8 slave, u8 reg, u8 data) { - struct ihs_fpga *fpga = (struct ihs_fpga *)CONFIG_SYS_FPGA_BASE(screen); - struct ihs_i2c *i2c = &fpga->i2c; + u16 val; - while (in_le16(&fpga->extended_interrupt) & (1 << 12)) - ; - out_le16(&i2c->write_mailbox_ext, reg | (data << 8)); - out_le16(&i2c->write_mailbox, 0xc400 | (slave << 1)); + do { + FPGA_GET_REG(screen, extended_interrupt, &val); + } while (val & (1 << 12)); + + FPGA_SET_REG(screen, i2c.write_mailbox_ext, reg | (data << 8)); + FPGA_SET_REG(screen, i2c.write_mailbox, 0xc400 | (slave << 1)); } static u8 fpga_iic_read(unsigned screen, u8 slave, u8 reg) { - struct ihs_fpga *fpga = (struct ihs_fpga *)CONFIG_SYS_FPGA_BASE(screen); - struct ihs_i2c *i2c = &fpga->i2c; unsigned int ctr = 0; + u16 val; + + do { + FPGA_GET_REG(screen, extended_interrupt, &val); + } while (val & (1 << 12)); - while (in_le16(&fpga->extended_interrupt) & (1 << 12)) - ; - out_le16(&fpga->extended_interrupt, 1 << 14); - out_le16(&i2c->write_mailbox_ext, reg); - out_le16(&i2c->write_mailbox, 0xc000 | (slave << 1)); - while (!(in_le16(&fpga->extended_interrupt) & (1 << 14))) { + FPGA_SET_REG(screen, extended_interrupt, 1 << 14); + FPGA_SET_REG(screen, i2c.write_mailbox_ext, reg); + FPGA_SET_REG(screen, i2c.write_mailbox, 0xc000 | (slave << 1)); + + FPGA_GET_REG(screen, extended_interrupt, &val); + while (!(val & (1 << 14))) { udelay(100000); if (ctr++ > 5) { printf("iic receive timeout\n"); break; } + FPGA_GET_REG(screen, extended_interrupt, &val); } - return in_le16(&i2c->read_mailbox_ext) >> 8; + + FPGA_GET_REG(screen, i2c.read_mailbox_ext, &val); + return val >> 8; } #endif @@ -113,7 +127,6 @@ static void mpc92469ac_calc_parameters(unsigned int fout, static void mpc92469ac_set(unsigned screen, unsigned int fout) { - struct ihs_fpga *fpga = (struct ihs_fpga *)CONFIG_SYS_FPGA_BASE(screen); unsigned int n; unsigned int m; unsigned int bitval = 0; @@ -134,7 +147,7 @@ static void mpc92469ac_set(unsigned screen, unsigned int fout) break; } - out_le16(&fpga->mpc3w_control, (bitval << 9) | m); + FPGA_SET_REG(screen, mpc3w_control, (bitval << 9) | m); } #endif @@ -249,14 +262,12 @@ static void ics8n3qv01_set(unsigned screen, unsigned int fout) static int osd_write_videomem(unsigned screen, unsigned offset, u16 *data, size_t charcount) { - struct ihs_fpga *fpga = - (struct ihs_fpga *) CONFIG_SYS_FPGA_BASE(screen); unsigned int k; for (k = 0; k < charcount; ++k) { - if (offset + k >= BUFSIZE) + if (offset + k >= bufsize) return -1; - out_le16(&fpga->videomem + offset + k, data[k]); + FPGA_SET_REG(screen, videomem[offset + k], data[k]); } return charcount; @@ -266,14 +277,13 @@ static int osd_print(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { unsigned screen; - for (screen = 0; screen < CONFIG_SYS_OSD_SCREENS; ++screen) { + for (screen = 0; screen <= max_osd_screen; ++screen) { unsigned x; unsigned y; unsigned charcount; unsigned len; u8 color; unsigned int k; - u16 buf[BUFSIZE]; char *text; int res; @@ -287,12 +297,12 @@ static int osd_print(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) color = simple_strtoul(argv[3], NULL, 16); text = argv[4]; charcount = strlen(text); - len = (charcount > BUFSIZE) ? BUFSIZE : charcount; + len = (charcount > bufsize) ? bufsize : charcount; for (k = 0; k < len; ++k) buf[k] = (text[k] << 8) | color; - res = osd_write_videomem(screen, y * BASE_WIDTH + x, buf, len); + res = osd_write_videomem(screen, y * base_width + x, buf, len); if (res < 0) return res; } @@ -302,24 +312,32 @@ static int osd_print(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) int osd_probe(unsigned screen) { - struct ihs_fpga *fpga = (struct ihs_fpga *)CONFIG_SYS_FPGA_BASE(screen); - struct ihs_osd *osd = &fpga->osd; - u16 version = in_le16(&osd->version); - u16 features = in_le16(&osd->features); - unsigned width; - unsigned height; + u16 version; + u16 features; u8 value; +#ifdef CONFIG_SYS_CH7301 + int old_bus = i2c_get_bus_num(); +#endif - width = ((features & 0x3f00) >> 8) + 1; - height = (features & 0x001f) + 1; + FPGA_GET_REG(0, osd.version, &version); + FPGA_GET_REG(0, osd.features, &features); + + base_width = ((features & 0x3f00) >> 8) + 1; + base_height = (features & 0x001f) + 1; + bufsize = base_width * base_height; + buf = malloc(sizeof(u16) * bufsize); + if (!buf) + return -1; printf("OSD%d: Digital-OSD version %01d.%02d, %d" "x%d characters\n", - screen, version/100, version%100, width, height); + screen, version/100, version%100, base_width, base_height); #ifdef CONFIG_SYS_CH7301 + i2c_set_bus_num(ch7301_i2c[screen]); value = i2c_reg_read(CH7301_I2C_ADDR, CH7301_DID); if (value != 0x17) { printf(" Probing CH7301 failed, DID %02x\n", value); + i2c_set_bus_num(old_bus); return -1; } i2c_reg_write(CH7301_I2C_ADDR, CH7301_TPCP, 0x08); @@ -327,6 +345,7 @@ int osd_probe(unsigned screen) 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); + i2c_set_bus_num(old_bus); #endif #ifdef CONFIG_SYS_MPC92469AC @@ -356,12 +375,15 @@ int osd_probe(unsigned screen) fpga_iic_write(screen, SIL1178_MASTER_I2C_ADDRESS, 0x08, 0x37); #endif - out_le16(&fpga->videocontrol, 0x0002); - out_le16(&osd->control, 0x0049); + FPGA_SET_REG(screen, videocontrol, 0x0002); + 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); - out_le16(&osd->xy_size, ((32 - 1) << 8) | (16 - 1)); - out_le16(&osd->x_pos, 0x007f); - out_le16(&osd->y_pos, 0x005f); + if (screen > max_osd_screen) + max_osd_screen = screen; return 0; } @@ -370,11 +392,11 @@ int osd_write(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { unsigned screen; - for (screen = 0; screen < CONFIG_SYS_OSD_SCREENS; ++screen) { + for (screen = 0; screen <= max_osd_screen; ++screen) { unsigned x; unsigned y; unsigned k; - u16 buffer[BASE_WIDTH]; + u16 buffer[base_width]; char *rp; u16 *wp = buffer; unsigned count = (argc > 4) ? @@ -399,13 +421,13 @@ int osd_write(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) rp += 4; wp++; - if (wp - buffer > BASE_WIDTH) + if (wp - buffer > base_width) break; } for (k = 0; k < count; ++k) { unsigned offset = - y * BASE_WIDTH + x + k * (wp - buffer); + y * base_width + x + k * (wp - buffer); osd_write_videomem(screen, offset, buffer, wp - buffer); } |