summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMax Krummenacher <max.krummenacher@toradex.com>2014-04-02 11:08:40 +0200
committerMax Krummenacher <max.krummenacher@toradex.com>2014-04-02 11:08:40 +0200
commit5e6d291ebc9fa899e4bff5c8dbba2d8bdf138bf8 (patch)
tree168d798b236c5d465f11d6601535fbff91b6509d
parente6d2fecb1535dba8fc78b5b5798d1f81bed70fe5 (diff)
board: add Toradex configblock handling
-rw-r--r--board/toradex/apalis_imx6/apalis_imx6.c159
-rw-r--r--include/configs/apalis-imx6.h7
2 files changed, 166 insertions, 0 deletions
diff --git a/board/toradex/apalis_imx6/apalis_imx6.c b/board/toradex/apalis_imx6/apalis_imx6.c
index 1175c91d94..cccc0de48d 100644
--- a/board/toradex/apalis_imx6/apalis_imx6.c
+++ b/board/toradex/apalis_imx6/apalis_imx6.c
@@ -34,6 +34,14 @@
DECLARE_GLOBAL_DATA_PTR;
+#if defined(CONFIG_BOARD_LATE_INIT) && (defined(CONFIG_TRDX_CFG_BLOCK) || \
+ defined(CONFIG_REVISION_TAG) || defined(CONFIG_SERIAL_TAG))
+/* buffer suitable for DMA */
+#define CONFIG_BLOCK_BUFFER_SIZE 4096
+static unsigned char config_block[roundup(CONFIG_BLOCK_BUFFER_SIZE, ARCH_DMA_MINALIGN)]
+ __aligned(ARCH_DMA_MINALIGN);
+#endif
+
#define UART_PAD_CTRL (PAD_CTL_PUS_100K_UP | \
PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm | \
PAD_CTL_SRE_FAST | PAD_CTL_HYS)
@@ -799,6 +807,157 @@ int board_init(void)
return 0;
}
+#ifdef CONFIG_BOARD_LATE_INIT
+int board_late_init(void)
+{
+#ifdef CONFIG_TRDX_CFG_BLOCK
+ char env_str[256];
+
+ int i;
+ unsigned size = 0;
+
+ char *addr_str, *end;
+ unsigned char bi_enetaddr[6] = {0, 0, 0, 0, 0, 0}; /* Ethernet
+ address */
+ unsigned char *mac_addr;
+ unsigned char mac_addr00[6] = {0, 0, 0, 0, 0, 0};
+
+ struct mmc *mmc;
+
+ unsigned char toradex_oui[3] = { 0x00, 0x14, 0x2d };
+ int valid = 0;
+
+ int ret;
+ /* Read production parameter config block from eMMC */
+ mmc = find_mmc_device(0);
+ /* Just reading one 512 byte block */
+ ret = mmc->block_dev.block_read(0, (CONFIG_TRDX_CFG_BLOCK_OFFSET / 512), 1,
+ (unsigned char *)config_block);
+ if (ret == 1) {
+ ret = 0;
+ size = 512;
+ }
+
+ /* Check validity */
+ if ((ret == 0) && (size > 0)) {
+ mac_addr = config_block + 8;
+ if (!(memcmp(mac_addr, toradex_oui, 3)))
+ valid = 1;
+ }
+
+ if (!valid) {
+ printf("Missing Colibri config block\n");
+ memset((void *)config_block, 0, size);
+ } else {
+ /* Get MAC address from environment */
+ addr_str = getenv("ethaddr");
+ if (addr_str != NULL) {
+ for (i = 0; i < 6; i++) {
+ bi_enetaddr[i] = addr_str ? simple_strtoul(
+ addr_str, &end, 16) : 0;
+ if (addr_str)
+ addr_str = (*end) ? end + 1 : end;
+ }
+ }
+
+ /* Set Ethernet MAC address from config block if not already set
+ */
+ if (memcmp(mac_addr00, bi_enetaddr, 6) == 0) {
+ sprintf(env_str, "%02x:%02x:%02x:%02x:%02x:%02x",
+ mac_addr[0], mac_addr[1], mac_addr[2],
+ mac_addr[3], mac_addr[4], mac_addr[5]);
+ setenv("ethaddr", env_str);
+#ifndef CONFIG_ENV_IS_NOWHERE
+ saveenv();
+#endif
+ }
+ }
+#endif /* CONFIG_TRDX_CFG_BLOCK */
+ return 0;
+}
+#endif /* CONFIG_BOARD_LATE_INIT */
+
+#ifdef CONFIG_REVISION_TAG
+u32 get_board_rev(void)
+{
+#ifdef CONFIG_BOARD_LATE_INIT
+ int i;
+ unsigned short major = 0, minor = 0, release = 0;
+ size_t size = 4096;
+
+ if (config_block == NULL)
+ return 0;
+
+ /* Parse revision information in config block */
+ for (i = 0; i < (size - 8); i++) {
+ if (config_block[i] == 0x02 && config_block[i+1] == 0x40 &&
+ config_block[i+2] == 0x08) {
+ break;
+ }
+ }
+
+ major = (config_block[i+3] << 8) | config_block[i+4];
+ minor = (config_block[i+5] << 8) | config_block[i+6];
+ release = (config_block[i+7] << 8) | config_block[i+8];
+
+ /* Check validity */
+ if (major)
+ return ((major & 0xff) << 8) | ((minor & 0xf) << 4) |
+ ((release & 0xf) + 0xa);
+ else
+ return 0;
+#else
+ return 0;
+#endif /* CONFIG_BOARD_LATE_INIT */
+}
+#endif /* CONFIG_REVISION_TAG */
+
+#ifdef CONFIG_SERIAL_TAG
+void get_board_serial(struct tag_serialnr *serialnr)
+{
+#ifdef CONFIG_BOARD_LATE_INIT
+ int array[8];
+ int i;
+ unsigned int serial = 0;
+ unsigned int serial_offset = 11;
+
+ if (config_block == NULL) {
+ serialnr->low = 0;
+ serialnr->high = 0;
+ return;
+ }
+
+ /* Get MAC address from config block */
+ memcpy(&serial, config_block + serial_offset, 3);
+ serial = ntohl(serial);
+ serial >>= 8;
+
+ /* Check validity */
+ if (serial) {
+ /* Convert to Linux serial number format (hexadecimal coded
+ decimal) */
+ i = 7;
+ while (serial) {
+ array[i--] = serial % 10;
+ serial /= 10;
+ }
+ while (i >= 0)
+ array[i--] = 0;
+ serial = array[0];
+ for (i = 1; i < 8; i++) {
+ serial *= 16;
+ serial += array[i];
+ }
+ }
+
+ serialnr->low = serial;
+#else
+ serialnr->low = 0;
+#endif /* CONFIG_BOARD_LATE_INIT */
+ serialnr->high = 0;
+}
+#endif /* CONFIG_SERIAL_TAG */
+
int checkboard(void)
{
puts("Board: Toradex Apalis iMX6\n");
diff --git a/include/configs/apalis-imx6.h b/include/configs/apalis-imx6.h
index 2b3919ffd6..82e04ecfc8 100644
--- a/include/configs/apalis-imx6.h
+++ b/include/configs/apalis-imx6.h
@@ -11,6 +11,7 @@
#define __CONFIG_H
#define CONFIG_MX6
+#define CONFIG_APALIS_IMX6 /* Toradex Apalis iMX6 module */
#define CONFIG_DISPLAY_CPUINFO
#define CONFIG_DISPLAY_BOARDINFO
@@ -23,11 +24,13 @@
#define CONFIG_SETUP_MEMORY_TAGS
#define CONFIG_INITRD_TAG
#define CONFIG_REVISION_TAG
+#define CONFIG_SERIAL_TAG
/* Size of malloc() pool */
#define CONFIG_SYS_MALLOC_LEN (10 * 1024 * 1024)
#define CONFIG_BOARD_EARLY_INIT_F
+#define CONFIG_BOARD_LATE_INIT
#define CONFIG_MISC_INIT_R
#define CONFIG_MXC_GPIO
@@ -278,6 +281,10 @@
#define CONFIG_SYS_MMC_ENV_DEV 0
#endif
+/* Toradex Configblock */
+#define CONFIG_TRDX_CFG_BLOCK
+#define CONFIG_TRDX_CFG_BLOCK_OFFSET (640 * 1024)
+
#define CONFIG_OF_LIBFDT
#define CONFIG_CMD_BOOTZ