From 00ec2a54f729d1a464afc6a95f6b516e50419293 Mon Sep 17 00:00:00 2001
From: Robert Nelson <robertcnelson@gmail.com>
Date: Tue, 14 Aug 2018 21:00:21 -0500
Subject: [PATCH] U-Boot: BeagleBone Cape Manager

Signed-off-by: Robert Nelson <robertcnelson@gmail.com>
---
 arch/arm/mach-omap2/am33xx/clock_am33xx.c |   1 +
 board/ti/am335x/board.c                   | 462 ++++++++++++++++++++++
 board/ti/am335x/board.h                   |  17 +
 board/ti/am335x/hash-string.h             |  59 +++
 board/ti/am335x/mux.c                     |  15 +
 include/configs/ti_armv7_common.h         | 219 ++++++++++
 include/configs/ti_armv7_omap.h           |   3 +
 include/environment/ti/mmc.h              |  15 +
 8 files changed, 791 insertions(+)
 create mode 100644 board/ti/am335x/hash-string.h

diff --git a/arch/arm/mach-omap2/am33xx/clock_am33xx.c b/arch/arm/mach-omap2/am33xx/clock_am33xx.c
index 32cdf63..fb871c2 100644
--- a/arch/arm/mach-omap2/am33xx/clock_am33xx.c
+++ b/arch/arm/mach-omap2/am33xx/clock_am33xx.c
@@ -220,6 +220,7 @@ void enable_basic_clocks(void)
 		&cmper->gpio2clkctrl,
 		&cmper->gpio3clkctrl,
 		&cmper->i2c1clkctrl,
+		&cmper->i2c2clkctrl,
 		&cmper->cpgmac0clkctrl,
 		&cmper->spi0clkctrl,
 		&cmrtc->rtcclkctrl,
diff --git a/board/ti/am335x/board.c b/board/ti/am335x/board.c
index ca03925..e2ee1fc 100644
--- a/board/ti/am335x/board.c
+++ b/board/ti/am335x/board.c
@@ -39,6 +39,7 @@
 #include <environment.h>
 #include "../common/board_detect.h"
 #include "board.h"
+#include "hash-string.h"
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -76,9 +77,462 @@ void do_board_detect(void)
 	if (ti_i2c_eeprom_am_get(CONFIG_EEPROM_BUS_ADDRESS,
 				 CONFIG_EEPROM_CHIP_ADDRESS))
 		printf("ti_i2c_eeprom_init failed\n");
+
+	//hack-ish, needs to mux'ed early, in do_cape_detect was too late...
+	enable_i2c2_pin_mux();
+	i2c_init(CONFIG_SYS_OMAP24_I2C_SPEED2, CONFIG_SYS_OMAP24_I2C_SLAVE2);
 }
 #endif
 
+#define CAPE_EEPROM_ADDR0	0x54
+#define CAPE_EEPROM_ADDR1	0x55
+#define CAPE_EEPROM_ADDR2	0x56
+#define CAPE_EEPROM_ADDR3	0x57
+
+void write_hex (unsigned char i)
+{
+	char cc;
+
+	cc = i >> 4;
+	cc &= 0xf;
+	if (cc > 9)
+		serial_putc (cc + 55);
+	else
+		serial_putc (cc + 48);
+	cc = i & 0xf;
+	if (cc > 9)
+		serial_putc (cc + 55);
+	else
+		serial_putc (cc + 48);
+}
+
+#define NOT_POP		0x0
+#define PINS_TAKEN	0x0
+
+#define UNK_BASE_DTB	0x0
+#define BB_BASE_DTB	0x1
+#define BBB_BASE_DTB	0x2
+#define BBGW_BASE_DTB	0x3
+#define BBBL_BASE_DTB	0x4
+#define BBE_BASE_DTB	0x5
+
+#define BBB_EMMC	0x1
+
+#define BBB_TDA998X_AUDIO	0x1
+#define BBB_TDA998X_NAUDIO	0x2
+#define BBB_ADV7511_AUDIO	0x3
+#define BBB_ADV7511_NAUDIO	0x4
+
+#define BBB_ADC		0x1
+
+#define BBBW_WL1835	0x1
+#define BBGW_WL1835	0x2
+
+#define CAPE_UNIVERSAL	0x0
+#define CAPE_UNIVERSAL_BBB	0x01
+#define CAPE_UNIVERSAL_BBG	0x02
+#define CAPE_UNIVERSAL_BBGW	0x03
+
+#define M_BBG1	0x01
+#define M_OS00	0x02
+
+static int probe_cape_eeprom(struct am335x_cape_eeprom_id *cape_header)
+{
+	unsigned char addr;
+	/* /lib/firmware/BB-CAPE-DISP-CT4-00A0.dtbo */
+	/* 14 + 16 + 1 + 4 + 5 = 40 */
+	char cape_overlay[40];
+	char process_cape_part_number[16];
+	char end_part_number;
+	char cape_overlay_pass_to_kernel[18];
+
+	//Don't forget about the BeagleBone Classic (White)
+	char base_dtb=UNK_BASE_DTB;
+	char virtual_emmc=NOT_POP;
+	char virtual_video=NOT_POP;
+	char virtual_audio=NOT_POP;
+	char virtual_wireless=NOT_POP;
+	char cape_universal=CAPE_UNIVERSAL;
+	char virtual_adc=NOT_POP;
+	char model=NOT_POP;
+
+	char *name = NULL;
+
+	if (board_is_bone_lt()) {
+		puts("BeagleBone Black:\n");
+		base_dtb=BBB_BASE_DTB;
+		virtual_emmc=BBB_EMMC;
+		virtual_video=BBB_TDA998X_AUDIO;
+		virtual_audio=BBB_TDA998X_AUDIO;
+		virtual_wireless=NOT_POP;
+		virtual_adc=BBB_ADC;
+		cape_universal=CAPE_UNIVERSAL_BBB;
+		name = "A335BNLT";
+
+		if (!strncmp(board_ti_get_rev(), "BLA", 3)) {
+			puts("Model: BeagleBoard.org BeagleBone Blue:\n");
+			/* Special case */
+			base_dtb=BBBL_BASE_DTB;
+			virtual_emmc=NOT_POP;
+			virtual_video=NOT_POP;
+			virtual_audio=NOT_POP;
+			virtual_wireless=NOT_POP;
+			virtual_adc=BBB_ADC;
+			cape_universal=CAPE_UNIVERSAL;
+			name = "BBBL";
+		}
+		if (!strncmp(board_ti_get_rev(), "BW", 2)) {
+			puts("Model: BeagleBoard.org BeagleBone Black Wireless:\n");
+			virtual_wireless=BBBW_WL1835;
+			name = "BBBW";
+		}
+		if (!strncmp(board_ti_get_rev(), "BBG", 3)) {
+			/* catches again in board_is_bbg1() */
+			//puts("Model: SeeedStudio BeagleBone Green:\n");
+			virtual_video=NOT_POP;
+			virtual_audio=NOT_POP;
+			cape_universal=CAPE_UNIVERSAL_BBG;
+			name = "BBG1";
+			model=M_BBG1;
+		}
+		if (!strncmp(board_ti_get_rev(), "GW1", 3)) {
+			puts("Model: SeeedStudio BeagleBone Green Wireless:\n");
+			base_dtb=BBGW_BASE_DTB;
+			virtual_video=NOT_POP;
+			virtual_audio=NOT_POP;
+			virtual_wireless=BBGW_WL1835;
+			cape_universal=CAPE_UNIVERSAL_BBGW;
+		}
+		if (!strncmp(board_ti_get_rev(), "AIA", 3)) {
+			puts("Model: Arrow BeagleBone Black Industrial:\n");
+			virtual_video=BBB_ADV7511_AUDIO;
+			virtual_audio=BBB_ADV7511_AUDIO;
+			cape_universal=CAPE_UNIVERSAL;
+		}
+		if (!strncmp(board_ti_get_rev(), "EIA", 3)) {
+			puts("Model: Element14 BeagleBone Black Industrial:\n");
+		}
+		if (!strncmp(board_ti_get_rev(), "SE", 2)) {
+			puts("Model: SanCloud BeagleBone Enhanced:\n");
+			base_dtb=BBE_BASE_DTB;
+			cape_universal=CAPE_UNIVERSAL_BBB;
+			name = "SBBE";
+		}
+		if (!strncmp(board_ti_get_rev(), "ME0", 3)) {
+			puts("Model: MENTOREL BeagleBone uSomIQ:\n");
+			virtual_video=NOT_POP;
+			virtual_audio=NOT_POP;
+			cape_universal=CAPE_UNIVERSAL_BBG;
+		}
+		if (!strncmp(board_ti_get_rev(), "NAD", 3)) {
+			puts("Model: Neuromeka BeagleBone Air:\n");
+			cape_universal=CAPE_UNIVERSAL;
+		}
+		if (!strncmp(board_ti_get_rev(), "OS0", 3)) {
+			puts("Model: Octavo Systems OSD3358-SM-RED:\n");
+			name = "OS00";
+			cape_universal=NOT_POP;
+			model=M_OS00;
+		}
+	}
+
+	if (board_is_bone()) {
+		puts("Model: BeagleBone:\n");
+		base_dtb=BB_BASE_DTB;
+		virtual_emmc=NOT_POP;
+		virtual_video=NOT_POP;
+		virtual_audio=NOT_POP;
+		virtual_wireless=NOT_POP;
+		virtual_adc=BBB_ADC;
+		cape_universal=CAPE_UNIVERSAL_BBB;
+		name = "A335BONE";
+	}
+
+	if (board_is_bbg1()) {
+		puts("Model: SeeedStudio BeagleBone Green:\n");
+		base_dtb=BBB_BASE_DTB;
+		virtual_emmc=BBB_EMMC;
+		virtual_video=NOT_POP;
+		virtual_audio=NOT_POP;
+		virtual_wireless=NOT_POP;
+		virtual_adc=BBB_ADC;
+		cape_universal=CAPE_UNIVERSAL_BBG;
+		name = "BBG1";
+		model=M_BBG1;
+	}
+
+	set_board_info_env(name);
+
+	i2c_set_bus_num(2);
+	strlcpy(cape_overlay_pass_to_kernel, "", 1);
+
+	for ( addr = CAPE_EEPROM_ADDR0; addr <= CAPE_EEPROM_ADDR3; addr++ ) {
+		if (i2c_probe(addr)) {
+			puts("BeagleBone: cape eeprom: i2c_probe: 0x");  write_hex(addr); puts(":\n");
+		} else {
+			/* read the eeprom using i2c */
+			if (i2c_read(addr, 0, 2, (uchar *)cape_header,
+				     sizeof(struct am335x_cape_eeprom_id))) {
+				puts("BeagleBone: cape eeprom: Could not read the EEPROM; something fundamentally"
+					" wrong on the I2C bus.\n");
+				return -EIO;
+			}
+
+			if (cape_header->header == 0xEE3355AA) {
+				strlcpy(cape_overlay, "/lib/firmware/", 14 + 1);
+				strlcpy(cape_overlay_pass_to_kernel, "", 2);
+				strlcpy(process_cape_part_number, "...............", 16 + 1);
+
+				strlcpy(process_cape_part_number, cape_header->part_number, 16 + 1);
+				printf("debug: process_cape_part_number:[%s]\n", process_cape_part_number);
+
+				//FIXME: some capes end with '.'
+				if ( process_cape_part_number[15] == 0x2E ) {
+					puts("debug: fixup, extra . in eeprom field\n");
+					process_cape_part_number[15] = 0x00;
+					if ( process_cape_part_number[14] == 0x2E ) {
+						process_cape_part_number[14] = 0x00;
+					}
+				}
+
+				//Find ending 0x00
+				puts("debug: process_cape_part_number:[");
+				end_part_number=16;
+				for ( int i=0; i <= 16; i++ ) {
+					if ( process_cape_part_number[i] == 0x00 ) {
+						end_part_number=i;
+						i=17;
+					} else {
+						write_hex(process_cape_part_number[i]);
+					}
+				}
+				puts("]\n");
+
+				strncat(cape_overlay, process_cape_part_number, end_part_number);
+				//printf("debug: %s\n", cape_overlay);
+
+				strncat(cape_overlay, "-", 1);
+				//printf("debug: %s\n", cape_overlay);
+
+				strncat(cape_overlay, cape_header->version, 4);
+				//printf("debug: %s\n", cape_overlay);
+
+				strncat(cape_overlay, ".dtbo", 5);
+				//printf("debug: %s\n", cape_overlay);
+
+				unsigned long cape_overlay_hash = hash_string(cape_overlay);
+
+				puts("BeagleBone: cape eeprom: i2c_probe: 0x");
+				write_hex(addr);
+				printf(": %s [0x%lx]\n", cape_overlay, cape_overlay_hash);
+
+				strncat(cape_overlay_pass_to_kernel, process_cape_part_number, end_part_number);
+				strncat(cape_overlay_pass_to_kernel, ",", 1);
+
+				switch(cape_overlay_hash) {
+					case 0x3c766f: /* /lib/firmware/BB-CAPE-DISP-CT4-00A0.dtbo */
+						virtual_video=PINS_TAKEN;
+						break;
+					case 0x24f51cf: /* /lib/firmware/BB-BONE-CAM-VVDN-00A0.dtbo */
+						virtual_emmc=PINS_TAKEN;
+						break;
+					case 0x4b0c13f: /* /lib/firmware/NL-AB-BBCL-00B0.dtbo */
+						virtual_video=PINS_TAKEN;
+						break;
+					case 0x74e7bbf: /* /lib/firmware/bb-justboom-dac-00A0.dtbo */
+						virtual_audio=PINS_TAKEN;
+						break;
+					case 0x93b574f: /* /lib/firmware/BB-GREEN-HDMI-00A0.dtbo */
+						virtual_video=PINS_TAKEN;
+						break;
+					case 0xb1b7bbf: /* /lib/firmware/bb-justboom-amp-00A0.dtbo */
+						virtual_audio=PINS_TAKEN;
+						break;
+					//d15bb
+					case 0xd15b80f: /* /lib/firmware/DLPDLCR2000-00A0.dtbo */
+						virtual_video=PINS_TAKEN;
+						break;
+					case 0xd4c9eff: /* /lib/firmware/bb-justboom-digi-00A0.dtbo */
+						virtual_audio=PINS_TAKEN;
+						break;
+					case 0xe3f55df: /* /lib/firmware/BB-BONE-NH7C-01-A0.dtbo */
+						virtual_video=PINS_TAKEN;
+						break;
+					case 0xfc93c8f: /* /lib/firmware/BB-BONE-LCD7-01-00A3.dtbo */
+						virtual_video=PINS_TAKEN;
+						virtual_adc=PINS_TAKEN;
+						break;
+					//fe131
+					case 0xfe1313f: /* /lib/firmware/BB-BONE-4D5R-01-00A1.dtbo */
+						virtual_video=PINS_TAKEN;
+						break;
+					//fe132
+					case 0xfe1323f: /* /lib/firmware/BB-BONE-4D4R-01-00A1.dtbo */
+						virtual_video=PINS_TAKEN;
+						break;
+					case 0xfe1327f: /* /lib/firmware/BB-BONE-4D4N-01-00A1.dtbo */
+						virtual_video=PINS_TAKEN;
+						break;
+					case 0xfe132cf: /* /lib/firmware/BB-BONE-4D4C-01-00A1.dtbo */
+						virtual_video=PINS_TAKEN;
+						break;
+					//fe133
+					case 0xfe1337f: /* /lib/firmware/BB-BONE-4D7N-01-00A1.dtbo */
+						virtual_video=PINS_TAKEN;
+						break;
+					case 0xfe133cf: /* /lib/firmware/BB-BONE-4D7C-01-00A1.dtbo */
+						virtual_video=PINS_TAKEN;
+						break;
+					//fe135
+					case 0xfe1357f: /* /lib/firmware/BB-BONE-4D5N-01-00A1.dtbo */
+						virtual_video=PINS_TAKEN;
+						break;
+					case 0xfe135cf: /* /lib/firmware/BB-BONE-4D5C-01-00A1.dtbo */
+						virtual_video=PINS_TAKEN;
+						break;
+					//fe137
+					case 0xfe1373f: /* /lib/firmware/BB-BONE-4D7R-01-00A1.dtbo */
+						virtual_video=PINS_TAKEN;
+						break;
+					case 0xfe93c1f: /* /lib/firmware/BB-BONE-LCD4-01-00A1.dtbo */
+						virtual_video=PINS_TAKEN;
+						virtual_adc=PINS_TAKEN;
+						break;
+				}
+
+				switch(addr) {
+					case CAPE_EEPROM_ADDR0:
+						env_set("uboot_overlay_addr0", cape_overlay);
+						env_set("uboot_detected_capes_addr0", cape_overlay_pass_to_kernel);
+						break;
+					case CAPE_EEPROM_ADDR1:
+						env_set("uboot_overlay_addr1", cape_overlay);
+						env_set("uboot_detected_capes_addr1", cape_overlay_pass_to_kernel);
+						break;
+					case CAPE_EEPROM_ADDR2:
+						env_set("uboot_overlay_addr2", cape_overlay);
+						env_set("uboot_detected_capes_addr2", cape_overlay_pass_to_kernel);
+						break;
+					case CAPE_EEPROM_ADDR3:
+						env_set("uboot_overlay_addr3", cape_overlay);
+						env_set("uboot_detected_capes_addr3", cape_overlay_pass_to_kernel);
+						break;
+				}
+				env_set("uboot_detected_capes", "1");
+			} else {
+				puts("BeagleBone: found invalid cape eeprom: i2c_probe: 0x");  write_hex(addr); puts(":\n");
+			}
+		}
+	}//for
+
+	switch(base_dtb) {
+		case BB_BASE_DTB:
+			env_set("uboot_base_dtb_univ", "am335x-bone-uboot-univ.dtb");
+			env_set("uboot_base_dtb", "am335x-bone.dtb");
+			env_set("uboot_try_cape_universal", "1");
+			break;
+		case BBB_BASE_DTB:
+			env_set("uboot_base_dtb_univ", "am335x-boneblack-uboot-univ.dtb");
+			env_set("uboot_base_dtb", "am335x-boneblack-uboot.dtb");
+			env_set("uboot_try_cape_universal", "1");
+			break;
+		case BBGW_BASE_DTB:
+			//gpio-hogs and cape-universal dont mesh very well on bootup...
+			env_set("uboot_base_dtb_univ", "am335x-bonegreen-wireless-uboot-univ.dtb");
+			env_set("uboot_base_dtb", "am335x-boneblack-uboot.dtb");
+			env_set("uboot_try_cape_universal", "1");
+			break;
+		case BBE_BASE_DTB:
+			env_set("uboot_base_dtb_univ", "am335x-sancloud-bbe-uboot-univ.dtb");
+			env_set("uboot_base_dtb", "am335x-sancloud-bbe-uboot.dtb");
+			env_set("uboot_try_cape_universal", "1");
+			break;
+		case BBBL_BASE_DTB:
+			env_set("uboot_base_dtb_univ", "am335x-boneblue.dtb");
+			break;
+	}
+
+	if (virtual_emmc == BBB_EMMC) {
+		env_set("uboot_emmc", "/lib/firmware/BB-BONE-eMMC1-01-00A0.dtbo");
+	}
+
+	switch(virtual_video) {
+		case BBB_TDA998X_AUDIO:
+			if (virtual_audio == PINS_TAKEN) {
+				env_set("uboot_video", "/lib/firmware/BB-NHDMI-TDA998x-00A0.dtbo");
+				env_set("uboot_video_naudio", "/lib/firmware/BB-NHDMI-TDA998x-00A0.dtbo");
+			} else {
+				env_set("uboot_video", "/lib/firmware/BB-HDMI-TDA998x-00A0.dtbo");
+				env_set("uboot_video_naudio", "/lib/firmware/BB-NHDMI-TDA998x-00A0.dtbo");
+			}
+			break;
+		case BBB_TDA998X_NAUDIO:
+			env_set("uboot_video", "/lib/firmware/BB-NHDMI-TDA998x-00A0.dtbo");
+			env_set("uboot_video_naudio", "/lib/firmware/BB-NHDMI-TDA998x-00A0.dtbo");
+			break;
+		case BBB_ADV7511_AUDIO:
+			if (virtual_audio == PINS_TAKEN) {
+				env_set("uboot_video", "/lib/firmware/BB-NHDMI-ADV7511-00A0.dtbo");
+				env_set("uboot_video_naudio", "/lib/firmware/BB-NHDMI-ADV7511-00A0.dtbo");
+			} else {
+				env_set("uboot_video", "/lib/firmware/BB-HDMI-ADV7511-00A0.dtbo");
+				env_set("uboot_video_naudio", "/lib/firmware/BB-NHDMI-ADV7511-00A0.dtbo");
+			}
+			break;
+		case BBB_ADV7511_NAUDIO:
+			env_set("uboot_video", "/lib/firmware/BB-NHDMI-ADV7511-00A0.dtbo");
+			env_set("uboot_video_naudio", "/lib/firmware/BB-NHDMI-ADV7511-00A0.dtbo");
+			break;
+	}
+
+	switch(virtual_wireless) {
+		case BBBW_WL1835:
+			env_set("uboot_wireless", "/lib/firmware/BB-BBBW-WL1835-00A0.dtbo");
+			break;
+		case BBGW_WL1835:
+			env_set("uboot_wireless", "/lib/firmware/BB-BBGW-WL1835-00A0.dtbo");
+			break;
+	}
+
+	switch(virtual_adc) {
+		case BBB_ADC:
+			env_set("uboot_adc", "/lib/firmware/BB-ADC-00A0.dtbo");
+			break;
+	}
+
+	switch(model) {
+		case M_BBG1:
+			env_set("uboot_model", "/lib/firmware/M-BB-BBG-00A0.dtbo");
+			break;
+		case M_OS00:
+			env_set("uboot_model", "/lib/firmware/M-BB-OSD3358-SM-RED-00A0.dtbo");
+			break;
+	}
+
+	switch(cape_universal) {
+		case CAPE_UNIVERSAL_BBB:
+			env_set("uboot_cape_universal_bbb", "1");
+			break;
+		case CAPE_UNIVERSAL_BBG:
+			env_set("uboot_cape_universal_bbg", "1");
+			break;
+		case CAPE_UNIVERSAL_BBGW:
+			env_set("uboot_cape_universal_bbgw", "1");
+			break;
+	}
+
+	i2c_set_bus_num(0);
+	return 0;
+}
+
+void do_cape_detect(void)
+{
+	struct am335x_cape_eeprom_id cape_header;
+
+	i2c_init(CONFIG_SYS_OMAP24_I2C_SPEED2, CONFIG_SYS_OMAP24_I2C_SLAVE2);
+	probe_cape_eeprom(&cape_header);
+}
+
 #ifndef CONFIG_DM_SERIAL
 struct serial_device *default_serial_console(void)
 {
@@ -855,6 +1309,14 @@ int board_late_init(void)
 			env_set("serial#", board_serial);
 	}
 
+#ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
+#ifdef CONFIG_TI_I2C_BOARD_DETECT
+	if (!board_is_pb() && !board_is_beaglelogic()) {
+		do_cape_detect();
+	}
+#endif
+#endif
+
 	return 0;
 }
 #endif
diff --git a/board/ti/am335x/board.h b/board/ti/am335x/board.h
index b658914..df64fca 100644
--- a/board/ti/am335x/board.h
+++ b/board/ti/am335x/board.h
@@ -10,6 +10,22 @@
 #ifndef _BOARD_H_
 #define _BOARD_H_
 
+struct am335x_cape_eeprom_id {
+	unsigned int header;
+	char eeprom_rev[2];
+	char board_name[32];
+	char version[4];
+	char manufacture[16];
+	char part_number[16];
+	char number_of_pins[2];
+	char serial_number[12];
+	char pin_usage[140];
+	char vdd_3v3exp[ 2];
+	char vdd_5v[ 2];
+	char sys_5v[2];
+	char dc_supplied[2];
+};
+
 /**
  * AM335X (EMIF_4D) EMIF REG_COS_COUNT_1, REG_COS_COUNT_2, and
  * REG_PR_OLD_COUNT values to avoid LCDC DMA FIFO underflows and Frame
@@ -128,5 +144,6 @@ void enable_uart3_pin_mux(void);
 void enable_uart4_pin_mux(void);
 void enable_uart5_pin_mux(void);
 void enable_i2c0_pin_mux(void);
+void enable_i2c2_pin_mux(void);
 void enable_board_pin_mux(void);
 #endif
diff --git a/board/ti/am335x/hash-string.h b/board/ti/am335x/hash-string.h
new file mode 100644
index 0000000..b267a87
--- /dev/null
+++ b/board/ti/am335x/hash-string.h
@@ -0,0 +1,59 @@
+/* Description of GNU message catalog format: string hashing function.
+   Copyright (C) 1995, 1997, 1998, 2000, 2001 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify it
+   under the terms of the GNU Library General Public License as published
+   by the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with this program; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+   USA.  */
+
+/* @@ end of prolog @@ */
+
+#ifndef PARAMS
+# if __STDC__ || defined __GNUC__ || defined __SUNPRO_C || defined __cplusplus || __PROTOTYPES
+#  define PARAMS(Args) Args
+# else
+#  define PARAMS(Args) ()
+# endif
+#endif
+
+/* We assume to have `unsigned long int' value with at least 32 bits.  */
+#define HASHWORDBITS 32
+
+
+/* Defines the so called `hashpjw' function by P.J. Weinberger
+   [see Aho/Sethi/Ullman, COMPILERS: Principles, Techniques and Tools,
+   1986, 1987 Bell Telephone Laboratories, Inc.]  */
+static unsigned long int hash_string PARAMS ((const char *__str_param));
+
+static inline unsigned long int
+hash_string (str_param)
+     const char *str_param;
+{
+  unsigned long int hval, g;
+  const char *str = str_param;
+
+  /* Compute the hash value for the given string.  */
+  hval = 0;
+  while (*str != '\0')
+    {
+      hval <<= 4;
+      hval += (unsigned long int) *str++;
+      g = hval & ((unsigned long int) 0xf << (HASHWORDBITS - 4));
+      if (g != 0)
+	{
+	  hval ^= g >> (HASHWORDBITS - 8);
+	  hval ^= g;
+	}
+    }
+  return hval;
+}
diff --git a/board/ti/am335x/mux.c b/board/ti/am335x/mux.c
index dc0189a..8eb99c3 100644
--- a/board/ti/am335x/mux.c
+++ b/board/ti/am335x/mux.c
@@ -120,6 +120,14 @@ static struct module_pin_mux i2c1_pin_mux[] = {
 	{-1},
 };
 
+static struct module_pin_mux i2c2_pin_mux[] = {
+	{OFFSET(uart1_ctsn), (MODE(3) | RXACTIVE |
+			PULLUP_EN | PULLUDEN | SLEWCTRL)},	/* I2C_DATA */
+	{OFFSET(uart1_rtsn), (MODE(3) | RXACTIVE |
+			PULLUP_EN | PULLUDEN | SLEWCTRL)},	/* I2C_SCLK */
+	{-1},
+};
+
 static struct module_pin_mux spi0_pin_mux[] = {
 	{OFFSET(spi0_sclk), (MODE(0) | RXACTIVE | PULLUDEN)},	/* SPI0_SCLK */
 	{OFFSET(spi0_d0), (MODE(0) | RXACTIVE |
@@ -304,6 +312,11 @@ void enable_i2c0_pin_mux(void)
 	configure_module_pin_mux(i2c0_pin_mux);
 }
 
+void enable_i2c2_pin_mux(void)
+{
+	configure_module_pin_mux(i2c2_pin_mux);
+}
+
 /*
  * The AM335x GP EVM, if daughter card(s) are connected, can have 8
  * different profiles.  These profiles determine what peripherals are
@@ -356,6 +369,7 @@ void enable_board_pin_mux(void)
 #else
 		configure_module_pin_mux(mmc1_pin_mux);
 #endif
+		configure_module_pin_mux(i2c2_pin_mux);
 	} else if (board_is_gp_evm()) {
 		/* General Purpose EVM */
 		unsigned short profile = detect_daughter_board_profile();
@@ -401,6 +415,7 @@ void enable_board_pin_mux(void)
 #else
 		configure_module_pin_mux(mmc1_pin_mux);
 #endif
+		configure_module_pin_mux(i2c2_pin_mux);
 	} else if (board_is_pb()) {
 		configure_module_pin_mux(mii1_pin_mux);
 		configure_module_pin_mux(mmc0_pin_mux);
diff --git a/include/configs/ti_armv7_common.h b/include/configs/ti_armv7_common.h
index b0f517c..f47080f 100644
--- a/include/configs/ti_armv7_common.h
+++ b/include/configs/ti_armv7_common.h
@@ -338,6 +338,51 @@
 			"echo loading ${bootdir}/${bootfile} ...; "\
 			"run loadimage;" \
 			"setenv fdtdir /boot/dtbs/${uname_r}; " \
+			"echo debug: [enable_uboot_overlays=${enable_uboot_overlays}] ... ;" \
+			"if test -n ${enable_uboot_overlays}; then " \
+				"if test -n ${dtb}; then " \
+					"echo uboot_overlays: dtb=${dtb} is set in /boot/uEnv.txt, unable to use [${uboot_base_dtb_univ} or ${uboot_base_dtb}] ... ;" \
+					"if test -n ${enable_uboot_overlays}; then " \
+						"env delete -f enable_uboot_overlays; " \
+						"echo uboot_overlays: disabling [enable_uboot_overlays=1] as dtb=${dtb} is set in /boot/uEnv.txt ... ;" \
+					"fi;" \
+				"else " \
+					"echo debug: [enable_uboot_cape_universal=${enable_uboot_cape_universal}] ... ;" \
+					"if test -n ${enable_uboot_cape_universal}; then " \
+						"echo debug: [uboot_base_dtb_univ=${uboot_base_dtb_univ}] ... ;" \
+						"if test -n ${uboot_base_dtb_univ}; then " \
+							"echo uboot_overlays: [uboot_base_dtb=${uboot_base_dtb_univ}] ... ;" \
+							"if test -e ${devtype} ${bootpart} ${fdtdir}/${uboot_base_dtb_univ}; then " \
+								"setenv fdtfile ${uboot_base_dtb_univ};" \
+								"echo uboot_overlays: Switching too: dtb=${fdtfile} ...;" \
+								"if test -n ${uboot_try_cape_universal}; then " \
+									"env delete -f uboot_try_cape_universal; " \
+								"fi;" \
+								"setenv cape_uboot bone_capemgr.uboot_capemgr_enabled=1; " \
+							"else " \
+								"echo debug: unable to find [${uboot_base_dtb_univ}] using [${uboot_base_dtb}] instead ... ;" \
+								"echo debug: [uboot_base_dtb_univ=${uboot_base_dtb}] ... ;" \
+								"if test -n ${uboot_base_dtb}; then " \
+									"echo uboot_overlays: [uboot_base_dtb=${uboot_base_dtb}] ... ;" \
+									"if test -e ${devtype} ${bootpart} ${fdtdir}/${uboot_base_dtb}; then " \
+										"setenv fdtfile ${uboot_base_dtb};" \
+										"echo uboot_overlays: Switching too: dtb=${fdtfile} ...;" \
+									"fi;" \
+								"fi;" \
+							"fi;" \
+						"fi;" \
+					"else " \
+						"echo debug: [uboot_base_dtb_univ=${uboot_base_dtb}] ... ;" \
+						"if test -n ${uboot_base_dtb}; then " \
+							"echo uboot_overlays: [uboot_base_dtb=${uboot_base_dtb}] ... ;" \
+							"if test -e ${devtype} ${bootpart} ${fdtdir}/${uboot_base_dtb}; then " \
+								"setenv fdtfile ${uboot_base_dtb};" \
+								"echo uboot_overlays: Switching too: dtb=${fdtfile} ...;" \
+							"fi;" \
+						"fi;" \
+					"fi;" \
+				"fi;" \
+			"fi;" \
 			"if test -e ${devtype} ${bootpart} ${fdtdir}/${fdtfile}; then " \
 				"run loadfdt;" \
 			"else " \
@@ -378,6 +423,180 @@
 					"fi;" \
 				"fi;" \
 			"fi; " \
+			"if test -n ${enable_uboot_overlays}; then " \
+				"setenv fdt_buffer 0x60000;" \
+				"if test -n ${uboot_fdt_buffer}; then " \
+					"setenv fdt_buffer ${uboot_fdt_buffer};" \
+				"fi;" \
+				"echo uboot_overlays: [fdt_buffer=${fdt_buffer}] ... ;" \
+				"if test -n ${uboot_silicon}; then " \
+					"setenv uboot_overlay ${uboot_silicon}; " \
+					"run virtualloadoverlay;" \
+				"fi;" \
+				"if test -n ${uboot_model}; then " \
+					"setenv uboot_overlay ${uboot_model}; " \
+					"run virtualloadoverlay;" \
+				"fi;" \
+				"if test -n ${uboot_overlay_addr0}; then " \
+					"if test -n ${disable_uboot_overlay_addr0}; then " \
+						"echo uboot_overlays: uboot loading of [${uboot_overlay_addr0}] disabled by /boot/uEnv.txt [disable_uboot_overlay_addr0=1]...;" \
+					"else " \
+						"setenv uboot_overlay ${uboot_overlay_addr0}; " \
+						"run capeloadoverlay;" \
+					"fi;" \
+				"fi;" \
+				"if test -n ${uboot_overlay_addr1}; then " \
+					"if test -n ${disable_uboot_overlay_addr1}; then " \
+						"echo uboot_overlays: uboot loading of [${uboot_overlay_addr1}] disabled by /boot/uEnv.txt [disable_uboot_overlay_addr1=1]...;" \
+					"else " \
+						"setenv uboot_overlay ${uboot_overlay_addr1}; " \
+						"run capeloadoverlay;" \
+					"fi;" \
+				"fi;" \
+				"if test -n ${uboot_overlay_addr2}; then " \
+					"if test -n ${disable_uboot_overlay_addr2}; then " \
+						"echo uboot_overlays: uboot loading of [${uboot_overlay_addr2}] disabled by /boot/uEnv.txt [disable_uboot_overlay_addr2=1]...;" \
+					"else " \
+						"setenv uboot_overlay ${uboot_overlay_addr2}; " \
+						"run capeloadoverlay;" \
+					"fi;" \
+				"fi;" \
+				"if test -n ${uboot_overlay_addr3}; then " \
+					"if test -n ${disable_uboot_overlay_addr3}; then " \
+						"echo uboot_overlays: uboot loading of [${uboot_overlay_addr3}] disabled by /boot/uEnv.txt [disable_uboot_overlay_addr3=1]...;" \
+					"else " \
+						"setenv uboot_overlay ${uboot_overlay_addr3}; " \
+						"run capeloadoverlay;" \
+					"fi;" \
+				"fi;" \
+				"if test -n ${uboot_overlay_addr4}; then " \
+					"setenv uboot_overlay ${uboot_overlay_addr4}; " \
+					"run capeloadoverlay;" \
+				"fi;" \
+				"if test -n ${uboot_overlay_addr5}; then " \
+					"setenv uboot_overlay ${uboot_overlay_addr5}; " \
+					"run capeloadoverlay;" \
+				"fi;" \
+				"if test -n ${uboot_overlay_addr6}; then " \
+					"setenv uboot_overlay ${uboot_overlay_addr6}; " \
+					"run capeloadoverlay;" \
+				"fi;" \
+				"if test -n ${uboot_overlay_addr7}; then " \
+					"setenv uboot_overlay ${uboot_overlay_addr7}; " \
+					"run capeloadoverlay;" \
+				"fi;" \
+				"if test -n ${uboot_emmc}; then " \
+					"if test -n ${disable_uboot_overlay_emmc}; then " \
+						"echo uboot_overlays: uboot loading of [${uboot_emmc}] disabled by /boot/uEnv.txt [disable_uboot_overlay_emmc=1]...;" \
+					"else " \
+						"setenv uboot_overlay ${uboot_emmc}; " \
+						"run virtualloadoverlay;" \
+					"fi;" \
+				"fi;" \
+				"if test -n ${uboot_video}; then " \
+					"if test -n ${disable_uboot_overlay_video}; then " \
+						"echo uboot_overlays: uboot loading of [${uboot_video}] disabled by /boot/uEnv.txt [disable_uboot_overlay_video=1]...;" \
+					"else " \
+						"if test -n ${disable_uboot_overlay_audio}; then " \
+							"echo uboot_overlays: uboot loading of [${uboot_video}] disabled by /boot/uEnv.txt [disable_uboot_overlay_audio=1]...;" \
+							"setenv uboot_overlay ${uboot_video_naudio}; " \
+							"run virtualloadoverlay;" \
+						"else " \
+							"setenv uboot_overlay ${uboot_video}; " \
+							"run virtualloadoverlay;" \
+						"fi;" \
+					"fi;" \
+				"fi;" \
+				"if test -n ${uboot_wireless}; then " \
+					"if test -n ${disable_uboot_overlay_wireless}; then " \
+						"echo uboot_overlays: uboot loading of [${uboot_wireless}] disabled by /boot/uEnv.txt [disable_uboot_overlay_wireless=1]...;" \
+					"else " \
+						"setenv uboot_overlay ${uboot_wireless}; " \
+						"run virtualloadoverlay;" \
+					"fi;" \
+				"fi;" \
+				"if test -n ${uboot_adc}; then " \
+					"if test -n ${disable_uboot_overlay_adc}; then " \
+						"echo uboot_overlays: uboot loading of [${uboot_adc}] disabled by /boot/uEnv.txt [disable_uboot_overlay_adc=1]...;" \
+					"else " \
+						"setenv uboot_overlay ${uboot_adc}; " \
+						"run virtualloadoverlay;" \
+					"fi;" \
+				"fi;" \
+				"if test -n ${uboot_overlay_pru}; then " \
+					"setenv uboot_overlay ${uboot_overlay_pru}; " \
+					"run virtualloadoverlay;" \
+				"fi;" \
+				"if test -n ${dtb_overlay}; then " \
+					"setenv uboot_overlay ${dtb_overlay}; " \
+					"echo uboot_overlays: [dtb_overlay=${uboot_overlay}] ... ;" \
+					"run capeloadoverlay;" \
+				"fi;" \
+				"if test -n ${uboot_detected_capes}; then " \
+					"echo uboot_overlays: [uboot_detected_capes=${uboot_detected_capes_addr0}${uboot_detected_capes_addr1}${uboot_detected_capes_addr2}${uboot_detected_capes_addr3}] ... ;" \
+					"setenv uboot_detected_capes uboot_detected_capes=${uboot_detected_capes_addr0}${uboot_detected_capes_addr1}${uboot_detected_capes_addr2}${uboot_detected_capes_addr3}; " \
+				"fi;" \
+				"if test -n ${uboot_try_cape_universal}; then " \
+					"if test -n ${enable_uboot_cape_universal}; then " \
+						"if test -n ${cape_uboot}; then " \
+							"echo uboot_overlays: cape universal disabled, external cape enabled or detected...;" \
+						"else " \
+							"if test -n ${uboot_cape_universal_bbb}; then " \
+								"if test -n ${disable_uboot_overlay_emmc}; then " \
+									"if test -n ${disable_uboot_overlay_video}; then " \
+										"setenv uboot_overlay /lib/firmware/univ-bbb-xxx-00A0.dtbo; " \
+									"else " \
+										"if test -n ${disable_uboot_overlay_audio}; then " \
+											"setenv uboot_overlay /lib/firmware/univ-bbb-xVx-00A0.dtbo; " \
+										"else " \
+											"setenv uboot_overlay /lib/firmware/univ-bbb-xVA-00A0.dtbo; " \
+										"fi;" \
+									"fi;" \
+								"else " \
+									"if test -n ${disable_uboot_overlay_video}; then " \
+										"setenv uboot_overlay /lib/firmware/univ-bbb-Exx-00A0.dtbo; " \
+									"else " \
+										"if test -n ${disable_uboot_overlay_audio}; then " \
+											"setenv uboot_overlay /lib/firmware/univ-bbb-EVx-00A0.dtbo; " \
+										"else " \
+											"setenv uboot_overlay /lib/firmware/univ-bbb-EVA-00A0.dtbo; " \
+										"fi;" \
+									"fi;" \
+								"fi;" \
+								"run capeloadoverlay;" \
+							"fi;" \
+							"if test -n ${uboot_cape_universal_bbg}; then " \
+								"if test -n ${disable_uboot_overlay_emmc}; then " \
+									"setenv uboot_overlay /lib/firmware/univ-bbb-xxx-00A0.dtbo; " \
+								"else " \
+									"setenv uboot_overlay /lib/firmware/univ-bbb-Exx-00A0.dtbo; " \
+								"fi;" \
+								"run capeloadoverlay;" \
+							"fi;" \
+							"if test -n ${uboot_cape_universal_bbgw}; then " \
+								"if test -n ${disable_uboot_overlay_emmc}; then " \
+									"if test -n ${disable_uboot_overlay_wireless}; then " \
+										"setenv uboot_overlay /lib/firmware/univ-bbgw-xx-00A0.dtbo; " \
+									"else " \
+										"setenv uboot_overlay /lib/firmware/univ-bbgw-xW-00A0.dtbo; " \
+									"fi;" \
+								"else " \
+									"if test -n ${disable_uboot_overlay_wireless}; then " \
+										"setenv uboot_overlay /lib/firmware/univ-bbgw-Ex-00A0.dtbo; " \
+									"else " \
+										"setenv uboot_overlay /lib/firmware/univ-bbgw-EW-00A0.dtbo; " \
+									"fi;" \
+								"fi;" \
+								"run capeloadoverlay;" \
+							"fi;" \
+						"fi;" \
+					"else " \
+						"echo uboot_overlays: add [enable_uboot_cape_universal=1] to /boot/uEnv.txt to enable...;" \
+					"fi;" \
+				"fi;" \
+			"else " \
+				"echo uboot_overlays: add [enable_uboot_overlays=1] to /boot/uEnv.txt to enable...;" \
+			"fi;" \
 			"setenv rdfile initrd.img-${uname_r}; " \
 			"if test -e ${devtype} ${bootpart} ${bootdir}/${rdfile}; then " \
 				"echo loading ${bootdir}/${rdfile} ...; "\
diff --git a/include/configs/ti_armv7_omap.h b/include/configs/ti_armv7_omap.h
index 98b5839..ce7927e 100644
--- a/include/configs/ti_armv7_omap.h
+++ b/include/configs/ti_armv7_omap.h
@@ -11,6 +11,9 @@
 #ifndef __CONFIG_TI_ARMV7_OMAP_H__
 #define __CONFIG_TI_ARMV7_OMAP_H__
 
+#define CONFIG_SYS_OMAP24_I2C_SPEED2	100000
+#define CONFIG_SYS_OMAP24_I2C_SLAVE2	1
+
 /*
  * GPMC NAND block.  We support 1 device and the physical address to
  * access CS0 at is 0x8000000.
diff --git a/include/environment/ti/mmc.h b/include/environment/ti/mmc.h
index 110c426..d6bbe3e 100644
--- a/include/environment/ti/mmc.h
+++ b/include/environment/ti/mmc.h
@@ -68,6 +68,21 @@
 	"loadimage=load ${devtype} ${bootpart} ${loadaddr} ${bootdir}/${bootfile}\0" \
 	"loadrd=load ${devtype} ${bootpart} ${rdaddr} ${bootdir}/${rdfile}; setenv rdsize ${filesize}\0" \
 	"loadfdt=echo loading ${fdtdir}/${fdtfile} ...; load ${devtype} ${bootpart} ${fdtaddr} ${fdtdir}/${fdtfile}\0" \
+	"loadoverlay=echo uboot_overlays: loading ${uboot_overlay} ...; " \
+		"load ${devtype} ${bootpart} ${rdaddr} ${uboot_overlay}; " \
+		"fdt addr ${fdtaddr}; fdt resize ${fdt_buffer}; " \
+		"fdt apply ${rdaddr}; fdt resize ${fdt_buffer};\0" \
+	"virtualloadoverlay=if test -e ${devtype} ${bootpart} ${uboot_overlay}; then " \
+				"run loadoverlay;" \
+			"else " \
+				"echo uboot_overlays: unable to find [${devtype} ${bootpart} ${uboot_overlay}]...;" \
+			"fi;\0" \
+	"capeloadoverlay=if test -e ${devtype} ${bootpart} ${uboot_overlay}; then " \
+				"run loadoverlay;" \
+				"setenv cape_uboot bone_capemgr.uboot_capemgr_enabled=1; " \
+			"else " \
+				"echo uboot_overlays: unable to find [${devtype} ${bootpart} ${uboot_overlay}]...;" \
+			"fi;\0" \
 	"failumsboot=echo; echo FAILSAFE: U-Boot UMS (USB Mass Storage) enabled, media now available over the usb slave port ...; " \
 		"ums 0 ${devtype} 1;\0" \
 	"envboot=mmc dev ${mmcdev}; " \
-- 
2.20.1

