]> git.sur5r.net Git - u-boot/blobdiff - board/keymile/common/common.c
km/common: implement setboardid command
[u-boot] / board / keymile / common / common.c
index 85538d061bb537cc32a1c6cbaedad9914842ed4a..9adfefaf6aac9c89cfec7e86429da150aabace33 100644 (file)
  */
 
 #include <common.h>
-#if defined(CONFIG_MGCOGE)
+#if defined(CONFIG_KM82XX)
 #include <mpc8260.h>
 #endif
 #include <ioports.h>
+#include <command.h>
 #include <malloc.h>
 #include <hush.h>
 #include <net.h>
 #if defined(CONFIG_HARD_I2C) || defined(CONFIG_SOFT_I2C)
 #include <i2c.h>
 
+static void i2c_write_start_seq(void);
+static int i2c_make_abort(void);
+DECLARE_GLOBAL_DATA_PTR;
+
 int ivm_calc_crc(unsigned char *buf, int len)
 {
        const unsigned short crc_tab[16] = {
@@ -70,6 +75,41 @@ int ivm_calc_crc(unsigned char *buf, int len)
        return crc;
 }
 
+/*
+ * Set Keymile specific environment variables
+ * Currently only some memory layout variables are calculated here
+ * ... ------------------------------------------------
+ * ... |@rootfsaddr |@pnvramaddr |@varaddr |@reserved |@END_OF_RAM
+ * ... |<------------------- pram ------------------->|
+ * ... ------------------------------------------------
+ * @END_OF_RAM: denotes the RAM size
+ * @pnvramaddr: Startadress of pseudo non volatile RAM in hex
+ * @pram      : preserved ram size in k
+ * @varaddr   : startadress for /var mounted into RAM
+ */
+int set_km_env(void)
+{
+       uchar buf[32];
+       unsigned int pnvramaddr;
+       unsigned int pram;
+       unsigned int varaddr;
+
+       pnvramaddr = gd->ram_size - CONFIG_KM_RESERVED_PRAM - CONFIG_KM_PHRAM
+                       - CONFIG_KM_PNVRAM;
+       sprintf((char *)buf, "0x%x", pnvramaddr);
+       setenv("pnvramaddr", (char *)buf);
+
+       pram = (CONFIG_KM_RESERVED_PRAM + CONFIG_KM_PHRAM + CONFIG_KM_PNVRAM) /
+               0x400;
+       sprintf((char *)buf, "0x%x", pram);
+       setenv("pram", (char *)buf);
+
+       varaddr = gd->ram_size - CONFIG_KM_RESERVED_PRAM - CONFIG_KM_PHRAM;
+       sprintf((char *)buf, "0x%x", varaddr);
+       setenv("varaddr", (char *)buf);
+       return 0;
+}
+
 static int ivm_set_value(char *name, char *value)
 {
        char tempbuf[256];
@@ -225,8 +265,21 @@ static int ivm_analyze_block2(unsigned char *buf, int len)
        /* IVM_MacAddress */
        sprintf((char *)valbuf, "%pM", buf);
        ivm_set_value("IVM_MacAddress", (char *)valbuf);
+       /* if an offset is defined, add it */
+#if defined(CONFIG_PIGGY_MAC_ADRESS_OFFSET)
+       if (CONFIG_PIGGY_MAC_ADRESS_OFFSET > 0) {
+               unsigned long val = (buf[4] << 16) + (buf[5] << 8) + buf[6];
+
+               val += CONFIG_PIGGY_MAC_ADRESS_OFFSET;
+               buf[4] = (val >> 16) & 0xff;
+               buf[5] = (val >> 8) & 0xff;
+               buf[6] = val & 0xff;
+               sprintf((char *)valbuf, "%pM", buf);
+       }
+#endif
        if (getenv("ethaddr") == NULL)
                setenv((char *)"ethaddr", (char *)valbuf);
+
        /* IVM_MacCount */
        count = (buf[10] << 24) +
                   (buf[11] << 16) +
@@ -329,8 +382,11 @@ int ivm_read_eeprom(void)
        if (buf != NULL)
                dev_addr = simple_strtoul((char *)buf, NULL, 16);
 
+       /* add deblocking here */
+       i2c_make_abort();
+
        ret = i2c_read(dev_addr, 0, 1, i2c_buffer,
-                       CONFIG_SYS_IVM_EEPROM_MAX_LEN);
+               CONFIG_SYS_IVM_EEPROM_MAX_LEN);
        if (ret != 0) {
                printf ("Error reading EEprom\n");
                return -2;
@@ -340,13 +396,13 @@ int ivm_read_eeprom(void)
 }
 
 #if defined(CONFIG_SYS_I2C_INIT_BOARD)
-#define DELAY_ABORT_SEQ                62
+#define DELAY_ABORT_SEQ                62  /* @200kHz 9 clocks = 44us, 62us is ok */
 #define DELAY_HALF_PERIOD      (500 / (CONFIG_SYS_I2C_SPEED / 1000))
 
-#if defined(CONFIG_MGCOGE)
+#if defined(CONFIG_KM_82XX)
 #define SDA_MASK       0x00010000
 #define SCL_MASK       0x00020000
-static void set_pin(int state, unsigned long mask)
+void set_pin(int state, unsigned long mask)
 {
        ioport_t *iop = ioport_addr((immap_t *)CONFIG_SYS_IMMR, 3);
 
@@ -404,7 +460,7 @@ static void setports(int gpio)
 #endif
 
 #if !defined(CONFIG_MPC83xx)
-static void writeStartSeq(void)
+static void i2c_write_start_seq(void)
 {
        set_sda(1);
        udelay(DELAY_HALF_PERIOD);
@@ -426,6 +482,21 @@ static void writeStartSeq(void)
  */
 static int i2c_make_abort(void)
 {
+
+#if defined(CONFIG_HARD_I2C) && !defined(MACH_TYPE_KM_KIRKWOOD)
+       immap_t *immap = (immap_t *)CONFIG_SYS_IMMR ;
+       i2c8260_t *i2c  = (i2c8260_t *)&immap->im_i2c;
+
+       /*
+        * disable I2C controller first, otherwhise it thinks we want to
+        * talk to the slave port...
+        */
+       clrbits_8(&i2c->i2c_i2mod, 0x01);
+
+       /* Set the PortPins to GPIO */
+       setports(1);
+#endif
+
        int     scl_state = 0;
        int     sda_state = 0;
        int     i = 0;
@@ -449,57 +520,93 @@ static int i2c_make_abort(void)
        }
        if (ret == 0)
                for (i = 0; i < 5; i++)
-                       writeStartSeq();
+                       i2c_write_start_seq();
 
+       /* respect stop setup time */
+       udelay(DELAY_ABORT_SEQ);
+       set_scl(1);
+       udelay(DELAY_ABORT_SEQ);
+       set_sda(1);
        get_sda();
+
+#if defined(CONFIG_HARD_I2C)
+       /* Set the PortPins back to use for I2C */
+       setports(0);
+#endif
        return ret;
 }
 #endif
 
-/*
- * i2c_init_board - reset i2c bus. When the board is powercycled during a
- * bus transfer it might hang; for details see doc/I2C_Edge_Conditions.
- */
-void i2c_init_board(void)
-{
 #if defined(CONFIG_MPC83xx)
+static void i2c_write_start_seq(void)
+{
+       struct fsl_i2c *dev;
+       dev = (struct fsl_i2c *) (CONFIG_SYS_IMMR + CONFIG_SYS_I2C_OFFSET);
+       udelay(DELAY_ABORT_SEQ);
+       out_8(&dev->cr, (I2C_CR_MEN | I2C_CR_MSTA));
+       udelay(DELAY_ABORT_SEQ);
+       out_8(&dev->cr, (I2C_CR_MEN));
+}
+
+static int i2c_make_abort(void)
+{
        struct fsl_i2c *dev;
        dev = (struct fsl_i2c *) (CONFIG_SYS_IMMR + CONFIG_SYS_I2C_OFFSET);
        uchar   dummy;
+       uchar   last;
+       int     nbr_read = 0;
+       int     i = 0;
+       int         ret = 0;
 
+       /* wait after each operation to finsh with a delay */
        out_8(&dev->cr, (I2C_CR_MSTA));
+       udelay(DELAY_ABORT_SEQ);
        out_8(&dev->cr, (I2C_CR_MEN | I2C_CR_MSTA));
+       udelay(DELAY_ABORT_SEQ);
        dummy = in_8(&dev->dr);
-       dummy = in_8(&dev->dr);
-       if (dummy != 0xff) {
-               dummy = in_8(&dev->dr);
-       }
-       out_8(&dev->cr, (I2C_CR_MEN));
-       out_8(&dev->cr, 0x00);
-       out_8(&dev->cr, (I2C_CR_MEN));
-#else
-#if defined(CONFIG_HARD_I2C) && !defined(MACH_TYPE_KM_KIRKWOOD)
-       immap_t *immap = (immap_t *)CONFIG_SYS_IMMR ;
-       i2c8260_t *i2c  = (i2c8260_t *)&immap->im_i2c;
+       udelay(DELAY_ABORT_SEQ);
+       last = in_8(&dev->dr);
+       nbr_read++;
 
        /*
-        * disable I2C controller first, otherwhise it thinks we want to
-        * talk to the slave port...
+        * do read until the last bit is 1, but stop if the full eeprom is
+        * read.
         */
-       clrbits_8(&i2c->i2c_i2mod, 0x01);
+       while (((last & 0x01) != 0x01) &&
+               (nbr_read < CONFIG_SYS_IVM_EEPROM_MAX_LEN)) {
+               udelay(DELAY_ABORT_SEQ);
+               last = in_8(&dev->dr);
+               nbr_read++;
+       }
+       if ((last & 0x01) != 0x01)
+               ret = -2;
+       if ((last != 0xff) || (nbr_read > 1))
+               printf("[INFO] i2c abort after %d bytes (0x%02x)\n",
+                       nbr_read, last);
+       udelay(DELAY_ABORT_SEQ);
+       out_8(&dev->cr, (I2C_CR_MEN));
+       udelay(DELAY_ABORT_SEQ);
+       /* clear status reg */
+       out_8(&dev->sr, 0);
 
-       /* Set the PortPins to GPIO */
-       setports(1);
+       for (i = 0; i < 5; i++)
+               i2c_write_start_seq();
+       if (ret != 0)
+               printf("[ERROR] i2c abort failed after %d bytes (0x%02x)\n",
+                       nbr_read, last);
+
+       return ret;
+}
 #endif
 
+/**
+ * i2c_init_board - reset i2c bus. When the board is powercycled during a
+ * bus transfer it might hang; for details see doc/I2C_Edge_Conditions.
+ */
+void i2c_init_board(void)
+{
        /* Now run the AbortSequence() */
        i2c_make_abort();
-
-#if defined(CONFIG_HARD_I2C)
-       /* Set the PortPins back to use for I2C */
-       setports(0);
-#endif
-#endif
 }
 #endif
 #endif
@@ -562,7 +669,8 @@ int fdt_get_node_and_value(void *blob,
 #if !defined(MACH_TYPE_KM_KIRKWOOD)
 int ethernet_present(void)
 {
-       struct km_bec_fpga *base = (struct km_bec_fpga *)CONFIG_SYS_PIGGY_BASE;
+       struct km_bec_fpga *base =
+               (struct km_bec_fpga *)CONFIG_SYS_KMBEC_FPGA_BASE;
 
        return in_8(&base->bprth) & PIGGY_PRESENT;
 }
@@ -570,11 +678,41 @@ int ethernet_present(void)
 
 int board_eth_init(bd_t *bis)
 {
-#ifdef CONFIG_KEYMILE_HDLC_ENET
-       (void)keymile_hdlc_enet_initialize(bis);
-#endif
        if (ethernet_present())
                return cpu_eth_init(bis);
 
        return -1;
 }
+
+/*
+ * do_setboardid command
+ * read out the board id and the hw key from the intventory EEPROM and set
+ * this values as environment variables.
+ */
+static int do_setboardid(cmd_tbl_t *cmdtp, int flag, int argc,
+                               char *const argv[])
+{
+       unsigned char buf[32];
+       char *p;
+
+       p = get_local_var("IVM_BoardId");
+       if (p == NULL) {
+               printf("can't get the IVM_Boardid\n");
+               return 1;
+       }
+       sprintf((char *)buf, "%s", p);
+       setenv("boardid", (char *)buf);
+
+       p = get_local_var("IVM_HWKey");
+       if (p == NULL) {
+               printf("can't get the IVM_HWKey\n");
+               return 1;
+       }
+       sprintf((char *)buf, "%s", p);
+       setenv("hwkey", (char *)buf);
+
+       return 0;
+}
+
+U_BOOT_CMD(km_setboardid, 1, 0, do_setboardid, "setboardid", "read out bid and "
+                                "hwkey from IVM and set in environment");