*/
#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] = {
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];
/* 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) +
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;
}
#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);
#endif
#if !defined(CONFIG_MPC83xx)
-static void writeStartSeq(void)
+static void i2c_write_start_seq(void)
{
set_sda(1);
udelay(DELAY_HALF_PERIOD);
*/
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;
}
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
#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;
}
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");