From: Dirk Eibach <eib...@gdsys.de>

Signed-off-by: Dirk Eibach <dirk.eib...@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
-- 
1.7.2.5

_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot

Reply via email to