board: gateworks: venice: use common GSC driver
Use the common GSC driver.
This allows us to do some additional cleanup:
 - rename gsc{.c,.h} to eeprom{.c.h} for clarity
 - collapse eeprom_get_dev
 - remove unnecessary header files and alphabatize includes
Signed-off-by: Tim Harvey <tharvey@gateworks.com>
			
			
This commit is contained in:
		
							parent
							
								
									82b16555cf
								
							
						
					
					
						commit
						fb9ec33878
					
				|  | @ -57,6 +57,10 @@ | ||||||
| 	u-boot,dm-spl; | 	u-boot,dm-spl; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | &gsc { | ||||||
|  | 	u-boot,dm-spl; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
| &i2c2 { | &i2c2 { | ||||||
| 	u-boot,dm-spl; | 	u-boot,dm-spl; | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | @ -27,6 +27,13 @@ | ||||||
| 	pinctrl-0 = <&pinctrl_i2c1>; | 	pinctrl-0 = <&pinctrl_i2c1>; | ||||||
| 	status = "okay"; | 	status = "okay"; | ||||||
| 
 | 
 | ||||||
|  | 	gsc: gsc@20 { | ||||||
|  | 		compatible = "gw,gsc"; | ||||||
|  | 		reg = <0x20>; | ||||||
|  | 		#address-cells = <1>; | ||||||
|  | 		#size-cells = <0>; | ||||||
|  | 	}; | ||||||
|  | 
 | ||||||
| 	eeprom@51 { | 	eeprom@51 { | ||||||
| 		compatible = "atmel,24c02"; | 		compatible = "atmel,24c02"; | ||||||
| 		reg = <0x51>; | 		reg = <0x51>; | ||||||
|  |  | ||||||
|  | @ -94,6 +94,10 @@ | ||||||
| 	u-boot,dm-spl; | 	u-boot,dm-spl; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | &gsc { | ||||||
|  | 	u-boot,dm-spl; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
| &i2c2 { | &i2c2 { | ||||||
| 	u-boot,dm-spl; | 	u-boot,dm-spl; | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | @ -27,6 +27,13 @@ | ||||||
| 	pinctrl-0 = <&pinctrl_i2c1>; | 	pinctrl-0 = <&pinctrl_i2c1>; | ||||||
| 	status = "okay"; | 	status = "okay"; | ||||||
| 
 | 
 | ||||||
|  | 	gsc: gsc@20 { | ||||||
|  | 		compatible = "gw,gsc"; | ||||||
|  | 		reg = <0x20>; | ||||||
|  | 		#address-cells = <1>; | ||||||
|  | 		#size-cells = <0>; | ||||||
|  | 	}; | ||||||
|  | 
 | ||||||
| 	eeprom@51 { | 	eeprom@51 { | ||||||
| 		compatible = "atmel,24c02"; | 		compatible = "atmel,24c02"; | ||||||
| 		reg = <0x51>; | 		reg = <0x51>; | ||||||
|  |  | ||||||
|  | @ -97,6 +97,8 @@ config TARGET_IMX8MM_VENICE | ||||||
| 	select IMX8MM | 	select IMX8MM | ||||||
| 	select SUPPORT_SPL | 	select SUPPORT_SPL | ||||||
| 	select IMX8M_LPDDR4 | 	select IMX8M_LPDDR4 | ||||||
|  | 	select GATEWORKS_SC | ||||||
|  | 	select MISC | ||||||
| 
 | 
 | ||||||
| config TARGET_KONTRON_MX8MM | config TARGET_KONTRON_MX8MM | ||||||
| 	bool "Kontron Electronics N80xx" | 	bool "Kontron Electronics N80xx" | ||||||
|  | @ -143,6 +145,8 @@ config TARGET_IMX8MN_VENICE | ||||||
| 	select IMX8MN | 	select IMX8MN | ||||||
| 	select SUPPORT_SPL | 	select SUPPORT_SPL | ||||||
| 	select IMX8M_LPDDR4 | 	select IMX8M_LPDDR4 | ||||||
|  | 	select GATEWORKS_SC | ||||||
|  | 	select MISC | ||||||
| 
 | 
 | ||||||
| config TARGET_IMX8MP_EVK | config TARGET_IMX8MP_EVK | ||||||
| 	bool "imx8mp LPDDR4 EVK board" | 	bool "imx8mp LPDDR4 EVK board" | ||||||
|  |  | ||||||
|  | @ -4,7 +4,7 @@ | ||||||
| # SPDX-License-Identifier: GPL-2.0+
 | # SPDX-License-Identifier: GPL-2.0+
 | ||||||
| #
 | #
 | ||||||
| 
 | 
 | ||||||
| obj-y += venice.o gsc.o | obj-y += venice.o eeprom.o | ||||||
| 
 | 
 | ||||||
| ifdef CONFIG_SPL_BUILD | ifdef CONFIG_SPL_BUILD | ||||||
| obj-y += spl.o | obj-y += spl.o | ||||||
|  |  | ||||||
|  | @ -0,0 +1,353 @@ | ||||||
|  | // SPDX-License-Identifier: GPL-2.0+
 | ||||||
|  | /*
 | ||||||
|  |  * Copyright 2021 Gateworks Corporation | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | #include <common.h> | ||||||
|  | #include <gsc.h> | ||||||
|  | #include <hexdump.h> | ||||||
|  | #include <i2c.h> | ||||||
|  | #include <dm/uclass.h> | ||||||
|  | 
 | ||||||
|  | #include "eeprom.h" | ||||||
|  | 
 | ||||||
|  | /* I2C */ | ||||||
|  | #define SOM_EEPROM_BUSNO		0 | ||||||
|  | #define SOM_EEPROM_ADDR			0x51 | ||||||
|  | #define BASEBOARD_EEPROM_BUSNO		1 | ||||||
|  | #define BASEBOARD_EEPROM_ADDR		0x52 | ||||||
|  | 
 | ||||||
|  | struct venice_board_info som_info; | ||||||
|  | struct venice_board_info base_info; | ||||||
|  | char venice_model[32]; | ||||||
|  | u32 venice_serial; | ||||||
|  | 
 | ||||||
|  | /* return a mac address from EEPROM info */ | ||||||
|  | int eeprom_getmac(int index, uint8_t *address) | ||||||
|  | { | ||||||
|  | 	int i, j; | ||||||
|  | 	u32 maclow, machigh; | ||||||
|  | 	u64 mac; | ||||||
|  | 
 | ||||||
|  | 	j = 0; | ||||||
|  | 	if (som_info.macno) { | ||||||
|  | 		maclow = som_info.mac[5]; | ||||||
|  | 		maclow |= som_info.mac[4] << 8; | ||||||
|  | 		maclow |= som_info.mac[3] << 16; | ||||||
|  | 		maclow |= som_info.mac[2] << 24; | ||||||
|  | 		machigh = som_info.mac[1]; | ||||||
|  | 		machigh |= som_info.mac[0] << 8; | ||||||
|  | 		mac = machigh; | ||||||
|  | 		mac <<= 32; | ||||||
|  | 		mac |= maclow; | ||||||
|  | 		for (i = 0; i < som_info.macno; i++, j++) { | ||||||
|  | 			if (index == j) | ||||||
|  | 				goto out; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	maclow = base_info.mac[5]; | ||||||
|  | 	maclow |= base_info.mac[4] << 8; | ||||||
|  | 	maclow |= base_info.mac[3] << 16; | ||||||
|  | 	maclow |= base_info.mac[2] << 24; | ||||||
|  | 	machigh = base_info.mac[1]; | ||||||
|  | 	machigh |= base_info.mac[0] << 8; | ||||||
|  | 	mac = machigh; | ||||||
|  | 	mac <<= 32; | ||||||
|  | 	mac |= maclow; | ||||||
|  | 	for (i = 0; i < base_info.macno; i++, j++) { | ||||||
|  | 		if (index == j) | ||||||
|  | 			goto out; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return -EINVAL; | ||||||
|  | 
 | ||||||
|  | out: | ||||||
|  | 	mac += i; | ||||||
|  | 	address[0] = (mac >> 40) & 0xff; | ||||||
|  | 	address[1] = (mac >> 32) & 0xff; | ||||||
|  | 	address[2] = (mac >> 24) & 0xff; | ||||||
|  | 	address[3] = (mac >> 16) & 0xff; | ||||||
|  | 	address[4] = (mac >> 8) & 0xff; | ||||||
|  | 	address[5] = (mac >> 0) & 0xff; | ||||||
|  | 
 | ||||||
|  | 	return 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static int eeprom_read(int busno, int slave, int alen, struct venice_board_info *info) | ||||||
|  | { | ||||||
|  | 	int i; | ||||||
|  | 	int chksum; | ||||||
|  | 	unsigned char *buf = (unsigned char *)info; | ||||||
|  | 	struct udevice *dev, *bus; | ||||||
|  | 	int ret; | ||||||
|  | 
 | ||||||
|  | 	/* probe device */ | ||||||
|  | 	ret = uclass_get_device_by_seq(UCLASS_I2C, busno, &bus); | ||||||
|  | 	if (ret) | ||||||
|  | 		return ret; | ||||||
|  | 	ret = dm_i2c_probe(bus, slave, 0, &dev); | ||||||
|  | 	if (ret) | ||||||
|  | 		return ret; | ||||||
|  | 
 | ||||||
|  | 	/* read eeprom config section */ | ||||||
|  | 	memset(info, 0, sizeof(*info)); | ||||||
|  | 	ret = i2c_set_chip_offset_len(dev, alen); | ||||||
|  | 	if (ret) { | ||||||
|  | 		puts("EEPROM: Failed to set alen\n"); | ||||||
|  | 		return ret; | ||||||
|  | 	} | ||||||
|  | 	ret = dm_i2c_read(dev, 0x00, buf, sizeof(*info)); | ||||||
|  | 	if (ret) { | ||||||
|  | 		if (slave == SOM_EEPROM_ADDR) | ||||||
|  | 			printf("EEPROM: Failed to read EEPROM\n"); | ||||||
|  | 		return ret; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	/* validate checksum */ | ||||||
|  | 	for (chksum = 0, i = 0; i < (int)sizeof(*info) - 2; i++) | ||||||
|  | 		chksum += buf[i]; | ||||||
|  | 	if ((info->chksum[0] != chksum >> 8) || | ||||||
|  | 	    (info->chksum[1] != (chksum & 0xff))) { | ||||||
|  | 		printf("EEPROM: I2C%d@0x%02x: Invalid Checksum\n", busno, slave); | ||||||
|  | 		print_hex_dump_bytes("", DUMP_PREFIX_NONE, buf, sizeof(*info)); | ||||||
|  | 		memset(info, 0, sizeof(*info)); | ||||||
|  | 		return -EINVAL; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	/* sanity check valid model */ | ||||||
|  | 	if (info->model[0] != 'G' || info->model[1] != 'W') { | ||||||
|  | 		printf("EEPROM: I2C%d@0x%02x: Invalid Model in EEPROM\n", busno, slave); | ||||||
|  | 		print_hex_dump_bytes("", DUMP_PREFIX_NONE, buf, sizeof(*info)); | ||||||
|  | 		memset(info, 0, sizeof(*info)); | ||||||
|  | 		return -EINVAL; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /* determine BOM revision from model */ | ||||||
|  | int get_bom_rev(const char *str) | ||||||
|  | { | ||||||
|  | 	int  rev_bom = 0; | ||||||
|  | 	int i; | ||||||
|  | 
 | ||||||
|  | 	for (i = strlen(str) - 1; i > 0; i--) { | ||||||
|  | 		if (str[i] == '-') | ||||||
|  | 			break; | ||||||
|  | 		if (str[i] >= '1' && str[i] <= '9') { | ||||||
|  | 			rev_bom = str[i] - '0'; | ||||||
|  | 			break; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	return rev_bom; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /* determine PCB revision from model */ | ||||||
|  | char get_pcb_rev(const char *str) | ||||||
|  | { | ||||||
|  | 	char rev_pcb = 'A'; | ||||||
|  | 	int i; | ||||||
|  | 
 | ||||||
|  | 	for (i = strlen(str) - 1; i > 0; i--) { | ||||||
|  | 		if (str[i] == '-') | ||||||
|  | 			break; | ||||||
|  | 		if (str[i] >= 'A') { | ||||||
|  | 			rev_pcb = str[i]; | ||||||
|  | 			break; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	return rev_pcb; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * get dt name based on model and detail level: | ||||||
|  |  * | ||||||
|  |  * For boards that are a combination of a SoM plus a Baseboard: | ||||||
|  |  *   Venice SoM part numbers are GW70xx where xx is: | ||||||
|  |  *    7000-7019: same PCB with som dt of '0x' | ||||||
|  |  *    7020-7039: same PCB with som dt of '2x' | ||||||
|  |  *    7040-7059: same PCB with som dt of '4x' | ||||||
|  |  *    7060-7079: same PCB with som dt of '6x' | ||||||
|  |  *    7080-7099: same PCB with som dt of '8x' | ||||||
|  |  *   Venice Baseboard part numbers are GW7xxx where xxx is: | ||||||
|  |  *    7100-7199: same PCB with base dt of '71xx' | ||||||
|  |  *    7200-7299: same PCB with base dt of '72xx' | ||||||
|  |  *    7300-7399: same PCB with base dt of '73xx' | ||||||
|  |  *    7400-7499: same PCB with base dt of '74xx' | ||||||
|  |  *    7500-7599: same PCB with base dt of '75xx' | ||||||
|  |  *    7600-7699: same PCB with base dt of '76xx' | ||||||
|  |  *    7700-7799: same PCB with base dt of '77xx' | ||||||
|  |  *    7800-7899: same PCB with base dt of '78xx' | ||||||
|  |  *   DT name is comprised of: | ||||||
|  |  *    gw<base dt>-<som dt>-[base-pcb-rev][base-bom-rev][som-pcb-rev][som-bom-rev] | ||||||
|  |  * | ||||||
|  |  * For board models from 7900-7999 each PCB is unique with its own dt: | ||||||
|  |  *   DT name is comprised: | ||||||
|  |  *    gw<model>-[pcb-rev][bom-rev] | ||||||
|  |  * | ||||||
|  |  */ | ||||||
|  | #define snprintfcat(dest, sz, fmt, ...) \ | ||||||
|  | 	snprintf((dest) + strlen(dest), (sz) - strlen(dest), fmt, ##__VA_ARGS__) | ||||||
|  | const char *eeprom_get_dtb_name(int level, char *buf, int sz) | ||||||
|  | { | ||||||
|  | #ifdef CONFIG_IMX8MM | ||||||
|  | 	const char *pre = "imx8mm-venice-gw"; | ||||||
|  | #else | ||||||
|  | 	const char *pre = "imx8mn-venice-gw"; | ||||||
|  | #endif | ||||||
|  | 	int model, rev_pcb, rev_bom; | ||||||
|  | 
 | ||||||
|  | 	model = ((som_info.model[2] - '0') * 1000) | ||||||
|  | 		+ ((som_info.model[3] - '0') * 100) | ||||||
|  | 		+ ((som_info.model[4] - '0') * 10) | ||||||
|  | 		+ (som_info.model[5] - '0'); | ||||||
|  | 	rev_pcb = tolower(get_pcb_rev(som_info.model)); | ||||||
|  | 	rev_bom = get_bom_rev(som_info.model); | ||||||
|  | 
 | ||||||
|  | 	/* som + baseboard*/ | ||||||
|  | 	if (base_info.model[0]) { | ||||||
|  | 		/* baseboard id: 7100-7199->71; 7200-7299->72; etc */ | ||||||
|  | 		int base = ((base_info.model[2] - '0') * 10) + (base_info.model[3] - '0'); | ||||||
|  | 		/* som id: 7000-7019->1; 7020-7039->2; etc */ | ||||||
|  | 		int som = ((model % 100) / 20) * 2; | ||||||
|  | 		int rev_base_pcb = tolower(get_pcb_rev(base_info.model)); | ||||||
|  | 		int rev_base_bom = get_bom_rev(base_info.model); | ||||||
|  | 
 | ||||||
|  | 		snprintf(buf, sz, "%s%2dxx-%dx", pre, base, som); | ||||||
|  | 		switch (level) { | ||||||
|  | 		case 0: /* full model (ie gw73xx-0x-a1a1) */ | ||||||
|  | 			if (rev_base_bom) | ||||||
|  | 				snprintfcat(buf, sz, "-%c%d", rev_base_pcb, rev_base_bom); | ||||||
|  | 			else | ||||||
|  | 				snprintfcat(buf, sz, "-%c", rev_base_pcb); | ||||||
|  | 			if (rev_bom) | ||||||
|  | 				snprintfcat(buf, sz, "%c%d", rev_pcb, rev_bom); | ||||||
|  | 			else | ||||||
|  | 				snprintfcat(buf, sz, "%c", rev_pcb); | ||||||
|  | 			break; | ||||||
|  | 		case 1: /* don't care about SoM revision */ | ||||||
|  | 			if (rev_base_bom) | ||||||
|  | 				snprintfcat(buf, sz, "-%c%d", rev_base_pcb, rev_base_bom); | ||||||
|  | 			else | ||||||
|  | 				snprintfcat(buf, sz, "-%c", rev_base_pcb); | ||||||
|  | 			snprintfcat(buf, sz, "xx"); | ||||||
|  | 			break; | ||||||
|  | 		case 2: /* don't care about baseboard revision */ | ||||||
|  | 			snprintfcat(buf, sz, "-xx"); | ||||||
|  | 			if (rev_bom) | ||||||
|  | 				snprintfcat(buf, sz, "%c%d", rev_pcb, rev_bom); | ||||||
|  | 			else | ||||||
|  | 				snprintfcat(buf, sz, "%c", rev_pcb); | ||||||
|  | 			break; | ||||||
|  | 		case 3: /* don't care about SoM/baseboard revision */ | ||||||
|  | 			break; | ||||||
|  | 		default: | ||||||
|  | 			return NULL; | ||||||
|  | 		} | ||||||
|  | 	} else { | ||||||
|  | 		snprintf(buf, sz, "%s%04d", pre, model); | ||||||
|  | 		switch (level) { | ||||||
|  | 		case 0: /* full model wth PCB and BOM revision first (ie gw7901-a1) */ | ||||||
|  | 			if (rev_bom) | ||||||
|  | 				snprintfcat(buf, sz, "-%c%d", rev_pcb, rev_bom); | ||||||
|  | 			else | ||||||
|  | 				snprintfcat(buf, sz, "-%c", rev_pcb); | ||||||
|  | 			break; | ||||||
|  | 		case 1: /* don't care about BOM revision */ | ||||||
|  | 			snprintfcat(buf, sz, "-%c", rev_pcb); | ||||||
|  | 			break; | ||||||
|  | 		case 2: /* don't care about PCB or BOM revision */ | ||||||
|  | 			break; | ||||||
|  | 		default: | ||||||
|  | 			return NULL; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return buf; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static int eeprom_info(bool verbose) | ||||||
|  | { | ||||||
|  | 	printf("Model   : %s\n", venice_model); | ||||||
|  | 	printf("Serial  : %d\n", som_info.serial); | ||||||
|  | 	printf("MFGDate : %02x-%02x-%02x%02x\n", | ||||||
|  | 	       som_info.mfgdate[0], som_info.mfgdate[1], | ||||||
|  | 	       som_info.mfgdate[2], som_info.mfgdate[3]); | ||||||
|  | 	if (base_info.model[0] && verbose) { | ||||||
|  | 		printf("SOM     : %s %d %02x-%02x-%02x%02x\n", | ||||||
|  | 		       som_info.model, som_info.serial, | ||||||
|  | 		       som_info.mfgdate[0], som_info.mfgdate[1], | ||||||
|  | 		       som_info.mfgdate[2], som_info.mfgdate[3]); | ||||||
|  | 		printf("BASE    : %s %d %02x-%02x-%02x%02x\n", | ||||||
|  | 		       base_info.model, base_info.serial, | ||||||
|  | 		       base_info.mfgdate[0], base_info.mfgdate[1], | ||||||
|  | 		       base_info.mfgdate[2], base_info.mfgdate[3]); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | int eeprom_init(int quiet) | ||||||
|  | { | ||||||
|  | 	char rev_pcb; | ||||||
|  | 	int rev_bom; | ||||||
|  | 	int ret; | ||||||
|  | 
 | ||||||
|  | 	ret = eeprom_read(SOM_EEPROM_BUSNO, SOM_EEPROM_ADDR, 1, &som_info); | ||||||
|  | 	if (ret) { | ||||||
|  | 		puts("ERROR: Failed to probe EEPROM\n"); | ||||||
|  | 		memset(&som_info, 0, sizeof(som_info)); | ||||||
|  | 		return 0; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	/* read optional baseboard EEPROM */ | ||||||
|  | 	eeprom_read(BASEBOARD_EEPROM_BUSNO, BASEBOARD_EEPROM_ADDR, 2, &base_info); | ||||||
|  | 
 | ||||||
|  | 	/* create model strings */ | ||||||
|  | 	if (base_info.model[0]) { | ||||||
|  | 		sprintf(venice_model, "GW%c%c%c%c-%c%c-", | ||||||
|  | 			som_info.model[2], /* family */ | ||||||
|  | 			base_info.model[3], /* baseboard */ | ||||||
|  | 			base_info.model[4], base_info.model[5], /* subload of baseboard */ | ||||||
|  | 			som_info.model[4], som_info.model[5]); /* last 2digits of SOM */ | ||||||
|  | 
 | ||||||
|  | 		/* baseboard revision */ | ||||||
|  | 		rev_pcb = get_pcb_rev(base_info.model); | ||||||
|  | 		rev_bom = get_bom_rev(base_info.model); | ||||||
|  | 		if (rev_bom) | ||||||
|  | 			sprintf(venice_model + strlen(venice_model), "%c%d", rev_pcb, rev_bom); | ||||||
|  | 		else | ||||||
|  | 			sprintf(venice_model + strlen(venice_model), "%c", rev_pcb); | ||||||
|  | 		/* som revision */ | ||||||
|  | 		rev_pcb = get_pcb_rev(som_info.model); | ||||||
|  | 		rev_bom = get_bom_rev(som_info.model); | ||||||
|  | 		if (rev_bom) | ||||||
|  | 			sprintf(venice_model + strlen(venice_model), "%c%d", rev_pcb, rev_bom); | ||||||
|  | 		else | ||||||
|  | 			sprintf(venice_model + strlen(venice_model), "%c", rev_pcb); | ||||||
|  | 	} else { | ||||||
|  | 		strcpy(venice_model, som_info.model); | ||||||
|  | 	} | ||||||
|  | 	venice_serial = som_info.serial; | ||||||
|  | 
 | ||||||
|  | 	if (!quiet) | ||||||
|  | 		eeprom_info(false); | ||||||
|  | 
 | ||||||
|  | 	return (16 << som_info.sdram_size); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void board_gsc_info(void) | ||||||
|  | { | ||||||
|  | 	eeprom_info(true); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | const char *eeprom_get_model(void) | ||||||
|  | { | ||||||
|  | 	return venice_model; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | u32 eeprom_get_serial(void) | ||||||
|  | { | ||||||
|  | 	return venice_serial; | ||||||
|  | } | ||||||
|  | @ -3,19 +3,8 @@ | ||||||
|  * Copyright 2021 Gateworks Corporation |  * Copyright 2021 Gateworks Corporation | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| #ifndef _GSC_H_ | #ifndef _VENICE_EEPROM_H_ | ||||||
| #define _GSC_H_ | #define _VENICE_EEPROM_H_ | ||||||
| 
 |  | ||||||
| /* I2C bus numbers */ |  | ||||||
| #define GSC_BUSNO			0 |  | ||||||
| #define BASEBOARD_EEPROM_BUSNO		1 |  | ||||||
| 
 |  | ||||||
| /* I2C slave addresses */ |  | ||||||
| #define GSC_SC_ADDR             0x20 |  | ||||||
| #define GSC_RTC_ADDR            0x68 |  | ||||||
| #define GSC_HWMON_ADDR          0x29 |  | ||||||
| #define GSC_EEPROM_ADDR         0x51 |  | ||||||
| #define BASEBOARD_EEPROM_ADDR	0x52 |  | ||||||
| 
 | 
 | ||||||
| struct venice_board_info { | struct venice_board_info { | ||||||
| 	u8 mac[6];		/* 0x00: MAC base */ | 	u8 mac[6];		/* 0x00: MAC base */ | ||||||
|  | @ -35,11 +24,10 @@ struct venice_board_info { | ||||||
| 	u8 chksum[2];	/* 0x4E */ | 	u8 chksum[2];	/* 0x4E */ | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| int gsc_init(int quiet); | int eeprom_init(int quiet); | ||||||
| int gsc_hwmon(void); | const char *eeprom_get_model(void); | ||||||
| const char *gsc_get_model(void); | const char *eeprom_get_dtb_name(int level, char *buf, int len); | ||||||
| const char *gsc_get_dtb_name(int level, char *buf, int len); | int eeprom_getmac(int index, uint8_t *enetaddr); | ||||||
| int gsc_getmac(int index, uint8_t *enetaddr); | uint32_t eeprom_get_serial(void); | ||||||
| uint32_t gsc_get_serial(void); |  | ||||||
| 
 | 
 | ||||||
| #endif | #endif | ||||||
|  | @ -1,700 +0,0 @@ | ||||||
| // SPDX-License-Identifier: GPL-2.0+
 |  | ||||||
| /*
 |  | ||||||
|  * Copyright 2021 Gateworks Corporation |  | ||||||
|  */ |  | ||||||
| 
 |  | ||||||
| #include <common.h> |  | ||||||
| #include <command.h> |  | ||||||
| #include <hang.h> |  | ||||||
| #include <hexdump.h> |  | ||||||
| #include <i2c.h> |  | ||||||
| #include <linux/delay.h> |  | ||||||
| #include <dm/uclass.h> |  | ||||||
| 
 |  | ||||||
| #include "gsc.h" |  | ||||||
| 
 |  | ||||||
| DECLARE_GLOBAL_DATA_PTR; |  | ||||||
| 
 |  | ||||||
| struct venice_board_info som_info; |  | ||||||
| struct venice_board_info base_info; |  | ||||||
| char venice_model[32]; |  | ||||||
| uint32_t venice_serial; |  | ||||||
| 
 |  | ||||||
| /* return a mac address from EEPROM info */ |  | ||||||
| int gsc_getmac(int index, uint8_t *address) |  | ||||||
| { |  | ||||||
| 	int i, j; |  | ||||||
| 	u32 maclow, machigh; |  | ||||||
| 	u64 mac; |  | ||||||
| 
 |  | ||||||
| 	j = 0; |  | ||||||
| 	if (som_info.macno) { |  | ||||||
| 		maclow = som_info.mac[5]; |  | ||||||
| 		maclow |= som_info.mac[4] << 8; |  | ||||||
| 		maclow |= som_info.mac[3] << 16; |  | ||||||
| 		maclow |= som_info.mac[2] << 24; |  | ||||||
| 		machigh = som_info.mac[1]; |  | ||||||
| 		machigh |= som_info.mac[0] << 8; |  | ||||||
| 		mac = machigh; |  | ||||||
| 		mac <<= 32; |  | ||||||
| 		mac |= maclow; |  | ||||||
| 		for (i = 0; i < som_info.macno; i++, j++) { |  | ||||||
| 			if (index == j) |  | ||||||
| 				goto out; |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	maclow = base_info.mac[5]; |  | ||||||
| 	maclow |= base_info.mac[4] << 8; |  | ||||||
| 	maclow |= base_info.mac[3] << 16; |  | ||||||
| 	maclow |= base_info.mac[2] << 24; |  | ||||||
| 	machigh = base_info.mac[1]; |  | ||||||
| 	machigh |= base_info.mac[0] << 8; |  | ||||||
| 	mac = machigh; |  | ||||||
| 	mac <<= 32; |  | ||||||
| 	mac |= maclow; |  | ||||||
| 	for (i = 0; i < base_info.macno; i++, j++) { |  | ||||||
| 		if (index == j) |  | ||||||
| 			goto out; |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	return -EINVAL; |  | ||||||
| 
 |  | ||||||
| out: |  | ||||||
| 	mac += i; |  | ||||||
| 	address[0] = (mac >> 40) & 0xff; |  | ||||||
| 	address[1] = (mac >> 32) & 0xff; |  | ||||||
| 	address[2] = (mac >> 24) & 0xff; |  | ||||||
| 	address[3] = (mac >> 16) & 0xff; |  | ||||||
| 	address[4] = (mac >> 8) & 0xff; |  | ||||||
| 	address[5] = (mac >> 0) & 0xff; |  | ||||||
| 
 |  | ||||||
| 	return 0; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| /* System Controller registers */ |  | ||||||
| enum { |  | ||||||
| 	GSC_SC_CTRL0		= 0, |  | ||||||
| 	GSC_SC_CTRL1		= 1, |  | ||||||
| 	GSC_SC_STATUS		= 10, |  | ||||||
| 	GSC_SC_FWCRC		= 12, |  | ||||||
| 	GSC_SC_FWVER		= 14, |  | ||||||
| 	GSC_SC_WP		= 15, |  | ||||||
| 	GSC_SC_RST_CAUSE	= 16, |  | ||||||
| 	GSC_SC_THERM_PROTECT	= 19, |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| /* System Controller Control1 bits */ |  | ||||||
| enum { |  | ||||||
| 	GSC_SC_CTRL1_WDTIME	= 4, /* 1 = 60s timeout, 0 = 30s timeout */ |  | ||||||
| 	GSC_SC_CTRL1_WDEN	= 5, /* 1 = enable, 0 = disable */ |  | ||||||
| 	GSC_SC_CTRL1_BOOT_CHK   = 6, /* 1 = enable alt boot check */ |  | ||||||
| 	GSC_SC_CTRL1_WDDIS	= 7, /* 1 = disable boot watchdog */ |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| /* System Controller Interrupt bits */ |  | ||||||
| enum { |  | ||||||
| 	GSC_SC_IRQ_PB		= 0, /* Pushbutton switch */ |  | ||||||
| 	GSC_SC_IRQ_SECURE	= 1, /* Secure Key erase operation complete */ |  | ||||||
| 	GSC_SC_IRQ_EEPROM_WP	= 2, /* EEPROM write violation */ |  | ||||||
| 	GSC_SC_IRQ_GPIO		= 4, /* GPIO change */ |  | ||||||
| 	GSC_SC_IRQ_TAMPER	= 5, /* Tamper detect */ |  | ||||||
| 	GSC_SC_IRQ_WATCHDOG	= 6, /* Watchdog trip */ |  | ||||||
| 	GSC_SC_IRQ_PBLONG	= 7, /* Pushbutton long hold */ |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| /* System Controller WP bits */ |  | ||||||
| enum { |  | ||||||
| 	GSC_SC_WP_ALL		= 0, /* Write Protect All EEPROM regions */ |  | ||||||
| 	GSC_SC_WP_BOARDINFO	= 1, /* Write Protect Board Info region */ |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| /* System Controller Reset Cause */ |  | ||||||
| enum { |  | ||||||
| 	GSC_SC_RST_CAUSE_VIN		= 0, |  | ||||||
| 	GSC_SC_RST_CAUSE_PB		= 1, |  | ||||||
| 	GSC_SC_RST_CAUSE_WDT		= 2, |  | ||||||
| 	GSC_SC_RST_CAUSE_CPU		= 3, |  | ||||||
| 	GSC_SC_RST_CAUSE_TEMP_LOCAL	= 4, |  | ||||||
| 	GSC_SC_RST_CAUSE_TEMP_REMOTE	= 5, |  | ||||||
| 	GSC_SC_RST_CAUSE_SLEEP		= 6, |  | ||||||
| 	GSC_SC_RST_CAUSE_BOOT_WDT	= 7, |  | ||||||
| 	GSC_SC_RST_CAUSE_BOOT_WDT_MAN	= 8, |  | ||||||
| 	GSC_SC_RST_CAUSE_SOFT_PWR	= 9, |  | ||||||
| 	GSC_SC_RST_CAUSE_MAX		= 10, |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| #include <dm/device.h> |  | ||||||
| static struct udevice *gsc_get_dev(int busno, int slave) |  | ||||||
| { |  | ||||||
| 	struct udevice *dev, *bus; |  | ||||||
| 	int ret; |  | ||||||
| 
 |  | ||||||
| 	ret = uclass_get_device_by_seq(UCLASS_I2C, busno, &bus); |  | ||||||
| 	if (ret) { |  | ||||||
| 		printf("GSC     : failed I2C%d probe: %d\n", busno, ret); |  | ||||||
| 		return NULL; |  | ||||||
| 	} |  | ||||||
| 	ret = dm_i2c_probe(bus, slave, 0, &dev); |  | ||||||
| 	if (ret) |  | ||||||
| 		return NULL; |  | ||||||
| 
 |  | ||||||
| 	return dev; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static int gsc_read_eeprom(int bus, int slave, int alen, struct venice_board_info *info) |  | ||||||
| { |  | ||||||
| 	int i; |  | ||||||
| 	int chksum; |  | ||||||
| 	unsigned char *buf = (unsigned char *)info; |  | ||||||
| 	struct udevice *dev; |  | ||||||
| 	int ret; |  | ||||||
| 
 |  | ||||||
| 	/* probe device */ |  | ||||||
| 	dev = gsc_get_dev(bus, slave); |  | ||||||
| 	if (!dev) { |  | ||||||
| 		if (slave == GSC_EEPROM_ADDR) |  | ||||||
| 			puts("ERROR: Failed to probe EEPROM\n"); |  | ||||||
| 		return -ENODEV; |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	/* read eeprom config section */ |  | ||||||
| 	memset(info, 0, sizeof(*info)); |  | ||||||
| 	ret = i2c_set_chip_offset_len(dev, alen); |  | ||||||
| 	if (ret) { |  | ||||||
| 		puts("EEPROM: Failed to set alen\n"); |  | ||||||
| 		return ret; |  | ||||||
| 	} |  | ||||||
| 	ret = dm_i2c_read(dev, 0x00, buf, sizeof(*info)); |  | ||||||
| 	if (ret) { |  | ||||||
| 		if (slave == GSC_EEPROM_ADDR) |  | ||||||
| 			printf("EEPROM: Failed to read EEPROM\n"); |  | ||||||
| 		return ret; |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	/* validate checksum */ |  | ||||||
| 	for (chksum = 0, i = 0; i < (int)sizeof(*info) - 2; i++) |  | ||||||
| 		chksum += buf[i]; |  | ||||||
| 	if ((info->chksum[0] != chksum >> 8) || |  | ||||||
| 	    (info->chksum[1] != (chksum & 0xff))) { |  | ||||||
| 		printf("EEPROM: I2C%d@0x%02x: Invalid Checksum\n", bus, slave); |  | ||||||
| 		print_hex_dump_bytes("", DUMP_PREFIX_NONE, buf, sizeof(*info)); |  | ||||||
| 		memset(info, 0, sizeof(*info)); |  | ||||||
| 		return -EINVAL; |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	/* sanity check valid model */ |  | ||||||
| 	if (info->model[0] != 'G' || info->model[1] != 'W') { |  | ||||||
| 		printf("EEPROM: I2C%d@0x%02x: Invalid Model in EEPROM\n", bus, slave); |  | ||||||
| 		print_hex_dump_bytes("", DUMP_PREFIX_NONE, buf, sizeof(*info)); |  | ||||||
| 		memset(info, 0, sizeof(*info)); |  | ||||||
| 		return -EINVAL; |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	return 0; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static const char *gsc_get_rst_cause(struct udevice *dev) |  | ||||||
| { |  | ||||||
| 	static char str[64]; |  | ||||||
| 	static const char * const names[] = { |  | ||||||
| 		"VIN", |  | ||||||
| 		"PB", |  | ||||||
| 		"WDT", |  | ||||||
| 		"CPU", |  | ||||||
| 		"TEMP_L", |  | ||||||
| 		"TEMP_R", |  | ||||||
| 		"SLEEP", |  | ||||||
| 		"BOOT_WDT1", |  | ||||||
| 		"BOOT_WDT2", |  | ||||||
| 		"SOFT_PWR", |  | ||||||
| 	}; |  | ||||||
| 	unsigned char reg; |  | ||||||
| 
 |  | ||||||
| 	/* reset cause */ |  | ||||||
| 	str[0] = 0; |  | ||||||
| 	if (!dm_i2c_read(dev, GSC_SC_RST_CAUSE, ®, 1)) { |  | ||||||
| 		if (reg < ARRAY_SIZE(names)) |  | ||||||
| 			sprintf(str, "%s", names[reg]); |  | ||||||
| 		else |  | ||||||
| 			sprintf(str, "0x%02x", reg); |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	/* thermal protection */ |  | ||||||
| 	if (!dm_i2c_read(dev, GSC_SC_THERM_PROTECT, ®, 1)) { |  | ||||||
| 		strcat(str, " Thermal Protection "); |  | ||||||
| 		if (reg & BIT(0)) |  | ||||||
| 			strcat(str, "Enabled"); |  | ||||||
| 		else |  | ||||||
| 			strcat(str, "Disabled"); |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	return str; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| /* display hardware monitor ADC channels */ |  | ||||||
| int gsc_hwmon(void) |  | ||||||
| { |  | ||||||
| 	const void *fdt = gd->fdt_blob; |  | ||||||
| 	struct udevice *dev; |  | ||||||
| 	int node, reg, mode, len, val, offset; |  | ||||||
| 	const char *label; |  | ||||||
| 	u8 buf[2]; |  | ||||||
| 	int ret; |  | ||||||
| 
 |  | ||||||
| 	node = fdt_node_offset_by_compatible(fdt, -1, "gw,gsc-adc"); |  | ||||||
| 	if (node <= 0) |  | ||||||
| 		return node; |  | ||||||
| 
 |  | ||||||
| 	/* probe device */ |  | ||||||
| 	dev = gsc_get_dev(GSC_BUSNO, GSC_HWMON_ADDR); |  | ||||||
| 	if (!dev) { |  | ||||||
| 		puts("ERROR: Failed to probe GSC HWMON\n"); |  | ||||||
| 		return -ENODEV; |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	/* iterate over hwmon nodes */ |  | ||||||
| 	node = fdt_first_subnode(fdt, node); |  | ||||||
| 	while (node > 0) { |  | ||||||
| 		reg = fdtdec_get_int(fdt, node, "reg", -1); |  | ||||||
| 		mode = fdtdec_get_int(fdt, node, "gw,mode", -1); |  | ||||||
| 		offset = fdtdec_get_int(fdt, node, "gw,voltage-offset-microvolt", 0); |  | ||||||
| 		label = fdt_stringlist_get(fdt, node, "label", 0, NULL); |  | ||||||
| 
 |  | ||||||
| 		if ((reg == -1) || (mode == -1) || !label) |  | ||||||
| 			printf("invalid dt:%s\n", fdt_get_name(fdt, node, NULL)); |  | ||||||
| 
 |  | ||||||
| 		memset(buf, 0, sizeof(buf)); |  | ||||||
| 		ret = dm_i2c_read(dev, reg, buf, sizeof(buf)); |  | ||||||
| 		if (ret) { |  | ||||||
| 			printf("i2c error: %d\n", ret); |  | ||||||
| 			continue; |  | ||||||
| 		} |  | ||||||
| 		val = buf[0] | buf[1] << 8; |  | ||||||
| 		if (val >= 0) { |  | ||||||
| 			const u32 *div; |  | ||||||
| 			int r[2]; |  | ||||||
| 
 |  | ||||||
| 			switch (mode) { |  | ||||||
| 			case 0: /* temperature (C*10) */ |  | ||||||
| 				if (val > 0x8000) |  | ||||||
| 					val -= 0xffff; |  | ||||||
| 				printf("%-8s: %d.%ldC\n", label, val / 10, abs(val % 10)); |  | ||||||
| 				break; |  | ||||||
| 			case 1: /* prescaled voltage */ |  | ||||||
| 				if (val != 0xffff) |  | ||||||
| 					printf("%-8s: %d.%03dV\n", label, val / 1000, val % 1000); |  | ||||||
| 				break; |  | ||||||
| 			case 2: /* scaled based on ref volt and resolution */ |  | ||||||
| 				val *= 2500; |  | ||||||
| 				val /= 1 << 12; |  | ||||||
| 
 |  | ||||||
| 				/* apply pre-scaler voltage divider */ |  | ||||||
| 				div  = fdt_getprop(fdt, node, "gw,voltage-divider-ohms", &len); |  | ||||||
| 				if (div && (len == sizeof(uint32_t) * 2)) { |  | ||||||
| 					r[0] = fdt32_to_cpu(div[0]); |  | ||||||
| 					r[1] = fdt32_to_cpu(div[1]); |  | ||||||
| 					if (r[0] && r[1]) { |  | ||||||
| 						val *= (r[0] + r[1]); |  | ||||||
| 						val /= r[1]; |  | ||||||
| 					} |  | ||||||
| 				} |  | ||||||
| 
 |  | ||||||
| 				/* adjust by offset */ |  | ||||||
| 				val += (offset / 1000); |  | ||||||
| 
 |  | ||||||
| 				printf("%-8s: %d.%03dV\n", label, val / 1000, val % 1000); |  | ||||||
| 				break; |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 		node = fdt_next_subnode(fdt, node); |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	return 0; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| /* determine BOM revision from model */ |  | ||||||
| int get_bom_rev(const char *str) |  | ||||||
| { |  | ||||||
| 	int  rev_bom = 0; |  | ||||||
| 	int i; |  | ||||||
| 
 |  | ||||||
| 	for (i = strlen(str) - 1; i > 0; i--) { |  | ||||||
| 		if (str[i] == '-') |  | ||||||
| 			break; |  | ||||||
| 		if (str[i] >= '1' && str[i] <= '9') { |  | ||||||
| 			rev_bom = str[i] - '0'; |  | ||||||
| 			break; |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	return rev_bom; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| /* determine PCB revision from model */ |  | ||||||
| char get_pcb_rev(const char *str) |  | ||||||
| { |  | ||||||
| 	char rev_pcb = 'A'; |  | ||||||
| 	int i; |  | ||||||
| 
 |  | ||||||
| 	for (i = strlen(str) - 1; i > 0; i--) { |  | ||||||
| 		if (str[i] == '-') |  | ||||||
| 			break; |  | ||||||
| 		if (str[i] >= 'A') { |  | ||||||
| 			rev_pcb = str[i]; |  | ||||||
| 			break; |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	return rev_pcb; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| /*
 |  | ||||||
|  * get dt name based on model and detail level: |  | ||||||
|  * |  | ||||||
|  * For boards that are a combination of a SoM plus a Baseboard: |  | ||||||
|  *   Venice SoM part numbers are GW70xx where xx is: |  | ||||||
|  *    7000-7019: same PCB with som dt of '0x' |  | ||||||
|  *    7020-7039: same PCB with som dt of '2x' |  | ||||||
|  *    7040-7059: same PCB with som dt of '4x' |  | ||||||
|  *    7060-7079: same PCB with som dt of '6x' |  | ||||||
|  *    7080-7099: same PCB with som dt of '8x' |  | ||||||
|  *   Venice Baseboard part numbers are GW7xxx where xxx is: |  | ||||||
|  *    7100-7199: same PCB with base dt of '71xx' |  | ||||||
|  *    7200-7299: same PCB with base dt of '72xx' |  | ||||||
|  *    7300-7399: same PCB with base dt of '73xx' |  | ||||||
|  *    7400-7499: same PCB with base dt of '74xx' |  | ||||||
|  *    7500-7599: same PCB with base dt of '75xx' |  | ||||||
|  *    7600-7699: same PCB with base dt of '76xx' |  | ||||||
|  *    7700-7799: same PCB with base dt of '77xx' |  | ||||||
|  *    7800-7899: same PCB with base dt of '78xx' |  | ||||||
|  *   DT name is comprised of: |  | ||||||
|  *    gw<base dt>-<som dt>-[base-pcb-rev][base-bom-rev][som-pcb-rev][som-bom-rev] |  | ||||||
|  * |  | ||||||
|  * For board models from 7900-7999 each PCB is unique with its own dt: |  | ||||||
|  *   DT name is comprised: |  | ||||||
|  *    gw<model>-[pcb-rev][bom-rev] |  | ||||||
|  * |  | ||||||
|  */ |  | ||||||
| #define snprintfcat(dest, sz, fmt, ...) \ |  | ||||||
| 	snprintf((dest) + strlen(dest), (sz) - strlen(dest), fmt, ##__VA_ARGS__) |  | ||||||
| const char *gsc_get_dtb_name(int level, char *buf, int sz) |  | ||||||
| { |  | ||||||
| #ifdef CONFIG_IMX8MM |  | ||||||
| 	const char *pre = "imx8mm-venice-gw"; |  | ||||||
| #else |  | ||||||
| 	const char *pre = "imx8mn-venice-gw"; |  | ||||||
| #endif |  | ||||||
| 	int model, rev_pcb, rev_bom; |  | ||||||
| 
 |  | ||||||
| 	model = ((som_info.model[2] - '0') * 1000) |  | ||||||
| 		+ ((som_info.model[3] - '0') * 100) |  | ||||||
| 		+ ((som_info.model[4] - '0') * 10) |  | ||||||
| 		+ (som_info.model[5] - '0'); |  | ||||||
| 	rev_pcb = tolower(get_pcb_rev(som_info.model)); |  | ||||||
| 	rev_bom = get_bom_rev(som_info.model); |  | ||||||
| 
 |  | ||||||
| 	/* som + baseboard*/ |  | ||||||
| 	if (base_info.model[0]) { |  | ||||||
| 		/* baseboard id: 7100-7199->71; 7200-7299->72; etc */ |  | ||||||
| 		int base = ((base_info.model[2] - '0') * 10) + (base_info.model[3] - '0'); |  | ||||||
| 		/* som id: 7000-7019->1; 7020-7039->2; etc */ |  | ||||||
| 		int som = ((model % 100) / 20) * 2; |  | ||||||
| 		int rev_base_pcb = tolower(get_pcb_rev(base_info.model)); |  | ||||||
| 		int rev_base_bom = get_bom_rev(base_info.model); |  | ||||||
| 
 |  | ||||||
| 		snprintf(buf, sz, "%s%2dxx-%dx", pre, base, som); |  | ||||||
| 		switch (level) { |  | ||||||
| 		case 0: /* full model (ie gw73xx-0x-a1a1) */ |  | ||||||
| 			if (rev_base_bom) |  | ||||||
| 				snprintfcat(buf, sz, "-%c%d", rev_base_pcb, rev_base_bom); |  | ||||||
| 			else |  | ||||||
| 				snprintfcat(buf, sz, "-%c", rev_base_pcb); |  | ||||||
| 			if (rev_bom) |  | ||||||
| 				snprintfcat(buf, sz, "%c%d", rev_pcb, rev_bom); |  | ||||||
| 			else |  | ||||||
| 				snprintfcat(buf, sz, "%c", rev_pcb); |  | ||||||
| 			break; |  | ||||||
| 		case 1: /* don't care about SoM revision */ |  | ||||||
| 			if (rev_base_bom) |  | ||||||
| 				snprintfcat(buf, sz, "-%c%d", rev_base_pcb, rev_base_bom); |  | ||||||
| 			else |  | ||||||
| 				snprintfcat(buf, sz, "-%c", rev_base_pcb); |  | ||||||
| 			snprintfcat(buf, sz, "xx"); |  | ||||||
| 			break; |  | ||||||
| 		case 2: /* don't care about baseboard revision */ |  | ||||||
| 			snprintfcat(buf, sz, "-xx"); |  | ||||||
| 			if (rev_bom) |  | ||||||
| 				snprintfcat(buf, sz, "%c%d", rev_pcb, rev_bom); |  | ||||||
| 			else |  | ||||||
| 				snprintfcat(buf, sz, "%c", rev_pcb); |  | ||||||
| 			break; |  | ||||||
| 		case 3: /* don't care about SoM/baseboard revision */ |  | ||||||
| 			break; |  | ||||||
| 		default: |  | ||||||
| 			return NULL; |  | ||||||
| 		} |  | ||||||
| 	} else { |  | ||||||
| 		snprintf(buf, sz, "%s%04d", pre, model); |  | ||||||
| 		switch (level) { |  | ||||||
| 		case 0: /* full model wth PCB and BOM revision first (ie gw7901-a1) */ |  | ||||||
| 			if (rev_bom) |  | ||||||
| 				snprintfcat(buf, sz, "-%c%d", rev_pcb, rev_bom); |  | ||||||
| 			else |  | ||||||
| 				snprintfcat(buf, sz, "-%c", rev_pcb); |  | ||||||
| 			break; |  | ||||||
| 		case 1: /* don't care about BOM revision */ |  | ||||||
| 			snprintfcat(buf, sz, "-%c", rev_pcb); |  | ||||||
| 			break; |  | ||||||
| 		case 2: /* don't care about PCB or BOM revision */ |  | ||||||
| 			break; |  | ||||||
| 		default: |  | ||||||
| 			return NULL; |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	return buf; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static int gsc_read(void) |  | ||||||
| { |  | ||||||
| 	char rev_pcb; |  | ||||||
| 	int rev_bom; |  | ||||||
| 	int ret; |  | ||||||
| 
 |  | ||||||
| 	ret = gsc_read_eeprom(GSC_BUSNO, GSC_EEPROM_ADDR, 1, &som_info); |  | ||||||
| 	if (ret) { |  | ||||||
| 		memset(&som_info, 0, sizeof(som_info)); |  | ||||||
| 		return ret; |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	/* read optional baseboard EEPROM */ |  | ||||||
| 	gsc_read_eeprom(BASEBOARD_EEPROM_BUSNO, BASEBOARD_EEPROM_ADDR, |  | ||||||
| 			2, &base_info); |  | ||||||
| 
 |  | ||||||
| 	/* create model strings */ |  | ||||||
| 	if (base_info.model[0]) { |  | ||||||
| 		sprintf(venice_model, "GW%c%c%c%c-%c%c-", |  | ||||||
| 			som_info.model[2], /* family */ |  | ||||||
| 			base_info.model[3], /* baseboard */ |  | ||||||
| 			base_info.model[4], base_info.model[5], /* subload of baseboard */ |  | ||||||
| 			som_info.model[4], som_info.model[5]); /* last 2digits of SOM */ |  | ||||||
| 
 |  | ||||||
| 		/* baseboard revision */ |  | ||||||
| 		rev_pcb = get_pcb_rev(base_info.model); |  | ||||||
| 		rev_bom = get_bom_rev(base_info.model); |  | ||||||
| 		if (rev_bom) |  | ||||||
| 			sprintf(venice_model + strlen(venice_model), "%c%d", rev_pcb, rev_bom); |  | ||||||
| 		else |  | ||||||
| 			sprintf(venice_model + strlen(venice_model), "%c", rev_pcb); |  | ||||||
| 		/* som revision */ |  | ||||||
| 		rev_pcb = get_pcb_rev(som_info.model); |  | ||||||
| 		rev_bom = get_bom_rev(som_info.model); |  | ||||||
| 		if (rev_bom) |  | ||||||
| 			sprintf(venice_model + strlen(venice_model), "%c%d", rev_pcb, rev_bom); |  | ||||||
| 		else |  | ||||||
| 			sprintf(venice_model + strlen(venice_model), "%c", rev_pcb); |  | ||||||
| 	} else { |  | ||||||
| 		strcpy(venice_model, som_info.model); |  | ||||||
| 	} |  | ||||||
| 	venice_serial = som_info.serial; |  | ||||||
| 
 |  | ||||||
| 	return 0; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static int gsc_info(int verbose) |  | ||||||
| { |  | ||||||
| 	struct udevice *dev; |  | ||||||
| 	unsigned char buf[16]; |  | ||||||
| 
 |  | ||||||
| 	printf("Model   : %s\n", venice_model); |  | ||||||
| 	printf("Serial  : %d\n", som_info.serial); |  | ||||||
| 	printf("MFGDate : %02x-%02x-%02x%02x\n", |  | ||||||
| 	       som_info.mfgdate[0], som_info.mfgdate[1], |  | ||||||
| 	       som_info.mfgdate[2], som_info.mfgdate[3]); |  | ||||||
| 	if (base_info.model[0] && verbose > 1) { |  | ||||||
| 		printf("SOM     : %s %d %02x-%02x-%02x%02x\n", |  | ||||||
| 		       som_info.model, som_info.serial, |  | ||||||
| 		       som_info.mfgdate[0], som_info.mfgdate[1], |  | ||||||
| 		       som_info.mfgdate[2], som_info.mfgdate[3]); |  | ||||||
| 		printf("BASE    : %s %d %02x-%02x-%02x%02x\n", |  | ||||||
| 		       base_info.model, base_info.serial, |  | ||||||
| 		       base_info.mfgdate[0], base_info.mfgdate[1], |  | ||||||
| 		       base_info.mfgdate[2], base_info.mfgdate[3]); |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	/* Display RTC */ |  | ||||||
| 	puts("RTC     : "); |  | ||||||
| 	dev = gsc_get_dev(GSC_BUSNO, GSC_RTC_ADDR); |  | ||||||
| 	if (!dev) { |  | ||||||
| 		puts("Failed to probe GSC RTC\n"); |  | ||||||
| 	} else { |  | ||||||
| 		dm_i2c_read(dev, 0, buf, 6); |  | ||||||
| 		printf("%d\n", buf[0] | buf[1] << 8 | buf[2] << 16 | buf[3] << 24); |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	/* Display hwmon */ |  | ||||||
| 	gsc_hwmon(); |  | ||||||
| 
 |  | ||||||
| 	return 0; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| int gsc_init(int quiet) |  | ||||||
| { |  | ||||||
| 	unsigned char buf[16]; |  | ||||||
| 	struct udevice *dev; |  | ||||||
| 	int ret; |  | ||||||
| 
 |  | ||||||
| 	/*
 |  | ||||||
| 	 * On a board with a missing/depleted backup battery for GSC, the |  | ||||||
| 	 * board may be ready to probe the GSC before its firmware is |  | ||||||
| 	 * running.  We will wait here indefinately for the GSC/EEPROM. |  | ||||||
| 	 */ |  | ||||||
| #ifdef CONFIG_IMX8MN |  | ||||||
| 	// TODO:
 |  | ||||||
| 	//   IMX8MN boots quicker than IMX8MM and exposes issue
 |  | ||||||
| 	//   where because GSC I2C state machine isn't running and its
 |  | ||||||
| 	//   SCL/SDA are driven low spams i2c errors
 |  | ||||||
| 	//
 |  | ||||||
| 	//   Put a loop here that somehow waits for I2C CLK/DAT to be high
 |  | ||||||
| 	mdelay(40); |  | ||||||
| #endif |  | ||||||
| 	while (1) { |  | ||||||
| 		/* probe device */ |  | ||||||
| 		dev = gsc_get_dev(GSC_BUSNO, GSC_SC_ADDR); |  | ||||||
| 		if (dev) |  | ||||||
| 			break; |  | ||||||
| 		mdelay(1); |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	ret = dm_i2c_read(dev, 0, buf, sizeof(buf)); |  | ||||||
| 	if (ret) { |  | ||||||
| 		puts("ERROR: Failed reading GSC\n"); |  | ||||||
| 		return ret; |  | ||||||
| 	} |  | ||||||
| 	gsc_read(); |  | ||||||
| 
 |  | ||||||
| 	/* banner */ |  | ||||||
| 	if (!quiet) { |  | ||||||
| 		printf("GSC     : v%d 0x%04x", buf[GSC_SC_FWVER], |  | ||||||
| 		       buf[GSC_SC_FWCRC] | buf[GSC_SC_FWCRC + 1] << 8); |  | ||||||
| 		printf(" RST:%s", gsc_get_rst_cause(dev)); |  | ||||||
| 		printf("\n"); |  | ||||||
| 		gsc_info(1); |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	if (ret) |  | ||||||
| 		hang(); |  | ||||||
| 
 |  | ||||||
| 	return (16 << som_info.sdram_size); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| const char *gsc_get_model(void) |  | ||||||
| { |  | ||||||
| 	return venice_model; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| uint32_t gsc_get_serial(void) |  | ||||||
| { |  | ||||||
| 	return venice_serial; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| #if !(IS_ENABLED(CONFIG_SPL_BUILD)) |  | ||||||
| static int gsc_sleep(unsigned long secs) |  | ||||||
| { |  | ||||||
| 	unsigned char reg; |  | ||||||
| 	struct udevice *dev; |  | ||||||
| 	int ret; |  | ||||||
| 
 |  | ||||||
| 	/* probe device */ |  | ||||||
| 	dev = gsc_get_dev(GSC_BUSNO, GSC_SC_ADDR); |  | ||||||
| 	if (!dev) |  | ||||||
| 		return -ENODEV; |  | ||||||
| 
 |  | ||||||
| 	printf("GSC Sleeping for %ld seconds\n", secs); |  | ||||||
| 	reg = (secs >> 24) & 0xff; |  | ||||||
| 	ret = dm_i2c_write(dev, 9, ®, 1); |  | ||||||
| 	if (ret) |  | ||||||
| 		goto err; |  | ||||||
| 	reg = (secs >> 16) & 0xff; |  | ||||||
| 	ret = dm_i2c_write(dev, 8, ®, 1); |  | ||||||
| 	if (ret) |  | ||||||
| 		goto err; |  | ||||||
| 	reg = (secs >> 8) & 0xff; |  | ||||||
| 	ret = dm_i2c_write(dev, 7, ®, 1); |  | ||||||
| 	if (ret) |  | ||||||
| 		goto err; |  | ||||||
| 	reg = secs & 0xff; |  | ||||||
| 	ret = dm_i2c_write(dev, 6, ®, 1); |  | ||||||
| 	if (ret) |  | ||||||
| 		goto err; |  | ||||||
| 	ret = dm_i2c_read(dev, GSC_SC_CTRL1, ®, 1); |  | ||||||
| 	if (ret) |  | ||||||
| 		goto err; |  | ||||||
| 	reg |= (1 << 2); |  | ||||||
| 	ret = dm_i2c_write(dev, GSC_SC_CTRL1, ®, 1); |  | ||||||
| 	if (ret) |  | ||||||
| 		goto err; |  | ||||||
| 	reg &= ~(1 << 2); |  | ||||||
| 	reg |= 0x3; |  | ||||||
| 	ret = dm_i2c_write(dev, GSC_SC_CTRL1, ®, 1); |  | ||||||
| 	if (ret) |  | ||||||
| 		goto err; |  | ||||||
| 
 |  | ||||||
| 	return 0; |  | ||||||
| 
 |  | ||||||
| err: |  | ||||||
| 	printf("i2c error\n"); |  | ||||||
| 	return ret; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static int gsc_boot_wd_disable(void) |  | ||||||
| { |  | ||||||
| 	u8 reg; |  | ||||||
| 	struct udevice *dev; |  | ||||||
| 	int ret; |  | ||||||
| 
 |  | ||||||
| 	/* probe device */ |  | ||||||
| 	dev = gsc_get_dev(GSC_BUSNO, GSC_SC_ADDR); |  | ||||||
| 	if (!dev) |  | ||||||
| 		return -ENODEV; |  | ||||||
| 
 |  | ||||||
| 	ret = dm_i2c_read(dev, GSC_SC_CTRL1, ®, 1); |  | ||||||
| 	if (ret) |  | ||||||
| 		goto err; |  | ||||||
| 	reg |= (1 << GSC_SC_CTRL1_WDDIS); |  | ||||||
| 	reg &= ~(1 << GSC_SC_CTRL1_BOOT_CHK); |  | ||||||
| 	ret = dm_i2c_write(dev, GSC_SC_CTRL1, ®, 1); |  | ||||||
| 	if (ret) |  | ||||||
| 		goto err; |  | ||||||
| 	puts("GSC     : boot watchdog disabled\n"); |  | ||||||
| 
 |  | ||||||
| 	return 0; |  | ||||||
| 
 |  | ||||||
| err: |  | ||||||
| 	printf("i2c error"); |  | ||||||
| 	return ret; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static int do_gsc(struct cmd_tbl *cmdtp, int flag, int argc, char * const argv[]) |  | ||||||
| { |  | ||||||
| 	if (argc < 2) |  | ||||||
| 		return gsc_info(2); |  | ||||||
| 
 |  | ||||||
| 	if (strcasecmp(argv[1], "sleep") == 0) { |  | ||||||
| 		if (argc < 3) |  | ||||||
| 			return CMD_RET_USAGE; |  | ||||||
| 		if (!gsc_sleep(dectoul(argv[2], NULL))) |  | ||||||
| 			return CMD_RET_SUCCESS; |  | ||||||
| 	} else if (strcasecmp(argv[1], "hwmon") == 0) { |  | ||||||
| 		if (!gsc_hwmon()) |  | ||||||
| 			return CMD_RET_SUCCESS; |  | ||||||
| 	} else if (strcasecmp(argv[1], "wd-disable") == 0) { |  | ||||||
| 		if (!gsc_boot_wd_disable()) |  | ||||||
| 			return CMD_RET_SUCCESS; |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	return CMD_RET_USAGE; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| U_BOOT_CMD(gsc, 4, 1, do_gsc, "Gateworks System Controller", |  | ||||||
| 	   "[sleep <secs>]|[hwmon]|[wd-disable]\n"); |  | ||||||
| #endif |  | ||||||
|  | @ -7,13 +7,9 @@ | ||||||
| #include <cpu_func.h> | #include <cpu_func.h> | ||||||
| #include <hang.h> | #include <hang.h> | ||||||
| #include <i2c.h> | #include <i2c.h> | ||||||
| #include <image.h> |  | ||||||
| #include <init.h> | #include <init.h> | ||||||
| #include <log.h> |  | ||||||
| #include <spl.h> | #include <spl.h> | ||||||
| #include <asm/io.h> |  | ||||||
| #include <asm/mach-imx/gpio.h> | #include <asm/mach-imx/gpio.h> | ||||||
| #include <asm/mach-imx/iomux-v3.h> |  | ||||||
| #include <asm/arch/clock.h> | #include <asm/arch/clock.h> | ||||||
| #include <asm/arch/imx8mm_pins.h> | #include <asm/arch/imx8mm_pins.h> | ||||||
| #include <asm/arch/imx8mn_pins.h> | #include <asm/arch/imx8mn_pins.h> | ||||||
|  | @ -21,22 +17,17 @@ | ||||||
| #include <asm/mach-imx/boot_mode.h> | #include <asm/mach-imx/boot_mode.h> | ||||||
| #include <asm/arch/ddr.h> | #include <asm/arch/ddr.h> | ||||||
| #include <asm-generic/gpio.h> | #include <asm-generic/gpio.h> | ||||||
| 
 |  | ||||||
| #include <dm/uclass.h> | #include <dm/uclass.h> | ||||||
| #include <dm/device.h> | #include <dm/device.h> | ||||||
| #include <dm/uclass-internal.h> | #include <linux/delay.h> | ||||||
| #include <dm/device-internal.h> |  | ||||||
| 
 |  | ||||||
| #include <power/bd71837.h> | #include <power/bd71837.h> | ||||||
| #include <power/mp5416.h> | #include <power/mp5416.h> | ||||||
| 
 | 
 | ||||||
| #include "gsc.h" | #include "eeprom.h" | ||||||
| #include "lpddr4_timing.h" | #include "lpddr4_timing.h" | ||||||
| 
 | 
 | ||||||
| #define PCIE_RSTN IMX_GPIO_NR(4, 6) | #define PCIE_RSTN IMX_GPIO_NR(4, 6) | ||||||
| 
 | 
 | ||||||
| DECLARE_GLOBAL_DATA_PTR; |  | ||||||
| 
 |  | ||||||
| static void spl_dram_init(int size) | static void spl_dram_init(int size) | ||||||
| { | { | ||||||
| 	struct dram_timing_info *dram_timing; | 	struct dram_timing_info *dram_timing; | ||||||
|  | @ -65,8 +56,8 @@ static void spl_dram_init(int size) | ||||||
| 		dram_timing = &dram_timing_1gb_single_die; | 		dram_timing = &dram_timing_1gb_single_die; | ||||||
| 		break; | 		break; | ||||||
| 	case 2048: | 	case 2048: | ||||||
| 		if (!strcmp(gsc_get_model(), "GW7902-SP466-A") || | 		if (!strcmp(eeprom_get_model(), "GW7902-SP466-A") || | ||||||
| 		    !strcmp(gsc_get_model(), "GW7902-SP466-B")) { | 		    !strcmp(eeprom_get_model(), "GW7902-SP466-B")) { | ||||||
| 			dram_timing = &dram_timing_2gb_dual_die; | 			dram_timing = &dram_timing_2gb_dual_die; | ||||||
| 		} else { | 		} else { | ||||||
| 			dram_timing = &dram_timing_2gb_single_die; | 			dram_timing = &dram_timing_2gb_single_die; | ||||||
|  | @ -149,7 +140,7 @@ static int dm_i2c_clrsetbits(struct udevice *dev, uint reg, uint clr, uint set) | ||||||
| 
 | 
 | ||||||
| static int power_init_board(void) | static int power_init_board(void) | ||||||
| { | { | ||||||
| 	const char *model = gsc_get_model(); | 	const char *model = eeprom_get_model(); | ||||||
| 	struct udevice *bus; | 	struct udevice *bus; | ||||||
| 	struct udevice *dev; | 	struct udevice *dev; | ||||||
| 	int ret; | 	int ret; | ||||||
|  | @ -243,22 +234,36 @@ void board_init_f(ulong dummy) | ||||||
| 		hang(); | 		hang(); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	ret = uclass_get_device_by_name(UCLASS_CLK, |  | ||||||
| 					"clock-controller@30380000", |  | ||||||
| 					&dev); |  | ||||||
| 	if (ret < 0) { |  | ||||||
| 		printf("Failed to find clock node. Check device tree\n"); |  | ||||||
| 		hang(); |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	enable_tzc380(); | 	enable_tzc380(); | ||||||
| 
 | 
 | ||||||
| 	/* need to hold PCIe switch in reset otherwise it can lock i2c bus EEPROM is on */ | 	/* need to hold PCIe switch in reset otherwise it can lock i2c bus EEPROM is on */ | ||||||
| 	gpio_request(PCIE_RSTN, "perst#"); | 	gpio_request(PCIE_RSTN, "perst#"); | ||||||
| 	gpio_direction_output(PCIE_RSTN, 0); | 	gpio_direction_output(PCIE_RSTN, 0); | ||||||
| 
 | 
 | ||||||
| 	/* GSC */ | 	/*
 | ||||||
| 	dram_sz = gsc_init(0); | 	 * probe GSC device | ||||||
|  | 	 * | ||||||
|  | 	 * On a board with a missing/depleted backup battery for GSC, the | ||||||
|  | 	 * board may be ready to probe the GSC before its firmware is | ||||||
|  | 	 * running. We will wait here indefinately for the GSC EEPROM. | ||||||
|  | 	 */ | ||||||
|  | #ifdef CONFIG_IMX8MN | ||||||
|  | 	/*
 | ||||||
|  | 	 * IMX8MN boots quicker than IMX8MM and exposes issue | ||||||
|  | 	 * where because GSC I2C state machine isn't running and its | ||||||
|  | 	 * SCL/SDA are driven low the I2C driver spams 'Arbitration lost' | ||||||
|  | 	 * I2C errors. | ||||||
|  | 	 * | ||||||
|  | 	 * TODO: Put a loop here that somehow waits for I2C CLK/DAT to be high | ||||||
|  | 	 */ | ||||||
|  | 	mdelay(50); | ||||||
|  | #endif | ||||||
|  | 	while (1) { | ||||||
|  | 		if (!uclass_get_device_by_driver(UCLASS_MISC, DM_DRIVER_GET(gsc), &dev)) | ||||||
|  | 			break; | ||||||
|  | 		mdelay(1); | ||||||
|  | 	} | ||||||
|  | 	dram_sz = eeprom_init(0); | ||||||
| 
 | 
 | ||||||
| 	/* PMIC */ | 	/* PMIC */ | ||||||
| 	power_init_board(); | 	power_init_board(); | ||||||
|  |  | ||||||
|  | @ -3,21 +3,12 @@ | ||||||
|  * Copyright 2021 Gateworks Corporation |  * Copyright 2021 Gateworks Corporation | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| #include <common.h> |  | ||||||
| #include <init.h> | #include <init.h> | ||||||
| #include <led.h> | #include <led.h> | ||||||
| #include <linux/delay.h> |  | ||||||
| #include <miiphy.h> | #include <miiphy.h> | ||||||
| #include <netdev.h> |  | ||||||
| 
 |  | ||||||
| #include <asm/arch/clock.h> |  | ||||||
| #include <asm/arch/sys_proto.h> | #include <asm/arch/sys_proto.h> | ||||||
| #include <asm/io.h> |  | ||||||
| #include <asm/unaligned.h> |  | ||||||
| 
 | 
 | ||||||
| #include "gsc.h" | #include "eeprom.h" | ||||||
| 
 |  | ||||||
| DECLARE_GLOBAL_DATA_PTR; |  | ||||||
| 
 | 
 | ||||||
| int board_phys_sdram_size(phys_size_t *size) | int board_phys_sdram_size(phys_size_t *size) | ||||||
| { | { | ||||||
|  | @ -37,7 +28,7 @@ int board_fit_config_name_match(const char *name) | ||||||
| 	char buf[32]; | 	char buf[32]; | ||||||
| 
 | 
 | ||||||
| 	do { | 	do { | ||||||
| 		dtb = gsc_get_dtb_name(i++, buf, sizeof(buf)); | 		dtb = eeprom_get_dtb_name(i++, buf, sizeof(buf)); | ||||||
| 		if (!strcmp(dtb, name)) { | 		if (!strcmp(dtb, name)) { | ||||||
| 			if (!init++) | 			if (!init++) | ||||||
| 				printf("DTB     : %s\n", name); | 				printf("DTB     : %s\n", name); | ||||||
|  | @ -100,13 +91,11 @@ int board_phy_config(struct phy_device *phydev) | ||||||
| 
 | 
 | ||||||
| int board_init(void) | int board_init(void) | ||||||
| { | { | ||||||
| 	gsc_init(1); | 	eeprom_init(1); | ||||||
| 
 | 
 | ||||||
| 	if (IS_ENABLED(CONFIG_FEC_MXC)) | 	if (IS_ENABLED(CONFIG_FEC_MXC)) | ||||||
| 		setup_fec(); | 		setup_fec(); | ||||||
| 
 | 
 | ||||||
| 	gsc_hwmon(); |  | ||||||
| 
 |  | ||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -122,13 +111,13 @@ int board_late_init(void) | ||||||
| 
 | 
 | ||||||
| 	/* Set board serial/model */ | 	/* Set board serial/model */ | ||||||
| 	if (!env_get("serial#")) | 	if (!env_get("serial#")) | ||||||
| 		env_set_ulong("serial#", gsc_get_serial()); | 		env_set_ulong("serial#", eeprom_get_serial()); | ||||||
| 	env_set("model", gsc_get_model()); | 	env_set("model", eeprom_get_model()); | ||||||
| 
 | 
 | ||||||
| 	/* Set fdt_file vars */ | 	/* Set fdt_file vars */ | ||||||
| 	i = 0; | 	i = 0; | ||||||
| 	do { | 	do { | ||||||
| 		str = gsc_get_dtb_name(i, fdt, sizeof(fdt)); | 		str = eeprom_get_dtb_name(i, fdt, sizeof(fdt)); | ||||||
| 		if (str) { | 		if (str) { | ||||||
| 			sprintf(env, "fdt_file%d", i + 1); | 			sprintf(env, "fdt_file%d", i + 1); | ||||||
| 			strcat(fdt, ".dtb"); | 			strcat(fdt, ".dtb"); | ||||||
|  | @ -146,7 +135,7 @@ int board_late_init(void) | ||||||
| 			sprintf(env, "ethaddr"); | 			sprintf(env, "ethaddr"); | ||||||
| 		str = env_get(env); | 		str = env_get(env); | ||||||
| 		if (!str) { | 		if (!str) { | ||||||
| 			ret = gsc_getmac(i, enetaddr); | 			ret = eeprom_getmac(i, enetaddr); | ||||||
| 			if (!ret) | 			if (!ret) | ||||||
| 				eth_env_set_enetaddr(env, enetaddr); | 				eth_env_set_enetaddr(env, enetaddr); | ||||||
| 		} | 		} | ||||||
|  | @ -166,7 +155,7 @@ int ft_board_setup(void *blob, struct bd_info *bd) | ||||||
| 	int off; | 	int off; | ||||||
| 
 | 
 | ||||||
| 	/* set board model dt prop */ | 	/* set board model dt prop */ | ||||||
| 	fdt_setprop_string(blob, 0, "board", gsc_get_model()); | 	fdt_setprop_string(blob, 0, "board", eeprom_get_model()); | ||||||
| 
 | 
 | ||||||
| 	/* update temp thresholds */ | 	/* update temp thresholds */ | ||||||
| 	off = fdt_path_offset(blob, "/thermal-zones/cpu-thermal/trips"); | 	off = fdt_path_offset(blob, "/thermal-zones/cpu-thermal/trips"); | ||||||
|  |  | ||||||
|  | @ -13,6 +13,7 @@ CONFIG_SPL_TEXT_BASE=0x912000 | ||||||
| CONFIG_TARGET_IMX8MN_VENICE=y | CONFIG_TARGET_IMX8MN_VENICE=y | ||||||
| CONFIG_SPL_MMC=y | CONFIG_SPL_MMC=y | ||||||
| CONFIG_SPL_SERIAL=y | CONFIG_SPL_SERIAL=y | ||||||
|  | CONFIG_SPL_DRIVERS_MISC=y | ||||||
| CONFIG_SPL=y | CONFIG_SPL=y | ||||||
| CONFIG_ENV_OFFSET_REDUND=0xff8000 | CONFIG_ENV_OFFSET_REDUND=0xff8000 | ||||||
| CONFIG_SPL_IMX_ROMAPI_LOADADDR=0x48000000 | CONFIG_SPL_IMX_ROMAPI_LOADADDR=0x48000000 | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue