
From: Dirk Eibach eibach@gdsys.de
Signed-off-by: Dirk Eibach dirk.eibach@gdsys.cc
--- Changes in v2: - fpga_state has been moved to arch_global_data - include cmd_fpgad in iocon - use multibus soft-i2c in iocon
board/gdsys/405ep/iocon.c | 253 ++++++++++++++++++++++++++++++++++++++------- board/gdsys/common/osd.c | 25 +++-- include/configs/iocon.h | 44 ++++++-- include/gdsys_fpga.h | 15 +++- 4 files changed, 280 insertions(+), 57 deletions(-)
diff --git a/board/gdsys/405ep/iocon.c b/board/gdsys/405ep/iocon.c index 0fc7db2..0ab8772 100644 --- a/board/gdsys/405ep/iocon.c +++ b/board/gdsys/405ep/iocon.c @@ -23,6 +23,7 @@
#include <common.h> #include <command.h> +#include <errno.h> #include <asm/processor.h> #include <asm/io.h> #include <asm/ppc4xx-gpio.h> @@ -31,6 +32,13 @@ #include <gdsys_fpga.h>
#include "../common/osd.h" +#include "../common/mclink.h" + +#include <i2c.h> +#include <pca953x.h> +#include <pca9698.h> + +DECLARE_GLOBAL_DATA_PTR;
#define LATCH0_BASE (CONFIG_SYS_LATCH_BASE) #define LATCH1_BASE (CONFIG_SYS_LATCH_BASE + 0x100) @@ -47,11 +55,20 @@ enum { HWVER_100 = 0, HWVER_104 = 1, HWVER_110 = 2, + HWVER_120 = 3, + HWVER_200 = 4, + HWVER_210 = 5, +}; + +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 { @@ -67,8 +84,56 @@ enum {
enum { RAM_DDR2_32 = 0, + RAM_DDR3_32 = 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, };
+unsigned int mclink_fpgacount; + +void fpga_set_reg(unsigned int fpga, u16 reg, u16 data) +{ + int res; + struct ihs_fpga *fpga_0 = (struct ihs_fpga *)CONFIG_SYS_FPGA_BASE(0); + + switch (fpga) { + case 0: + out_le16((u16 *)fpga_0 + reg / sizeof(u16), data); + break; + default: + res = mclink_send(fpga - 1, reg, data); + if (res < 0) + printf("mclink_send reg %02x data %04x returned %d\n", + reg, data, res); + break; + } +} + +u16 fpga_get_reg(unsigned int fpga, u16 reg) +{ + int res; + u16 data; + struct ihs_fpga *fpga_0 = (struct ihs_fpga *)CONFIG_SYS_FPGA_BASE(0); + + switch (fpga) { + case 0: + return in_le16((u16 *)fpga_0 + reg / sizeof(u16)); + default: + if (fpga > mclink_fpgacount) + return -EINVAL; + res = mclink_receive(fpga - 1, reg, &data); + if (res < 0) + printf("mclink_receive returned %d\n", res); + return data; + } +} + /* * Check Board Identity: */ @@ -90,12 +155,11 @@ int checkboard(void) return 0; }
-static void print_fpga_info(void) +static void print_fpga_info(unsigned int fpga) { - 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 = fpga_get_reg(fpga, REG(versions)); + u16 fpga_version = fpga_get_reg(fpga, REG(fpga_version)); + u16 fpga_features = fpga_get_reg(fpga, REG(fpga_features)); unsigned unit_type; unsigned hardware_version; unsigned feature_compression; @@ -105,9 +169,9 @@ static void print_fpga_info(void) unsigned feature_ramconfig; unsigned feature_carriers; unsigned feature_video_channels; + int legacy = get_fpga_state(0) & FPGA_STATE_PLATFORM;
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; @@ -116,6 +180,9 @@ static void print_fpga_info(void) 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"); @@ -130,27 +197,68 @@ 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; + + default: + printf(" HW-Ver %d(not supported),", + hardware_version); + break; + } + }
- 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) { @@ -162,6 +270,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; @@ -208,6 +320,10 @@ 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; @@ -220,41 +336,94 @@ static void print_fpga_info(void)
int last_stage_init(void) { - print_fpga_info(); + int slaves; + unsigned int k; + unsigned char mclink_controllers[] = { 0x24, 0x25, 0x26 }; + + print_fpga_info(0); + 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; + } + } + } + + /* 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) { + print_fpga_info(k); + osd_probe(k); + }
- return osd_probe(0); + return 0; }
/* * provide access to fpga gpios (for I2C bitbang) */ -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, REG(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, REG(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; + return fpga_get_reg(bus, REG(gpio.read)) & 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); } }
@@ -269,5 +438,11 @@ 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); } diff --git a/board/gdsys/common/osd.c b/board/gdsys/common/osd.c index 81c8136..2cfbe58 100644 --- a/board/gdsys/common/osd.c +++ b/board/gdsys/common/osd.c @@ -22,7 +22,8 @@ */
#include <common.h> -#include "bb_i2c.h" +#include <i2c.h> +#include <malloc.h> #include <asm/io.h>
#include <gdsys_fpga.h> @@ -69,6 +70,10 @@ enum {
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) { @@ -318,6 +323,9 @@ int osd_probe(unsigned screen) unsigned width; unsigned height; u8 value; +#ifdef CONFIG_SYS_CH7301 + int old_bus = i2c_get_bus_num(); +#endif
width = ((features & 0x3f00) >> 8) + 1; height = (features & 0x001f) + 1; @@ -326,16 +334,19 @@ int osd_probe(unsigned screen) screen, version/100, version%100, width, height);
#ifdef CONFIG_SYS_CH7301 - value = bb_i2c_reg_read(screen, CH7301_I2C_ADDR, CH7301_DID); + 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; } - bb_i2c_reg_write(screen, CH7301_I2C_ADDR, CH7301_TPCP, 0x08); - bb_i2c_reg_write(screen, CH7301_I2C_ADDR, CH7301_TPD, 0x16); - bb_i2c_reg_write(screen, CH7301_I2C_ADDR, CH7301_TPF, 0x60); - bb_i2c_reg_write(screen, CH7301_I2C_ADDR, CH7301_DC, 0x09); - bb_i2c_reg_write(screen, CH7301_I2C_ADDR, CH7301_PM, 0xc0); + 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); + i2c_set_bus_num(old_bus); #endif
#ifdef CONFIG_SYS_MPC92469AC diff --git a/include/configs/iocon.h b/include/configs/iocon.h index 5972711..921ac05 100644 --- a/include/configs/iocon.h +++ b/include/configs/iocon.h @@ -79,6 +79,7 @@ * Commands additional to the ones defined in amcc-common.h */ #define CONFIG_CMD_CACHE +#define CONFIG_CMD_FPGAD #undef CONFIG_CMD_EEPROM
/* @@ -116,23 +117,46 @@ #define CONFIG_SYS_I2C_PPC4XX_SPEED_0 400000 #define CONFIG_SYS_I2C_PPC4XX_SLAVE_0 0x7F
+#define CONFIG_SYS_I2C_SPEED 400000 + +#define CONFIG_PCA953X /* NXP PCA9554 */ +#define CONFIG_PCA9698 /* NXP PCA9698 */ + /* * Software (bit-bang) I2C driver configuration */ +#define CONFIG_SYS_I2C_SOFT +#define CONFIG_SYS_I2C_SOFT_SPEED 50000 +#define CONFIG_SYS_I2C_SOFT_SLAVE 0x7F +#define I2C_SOFT_DECLARATIONS2 +#define CONFIG_SYS_I2C_SOFT_SPEED_2 50000 +#define CONFIG_SYS_I2C_SOFT_SLAVE_2 0x7F +#define I2C_SOFT_DECLARATIONS3 +#define CONFIG_SYS_I2C_SOFT_SPEED_3 50000 +#define CONFIG_SYS_I2C_SOFT_SLAVE_3 0x7F +#define I2C_SOFT_DECLARATIONS4 +#define CONFIG_SYS_I2C_SOFT_SPEED_4 50000 +#define CONFIG_SYS_I2C_SOFT_SLAVE_4 0x7F + +#define CONFIG_SYS_CH7301_I2C {1, 2, 3, 4}
#ifndef __ASSEMBLY__ -void fpga_gpio_set(int pin); -void fpga_gpio_clear(int pin); -int fpga_gpio_get(int pin); +void fpga_gpio_set(unsigned int bus, int pin); +void fpga_gpio_clear(unsigned int bus, int pin); +int fpga_gpio_get(unsigned int bus, int pin); #endif
#define I2C_ACTIVE { } #define I2C_TRISTATE { } -#define I2C_READ fpga_gpio_get(0x0040) ? 1 : 0 -#define I2C_SDA(bit) if (bit) fpga_gpio_set(0x0040); \ - else fpga_gpio_clear(0x0040) -#define I2C_SCL(bit) if (bit) fpga_gpio_set(0x0020); \ - else fpga_gpio_clear(0x0020) +#define I2C_READ fpga_gpio_get(I2C_ADAP_HWNR, 0x0040) ? 1 : 0 +#define I2C_SDA(bit) if (bit) \ + fpga_gpio_set(I2C_ADAP_HWNR, 0x0040); \ + else \ + fpga_gpio_clear(I2C_ADAP_HWNR, 0x0040) +#define I2C_SCL(bit) if (bit) \ + fpga_gpio_set(I2C_ADAP_HWNR, 0x0020); \ + else \ + fpga_gpio_clear(I2C_ADAP_HWNR, 0x0020) #define I2C_DELAY udelay(25) /* 1/4 I2C clock duration */
/* @@ -252,6 +276,8 @@ int fpga_gpio_get(int pin);
#define CONFIG_SYS_FPGA_COUNT 1
+#define CONFIG_SYS_MCLINK_MAX 3 + /* Memory Bank 3 (Latches) initialization */ #define CONFIG_SYS_LATCH_BASE 0x7f200000 #define CONFIG_SYS_EBC_PB3AP 0x02025080 @@ -267,6 +293,6 @@ int fpga_gpio_get(int pin); */ #define CONFIG_SYS_MPC92469AC #define CONFIG_SYS_CH7301 -#define CONFIG_SYS_OSD_SCREENS CONFIG_SYS_FPGA_COUNT +#define CONFIG_SYS_OSD_SCREENS 1
#endif /* __CONFIG_H */ diff --git a/include/gdsys_fpga.h b/include/gdsys_fpga.h index c12a31d..b246f2f 100644 --- a/include/gdsys_fpga.h +++ b/include/gdsys_fpga.h @@ -117,10 +117,21 @@ struct ihs_fpga { u16 mpc3w_control; /* 0x001a */ u16 reserved_1[19]; /* 0x001c */ u16 videocontrol; /* 0x0042 */ - u16 reserved_2[93]; /* 0x0044 */ + u16 reserved_2[14]; /* 0x0044 */ + u16 mc_int; /* 0x0060 */ + u16 mc_int_en; /* 0x0062 */ + u16 mc_status; /* 0x0064 */ + u16 mc_control; /* 0x0066 */ + u16 mc_tx_data; /* 0x0068 */ + u16 mc_tx_address; /* 0x006a */ + u16 mc_tx_cmd; /* 0x006c */ + u16 mc_res; /* 0x006e */ + u16 mc_rx_cmd_status; /* 0x0070 */ + u16 mc_rx_data; /* 0x0072 */ + u16 reserved_3[69]; /* 0x0074 */ u16 reflection_high; /* 0x00fe */ struct ihs_osd osd; /* 0x0100 */ - u16 reserved_3[889]; /* 0x010e */ + u16 reserved_4[889]; /* 0x010e */ u16 videomem; /* 0x0800 */ }; #endif