diff options
Diffstat (limited to 'board/keymile/common/common.c')
| -rw-r--r-- | board/keymile/common/common.c | 465 | 
1 files changed, 17 insertions, 448 deletions
| diff --git a/board/keymile/common/common.c b/board/keymile/common/common.c index 9be4c728b..fce9d582f 100644 --- a/board/keymile/common/common.c +++ b/board/keymile/common/common.c @@ -2,6 +2,9 @@   * (C) Copyright 2008   * Heiko Schocher, DENX Software Engineering, hs@denx.de.   * + * (C) Copyright 2011 + * Holger Brunck, Keymile GmbH Hannover, holger.brunck@keymile.com + *   * See file CREDITS for list of people who contributed to this   * project.   * @@ -22,9 +25,6 @@   */  #include <common.h> -#if defined(CONFIG_KM82XX) -#include <mpc8260.h> -#endif  #include <ioports.h>  #include <command.h>  #include <malloc.h> @@ -38,44 +38,14 @@  #include <libfdt.h>  #endif -#include "../common/common.h" +#include "common.h"  #if defined(CONFIG_HARD_I2C) || defined(CONFIG_SOFT_I2C)  #include <i2c.h> +#endif  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] = { -		0x0000, 0xCC01, 0xD801, 0x1400, -		0xF001, 0x3C00, 0x2800, 0xE401, -		0xA001, 0x6C00, 0x7800, 0xB401, -		0x5000, 0x9C01, 0x8801, 0x4400}; - -	unsigned short crc     = 0;   /* final result */ -	unsigned short r1      = 0;   /* temp */ -	unsigned char  byte    = 0;   /* input buffer */ -	int	i; - -	/* calculate CRC from array data */ -	for (i = 0; i < len; i++) { -		byte = buf[i]; - -		/* lower 4 bits */ -		r1 = crc_tab[crc & 0xF]; -		crc = ((crc) >> 4) & 0x0FFF; -		crc = crc ^ r1 ^ crc_tab[byte & 0xF]; - -		/* upper 4 bits */ -		r1 = crc_tab[crc & 0xF]; -		crc = (crc >> 4) & 0x0FFF; -		crc = crc ^ r1 ^ crc_tab[(byte >> 4) & 0xF]; -	} -	return crc; -} -  /*   * Set Keymile specific environment variables   * Currently only some memory layout variables are calculated here @@ -111,355 +81,9 @@ int set_km_env(void)  	return 0;  } -static int ivm_set_value(char *name, char *value) -{ -	char tempbuf[256]; - -	if (value != NULL) { -		sprintf(tempbuf, "%s=%s", name, value); -		return set_local_var(tempbuf, 0); -	} else { -		unset_local_var(name); -	} -	return 0; -} - -static int ivm_get_value(unsigned char *buf, int len, char *name, int off, -				int check) -{ -	unsigned short	val; -	unsigned char	valbuf[30]; - -	if ((buf[off + 0] != buf[off + 2]) && -	    (buf[off + 2] != buf[off + 4])) { -		printf("%s Error corrupted %s\n", __func__, name); -		val = -1; -	} else { -		val = buf[off + 0] + (buf[off + 1] << 8); -		if ((val == 0) && (check == 1)) -			val = -1; -	} -	sprintf((char *)valbuf, "%x", val); -	ivm_set_value(name, (char *)valbuf); -	return val; -} - -#define INV_BLOCKSIZE		0x100 -#define INV_DATAADDRESS		0x21 -#define INVENTORYDATASIZE	(INV_BLOCKSIZE - INV_DATAADDRESS - 3) - -#define IVM_POS_SHORT_TEXT		0 -#define IVM_POS_MANU_ID			1 -#define IVM_POS_MANU_SERIAL		2 -#define IVM_POS_PART_NUMBER		3 -#define IVM_POS_BUILD_STATE		4 -#define IVM_POS_SUPPLIER_PART_NUMBER	5 -#define IVM_POS_DELIVERY_DATE		6 -#define IVM_POS_SUPPLIER_BUILD_STATE	7 -#define IVM_POS_CUSTOMER_ID		8 -#define IVM_POS_CUSTOMER_PROD_ID	9 -#define IVM_POS_HISTORY			10 -#define IVM_POS_SYMBOL_ONLY		11 - -static char convert_char(char c) -{ -	return (c < ' ' || c > '~') ? '.' : c; -} - -static int ivm_findinventorystring(int type, -					unsigned char* const string, -					unsigned long maxlen, -					unsigned char *buf) -{ -	int xcode = 0; -	unsigned long cr = 0; -	unsigned long addr = INV_DATAADDRESS; -	unsigned long size = 0; -	unsigned long nr = type; -	int stop = 0; 	/* stop on semicolon */ - -	memset(string, '\0', maxlen); -	switch (type) { -		case IVM_POS_SYMBOL_ONLY: -			nr = 0; -			stop= 1; -		break; -		default: -			nr = type; -			stop = 0; -	} - -	/* Look for the requested number of CR. */ -	while ((cr != nr) && (addr < INVENTORYDATASIZE)) { -		if ((buf[addr] == '\r')) { -			cr++; -		} -		addr++; -	} - -	/* -	 * the expected number of CR was found until the end of the IVM -	 *  content --> fill string -	 */ -	if (addr < INVENTORYDATASIZE) { -		/* Copy the IVM string in the corresponding string */ -		for (; (buf[addr] != '\r')			&& -			((buf[addr] != ';') ||  (!stop))	&& -			(size < (maxlen - 1)			&& -			(addr < INVENTORYDATASIZE)); addr++) -		{ -			size += sprintf((char *)string + size, "%c", -						convert_char (buf[addr])); -		} - -		/* -		 * copy phase is done: check if everything is ok. If not, -		 * the inventory data is most probably corrupted: tell -		 * the world there is a problem! -		 */ -		if (addr == INVENTORYDATASIZE) { -			xcode = -1; -			printf("Error end of string not found\n"); -		} else if ((size >= (maxlen - 1)) && -			   (buf[addr] != '\r')) { -			xcode = -1; -			printf("string too long till next CR\n"); -		} -	} else { -		/* -		 * some CR are missing... -		 * the inventory data is most probably corrupted -		 */ -		xcode = -1; -		printf("not enough cr found\n"); -	} -	return xcode; -} - -#define GET_STRING(name, which, len) \ -	if (ivm_findinventorystring(which, valbuf, len, buf) == 0) { \ -		ivm_set_value(name, (char *)valbuf); \ -	} - -static int ivm_check_crc(unsigned char *buf, int block) -{ -	unsigned long	crc; -	unsigned long	crceeprom; - -	crc = ivm_calc_crc(buf, CONFIG_SYS_IVM_EEPROM_PAGE_LEN - 2); -	crceeprom = (buf[CONFIG_SYS_IVM_EEPROM_PAGE_LEN - 1] + \ -			buf[CONFIG_SYS_IVM_EEPROM_PAGE_LEN - 2] * 256); -	if (crc != crceeprom) { -		if (block == 0) -			printf("Error CRC Block: %d EEprom: calculated: \ -			%lx EEprom: %lx\n", block, crc, crceeprom); -		return -1; -	} -	return 0; -} - -static int ivm_analyze_block2(unsigned char *buf, int len) -{ -	unsigned char	valbuf[CONFIG_SYS_IVM_EEPROM_PAGE_LEN]; -	unsigned long	count; - -	/* 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) + -		   (buf[12] << 8)  + -		    buf[13]; -	if (count == 0xffffffff) -		count = 1; -	sprintf((char *)valbuf, "%lx", count); -	ivm_set_value("IVM_MacCount", (char *)valbuf); -	return 0; -} - -int ivm_analyze_eeprom(unsigned char *buf, int len) -{ -	unsigned short	val; -	unsigned char	valbuf[CONFIG_SYS_IVM_EEPROM_PAGE_LEN]; -	unsigned char	*tmp; - -	if (ivm_check_crc(buf, 0) != 0) -		return -1; - -	ivm_get_value(buf, CONFIG_SYS_IVM_EEPROM_PAGE_LEN, -			"IVM_BoardId", 0, 1); -	val = ivm_get_value(buf, CONFIG_SYS_IVM_EEPROM_PAGE_LEN, -			"IVM_HWKey", 6, 1); -	if (val != 0xffff) { -		sprintf((char *)valbuf, "%x", ((val / 100) % 10)); -		ivm_set_value("IVM_HWVariant", (char *)valbuf); -		sprintf((char *)valbuf, "%x", (val % 100)); -		ivm_set_value("IVM_HWVersion", (char *)valbuf); -	} -	ivm_get_value(buf, CONFIG_SYS_IVM_EEPROM_PAGE_LEN, -		"IVM_Functions", 12, 0); - -	GET_STRING("IVM_Symbol", IVM_POS_SYMBOL_ONLY, 8) -	GET_STRING("IVM_DeviceName", IVM_POS_SHORT_TEXT, 64) -	tmp = (unsigned char *) getenv("IVM_DeviceName"); -	if (tmp) { -		int	len = strlen((char *)tmp); -		int	i = 0; - -		while (i < len) { -			if (tmp[i] == ';') { -				ivm_set_value("IVM_ShortText", -					(char *)&tmp[i + 1]); -				break; -			} -			i++; -		} -		if (i >= len) -			ivm_set_value("IVM_ShortText", NULL); -	} else { -		ivm_set_value("IVM_ShortText", NULL); -	} -	GET_STRING("IVM_ManufacturerID", IVM_POS_MANU_ID, 32) -	GET_STRING("IVM_ManufacturerSerialNumber", IVM_POS_MANU_SERIAL, 20) -	GET_STRING("IVM_ManufacturerPartNumber", IVM_POS_PART_NUMBER, 32) -	GET_STRING("IVM_ManufacturerBuildState", IVM_POS_BUILD_STATE, 32) -	GET_STRING("IVM_SupplierPartNumber", IVM_POS_SUPPLIER_PART_NUMBER, 32) -	GET_STRING("IVM_DelieveryDate", IVM_POS_DELIVERY_DATE, 32) -	GET_STRING("IVM_SupplierBuildState", IVM_POS_SUPPLIER_BUILD_STATE, 32) -	GET_STRING("IVM_CustomerID", IVM_POS_CUSTOMER_ID, 32) -	GET_STRING("IVM_CustomerProductID", IVM_POS_CUSTOMER_PROD_ID, 32) - -	if (ivm_check_crc(&buf[CONFIG_SYS_IVM_EEPROM_PAGE_LEN * 2], 2) != 0) -		return 0; -	ivm_analyze_block2(&buf[CONFIG_SYS_IVM_EEPROM_PAGE_LEN * 2], -		CONFIG_SYS_IVM_EEPROM_PAGE_LEN); - -	return 0; -} - -int ivm_read_eeprom(void) -{ -#if defined(CONFIG_I2C_MUX) -	I2C_MUX_DEVICE *dev = NULL; -#endif -	uchar i2c_buffer[CONFIG_SYS_IVM_EEPROM_MAX_LEN]; -	uchar	*buf; -	unsigned dev_addr = CONFIG_SYS_IVM_EEPROM_ADR; -	int ret; - -#if defined(CONFIG_I2C_MUX) -	/* First init the Bus, select the Bus */ -#if defined(CONFIG_SYS_I2C_IVM_BUS) -	dev = i2c_mux_ident_muxstring((uchar *)CONFIG_SYS_I2C_IVM_BUS); -#else -	buf = (unsigned char *) getenv("EEprom_ivm"); -	if (buf != NULL) -		dev = i2c_mux_ident_muxstring(buf); -#endif -	if (dev == NULL) { -		printf("Error couldnt add Bus for IVM\n"); -		return -1; -	} -	i2c_set_bus_num(dev->busid); -#endif - -	buf = (unsigned char *) getenv("EEprom_ivm_addr"); -	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); -	if (ret != 0) { -		printf ("Error reading EEprom\n"); -		return -2; -	} - -	return ivm_analyze_eeprom(i2c_buffer, CONFIG_SYS_IVM_EEPROM_MAX_LEN); -} - -#if defined(CONFIG_SYS_I2C_INIT_BOARD)  #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_KM_82XX) -#define SDA_MASK	0x00010000 -#define SCL_MASK	0x00020000 -void set_pin(int state, unsigned long mask) -{ -	ioport_t *iop = ioport_addr((immap_t *)CONFIG_SYS_IMMR, 3); - -	if (state) -		setbits_be32(&iop->pdat, mask); -	else -		clrbits_be32(&iop->pdat, mask); - -	setbits_be32(&iop->pdir, mask); -} - -static int get_pin(unsigned long mask) -{ -	ioport_t *iop = ioport_addr((immap_t *)CONFIG_SYS_IMMR, 3); - -	clrbits_be32(&iop->pdir, mask); -	return 0 != (in_be32(&iop->pdat) & mask); -} - -static void set_sda(int state) -{ -	set_pin(state, SDA_MASK); -} - -static void set_scl(int state) -{ -	set_pin(state, SCL_MASK); -} - -static int get_sda(void) -{ -	return get_pin(SDA_MASK); -} - -static int get_scl(void) -{ -	return get_pin(SCL_MASK); -} - -#if defined(CONFIG_HARD_I2C) -static void setports(int gpio) -{ -	ioport_t *iop = ioport_addr((immap_t *)CONFIG_SYS_IMMR, 3); - -	if (gpio) { -		clrbits_be32(&iop->ppar, (SDA_MASK | SCL_MASK)); -		clrbits_be32(&iop->podr, (SDA_MASK | SCL_MASK)); -	} else { -		setbits_be32(&iop->ppar, (SDA_MASK | SCL_MASK)); -		clrbits_be32(&iop->pdir, (SDA_MASK | SCL_MASK)); -		setbits_be32(&iop->podr, (SDA_MASK | SCL_MASK)); -	} -} -#endif -#endif -  #if !defined(CONFIG_MPC83xx)  static void i2c_write_start_seq(void)  { @@ -481,7 +105,7 @@ static void i2c_write_start_seq(void)   * This I2C Deblocking mechanism was developed by Keymile in association   * with Anatech and Atmel in 1998.   */ -static int i2c_make_abort(void) +int i2c_make_abort(void)  {  #if defined(CONFIG_HARD_I2C) && !defined(MACH_TYPE_KM_KIRKWOOD) @@ -515,6 +139,7 @@ static int i2c_make_abort(void)  			sda_state = get_sda();  			if (scl_state && sda_state) {  				ret = 0; +				printf("[INFO] i2c abort after %d clocks\n", i);  				break;  			}  		} @@ -522,6 +147,8 @@ static int i2c_make_abort(void)  	if (ret == 0)  		for (i = 0; i < 5; i++)  			i2c_write_start_seq(); +	else +		printf("[ERROR] i2c abort failed\n");  	/* respect stop setup time */  	udelay(DELAY_ABORT_SEQ); @@ -536,7 +163,7 @@ static int i2c_make_abort(void)  #endif  	return ret;  } -#endif +#endif /* !MPC83xx */  #if defined(CONFIG_MPC83xx)  static void i2c_write_start_seq(void) @@ -549,7 +176,7 @@ static void i2c_write_start_seq(void)  	out_8(&dev->cr, (I2C_CR_MEN));  } -static int i2c_make_abort(void) +int i2c_make_abort(void)  {  	struct fsl_i2c *dev;  	dev = (struct fsl_i2c *) (CONFIG_SYS_IMMR + CONFIG_SYS_I2C_OFFSET); @@ -609,63 +236,6 @@ void i2c_init_board(void)  	/* Now run the AbortSequence() */  	i2c_make_abort();  } -#endif -#endif - -#if defined(CONFIG_OF_BOARD_SETUP) && defined(CONFIG_OF_LIBFDT) -int fdt_set_node_and_value(void *blob, -				char *nodename, -				char *regname, -				void *var, -				int size) -{ -	int ret = 0; -	int nodeoffset = 0; - -	nodeoffset = fdt_path_offset(blob, nodename); -	if (nodeoffset >= 0) { -		ret = fdt_setprop(blob, nodeoffset, regname, var, -					size); -		if (ret < 0) -			printf("ft_blob_update(): cannot set %s/%s " -				"property err:%s\n", nodename, regname, -				fdt_strerror(ret)); -	} else { -		printf("ft_blob_update(): cannot find %s node " -			"err:%s\n", nodename, fdt_strerror(nodeoffset)); -	} -	return ret; -} - -int fdt_get_node_and_value(void *blob, -				char *nodename, -				char *propname, -				void **var) -{ -	int len; -	int nodeoffset = 0; - -	nodeoffset = fdt_path_offset(blob, nodename); -	if (nodeoffset >= 0) { -		*var = (void *)fdt_getprop(blob, nodeoffset, propname, &len); -		if (len == 0) { -			/* no value */ -			printf("%s no value\n", __func__); -			return -1; -		} else if (len > 0) { -			return len; -		} else { -			printf("libfdt fdt_getprop(): %s\n", -				fdt_strerror(len)); -			return -2; -		} -	} else { -		printf("%s: cannot find %s node err:%s\n", __func__, -			nodename, fdt_strerror(nodeoffset)); -		return -3; -	} -} -#endif  #if !defined(MACH_TYPE_KM_KIRKWOOD)  int ethernet_present(void) @@ -703,6 +273,7 @@ static int do_setboardid(cmd_tbl_t *cmdtp, int flag, int argc,  	}  	sprintf((char *)buf, "%s", p);  	setenv("boardid", (char *)buf); +	printf("set boardid=%s\n", buf);  	p = get_local_var("IVM_HWKey");  	if (p == NULL) { @@ -711,6 +282,8 @@ static int do_setboardid(cmd_tbl_t *cmdtp, int flag, int argc,  	}  	sprintf((char *)buf, "%s", p);  	setenv("hwkey", (char *)buf); +	printf("set hwkey=%s\n", buf); +	printf("Execute manually saveenv for persistent storage.\n");  	return 0;  } @@ -832,11 +405,7 @@ int do_checkboardidhwk(cmd_tbl_t *cmdtp, int flag, int argc,  				 * Compare the values of the found entry in the  				 * list with the valid values which are stored  				 * in the inventory eeprom. If they are equal -				 * store the values in environment variables -				 * and save the environment. -				 * This can only happen once for the lifetime -				 * of a board, because once saved the function -				 * will never reach the while loop. +				 * set the values in environment variables.  				 */  				if ((bid == ivmbid) && (hwkey == ivmhwkey)) {  					char buf[10]; @@ -848,7 +417,6 @@ int do_checkboardidhwk(cmd_tbl_t *cmdtp, int flag, int argc,  					setenv("boardid", buf);  					sprintf(buf, "%lx", hwkey);  					setenv("hwkey", buf); -					saveenv();  				}  			} /* end while( ! found ) */  		} @@ -859,7 +427,8 @@ int do_checkboardidhwk(cmd_tbl_t *cmdtp, int flag, int argc,  		printf("boardid=0x%3lX, hwkey=%ld\n", envbid, envhwkey);  		rc = 0; /* match */  	} else { -		printf("Error: env bId=0x%3lX, hwKey=%ld\n", envbid, envhwkey); +		printf("Error: env boardid=0x%3lX, hwkey=%ld\n", envbid, +			envhwkey);  		printf("       IVM bId=0x%3lX, hwKey=%ld\n", ivmbid, ivmhwkey);  		rc = 1; /* don't match */  	} |