From cac4ae7a91a4872dd67084cb244f68446a4b39b8 Mon Sep 17 00:00:00 2001 From: Marcel Ziswiler Date: Thu, 18 Oct 2012 12:49:29 +0200 Subject: colibri_t20: nand: integrate NVIDIA partition table parsing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit NVIDIA's NAND layout includes a partition table that can be used to generically construct the mtdparts kernel boot argument. As an added benefit this is completely independent of the underlying NAND part used which differs with various module versions. It further allows our customer easy adoption to their own custom partition layout. Initial partition table parsing courtesy of Mitja Špes from LXNAV. --- arch/arm/include/asm/arch-tegra/tegra.h | 5 + arch/arm/lib/board.c | 8 + board/toradex/common/Makefile | 1 + board/toradex/common/tegra2_partitions.c | 342 +++++++++++++++++++++++++++++++ board/toradex/common/tegra2_partitions.h | 38 ++++ 5 files changed, 394 insertions(+) create mode 100644 board/toradex/common/tegra2_partitions.c create mode 100644 board/toradex/common/tegra2_partitions.h diff --git a/arch/arm/include/asm/arch-tegra/tegra.h b/arch/arm/include/asm/arch-tegra/tegra.h index c51a8014e0..db00ebf167 100644 --- a/arch/arm/include/asm/arch-tegra/tegra.h +++ b/arch/arm/include/asm/arch-tegra/tegra.h @@ -78,6 +78,11 @@ struct timerus { unsigned int cntr_1us; }; +#define NVBOOTINFOTABLE_BCTSIZE 0x38 /* BCT size in BIT in IRAM */ +#define NVBOOTINFOTABLE_BCTPTR 0x3C /* BCT pointer in BIT in IRAM */ +#define BCT_PTINFO_OFFSET 3820 + +/* These are the available SKUs (product types) for Tegra */ enum { SKU_ID_T20 = 0x8, SKU_ID_T25SE = 0x14, diff --git a/arch/arm/lib/board.c b/arch/arm/lib/board.c index 10ef2c8128..c6a12463e0 100644 --- a/arch/arm/lib/board.c +++ b/arch/arm/lib/board.c @@ -87,6 +87,10 @@ extern void rtl8019_get_enetaddr (uchar * addr); #include #endif +#ifdef CONFIG_COLIBRI_T20 +extern void tegra_partition_init(void); +#endif + /************************************************************************ * Coloured LED functionality @@ -594,6 +598,10 @@ void board_init_r (gd_t *id, ulong dest_addr) onenand_init(); #endif +#ifdef CONFIG_COLIBRI_T20 + tegra_partition_init(); +#endif + #ifdef CONFIG_GENERIC_MMC puts("MMC: "); mmc_initialize(bd); diff --git a/board/toradex/common/Makefile b/board/toradex/common/Makefile index e3a6dbf938..8d160d50e9 100644 --- a/board/toradex/common/Makefile +++ b/board/toradex/common/Makefile @@ -27,6 +27,7 @@ LIB = $(obj)lib$(VENDOR).o COBJS-y += board.o COBJS-$(CONFIG_TEGRA2_NAND) += tegra2_nand.o +COBJS-$(CONFIG_TEGRA2_NAND) += tegra2_partitions.o COBJS-$(CONFIG_USB_EHCI_TEGRA) += ulpi_linux.o COBJS-$(CONFIG_USB_EHCI_TEGRA) += usb.o diff --git a/board/toradex/common/tegra2_partitions.c b/board/toradex/common/tegra2_partitions.c new file mode 100644 index 0000000000..b8d8bf29ba --- /dev/null +++ b/board/toradex/common/tegra2_partitions.c @@ -0,0 +1,342 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "tegra2_nand.h" +#include "tegra2_partitions.h" + +#define DEBUG 0 + +DECLARE_GLOBAL_DATA_PTR; + +/** + * nvtegra_print_partition_table - prints partition table info + * @param pt: nvtegra_parttable_t structure + */ +void nvtegra_print_partition_table(nvtegra_parttable_t * pt) +{ + int i; + nvtegra_partinfo_t *p; + + // sanity check + if (!pt) { + printf("%s: Error! pt arg is NULL\n", __FUNCTION__); + return; + } + + p = &(pt->partinfo[0]); + printf("\n------ NVTEGRA Partitions ------\n"); + +#if DEBUG > 1 + printf("UNK:\n"); + for (i = 0; i < 18; i++) { + if (pt->_unknown[i] > 1000000) + printf("0x%08X\t", pt->_unknown[i]); + else + printf("%u\t", pt->_unknown[i]); + if ((i + 1) % 6 == 0) + printf("\n"); + } + printf("\n"); +#endif + + for (i = 0; (p->id < 128) && (i < TEGRA_MAX_PARTITIONS); i++) { + printf + ("\n[%u]\tPart:\tID=%u\tNAME=%s\tNAME2=%s\n\t\tTYPE=%u\tALLOC_POLICY=%u\tFS_TYPE=%u\n\t\tVIRTUAL START SEC=%u\tVIRTUAL SIZE=%u\n", + i, p->id, p->name, p->name2, p->type, p->allocation_policy, + p->filesystem_type, p->virtual_start_sector, + p->virtual_size); + printf("\t\tSTART SEC=%u\tEND SEC=%u\tTOTAL=%u\n", + p->start_sector, p->end_sector, + p->end_sector + 1 - p->start_sector); + +#if DEBUG > 1 + printf("\t\tUNK1=%u\t%u\n", p->_unknown1[0], p->_unknown1[1]); + printf("\t\tUNK2=%u\t%u\t0x%08x\n", p->_unknown2[0], + p->_unknown2[1], p->_unknown2[2]); + printf("\t\tUNK3=%u\n", p->_unknown3); + printf("\t\tUNK4=%u\n", p->_unknown4); + printf("\t\tUNK5=%u\n", p->_unknown5); + printf("\t\tUNK6=%u\t%u\n", p->_unknown6[0], p->_unknown6[1]); +#endif + + p++; + } + printf("--------------------------------\n"); +} + +/** + * nvtegra_read_partition_table - reads nvidia's partition table + * @return: + * 1 - Success + * 0 - Error + */ +int nvtegra_read_partition_table(nvtegra_parttable_t * pt) +{ + size_t size; + int i; + nvtegra_partinfo_t *p; + u32 bct_start, pt_logical, pt_offset; + + // sanity check + if (!pt) { + printf("%s: Error! pt arg is NULL\n", __FUNCTION__); + return 0; + } + + /* + * Partition table offset is stored in the BCT in IRAM by the BootROM. + * The BCT start and size are stored in the BIT in IRAM. + * Read the data @ bct_start + (bct_size - 260). This works + * on T20 and T30 BCTs, which are locked down. If this changes + * in new chips (T114, etc.), we can revisit this algorithm. + */ + bct_start = readl(AP20_BASE_PA_SRAM + NVBOOTINFOTABLE_BCTPTR); +#if DEBUG > 1 + printf("bct_start=0x%08x\n", bct_start); +#endif + pt_logical = readw(bct_start + BCT_PTINFO_OFFSET); + /* In case we are running with a recovery BCT missing the partition + table offset information */ + if (pt_logical == 0) { + /* BCT partition size is 3 M in our default layout */ + pt_logical = 3 * 1024 * 1024 / nand_info->writesize; + } + /* StartLogicalSector * PageSize + 4 * BlockSize */ + pt_offset = pt_logical * nand_info->writesize + 4 * nand_info->erasesize; +#if DEBUG > 1 + printf("logical=0x%08x writesize=0x%08x erasesize=0x%08x\n", readw(bct_start + BCT_PTINFO_OFFSET), nand_info->writesize, nand_info->erasesize); + printf("pt_offset=0x%08x\n", pt_offset); +#endif + + size = sizeof(nvtegra_parttable_t); + i = nand_read_skip_bad(&nand_info[0], pt_offset, &size, + (unsigned char *)pt); + if ((i != 0) || (size != sizeof(nvtegra_parttable_t))) { + printf + ("%s: Error! nand_read_skip_bad failed. nand_info->writesize=%d ret=%d\n", + __FUNCTION__, nand_info->writesize, i); + return 0; + } + + /* some heuristics */ + p = &(pt->partinfo[0]); + if ((p->id != 2) || memcmp(p->name, "BCT\0", 4) + || memcmp(p->name2, "BCT\0", 4) || (p->virtual_start_sector != 0)) { + printf + ("%s: Error! Partition table offset is probably incorrect. name='%s'\n", + __FUNCTION__, p->name); + return 0; + } + + return 1; +} + +/** + * nvtegra_find_partition - parse nvidia partition table + * @param pt: nvtegra_parttable_t structure + * @param name: partition name + * @param partinfo: output pointer to nvtegra_partinfo_t structure + * @return: + * 1 - Success, partinfo contains partition info + * 0 - Not found or error + */ +int nvtegra_find_partition(nvtegra_parttable_t * pt, const char *name, + nvtegra_partinfo_t ** partinfo) +{ + int i, l; + nvtegra_partinfo_t *p; + + // sanity checks + if (!pt) { + printf("%s: Error! pt arg is NULL\n", __FUNCTION__); + return 0; + } + if (!name) { + printf("%s: Error! name arg is NULL\n", __FUNCTION__); + return 0; + } + if (!partinfo) { + printf("%s: Error! partinfo arg is NULL\n", __FUNCTION__); + return 0; + } + + p = &(pt->partinfo[0]); + l = strlen(name) + 1; // string length + \0 + for (i = 0; (p->id < 128) && (i < TEGRA_MAX_PARTITIONS); i++) { + if (memcmp(p->name, name, l) == 0 + || memcmp(p->name2, name, l) == 0) { + *partinfo = p; + return 1; + } + p++; + } + + printf("%s: Error! Partition '%s' not found.\n", __FUNCTION__, name); + return 0; +} + +int nvtegra_mtdparts_string(char *output, int size) +{ + int i, j = 0; + nvtegra_parttable_t *pt; + nvtegra_partinfo_t *p, *usr; + char buffer[512]; + + // sanity checks + if (!output) { + printf("%s: Error! output arg is NULL.\n", __FUNCTION__); + return 0; + } + if (size > 256) { + printf + ("%s: Error! size is too large. Increase buffer size here.\n", + __FUNCTION__); + return 0; + } + // parse nvidia partition table + pt = malloc(sizeof(nvtegra_parttable_t)); + if (!pt) { + printf("%s: Error calling malloc(%d)\n", __FUNCTION__, + sizeof(nvtegra_parttable_t)); + return 0; + } + + if (!nvtegra_read_partition_table(pt)) { + free(pt); + return 0; + } + // make rootfs partition the first in the list + if (nvtegra_find_partition(pt, "USR", &p)) { + sprintf(buffer + j, "%uK@%uK(USR)", + p->virtual_size * nand_info->writesize / 1024, + p->start_sector * nand_info->writesize / 1024); + j += strlen(buffer + j); + } + usr = p; + + p = &(pt->partinfo[0]); + for (i = 0; (p->id < 128) && (i < TEGRA_MAX_PARTITIONS); i++) { + if (p != usr) { + if (strlen(p->name)) + sprintf(buffer + j, ",%uK@%uK(%s)", + p->virtual_size * + nand_info->writesize / 1024, + p->start_sector * + nand_info->writesize / 1024, p->name); + else + sprintf(buffer + j, ",%uK@%uK", + p->virtual_size * + nand_info->writesize / 1024, + p->start_sector * + nand_info->writesize / 1024); + + j += strlen(buffer + j); + } + if (strlen(buffer) >= size) + break; + p++; + } + + memcpy(output, buffer, (j < size ? j + 1 : size)); + free(pt); + return 1; +} + +void tegra_partition_init(void) +{ + nvtegra_parttable_t *pt; + nvtegra_partinfo_t *partinfo; + + // parse nvidia partition table + pt = malloc(sizeof(nvtegra_parttable_t)); + if (!pt) { + printf("%s: Error calling malloc(%d)\n", __FUNCTION__, + sizeof(nvtegra_parttable_t)); + return; + } + //copy partition information to global data + if (!nvtegra_read_partition_table(pt)) { + free(pt); + return; + } + + if (nvtegra_find_partition(pt, "ENV", &partinfo)) { + gd->env_offset = + partinfo->start_sector * nand_info->writesize; +#if DEBUG > 1 + printf + ("\nPart:\tID=%u\tNAME=%s\tNAME2=%s\n\t\tTYPE=%u\tALLOC_POLICY=%u\tFS_TYPE=%u\n\t\tVIRTUAL START SEC=%u\tVIRTUAL SIZE=%u\n", + partinfo->id, partinfo->name, partinfo->name2, + partinfo->type, partinfo->allocation_policy, + partinfo->filesystem_type, partinfo->virtual_start_sector, + partinfo->virtual_size); + printf("\t\tSTART SEC=%u\tEND SEC=%u\tTOTAL=%u\n", + partinfo->start_sector, partinfo->end_sector, + partinfo->end_sector + 1 - partinfo->start_sector); +#endif + } + + if (nvtegra_find_partition(pt, "ARG", &partinfo)) { + gd->conf_blk_offset = + partinfo->start_sector * nand_info->writesize; +#if DEBUG > 1 + printf + ("\nPart:\tID=%u\tNAME=%s\tNAME2=%s\n\t\tTYPE=%u\tALLOC_POLICY=%u\tFS_TYPE=%u\n\t\tVIRTUAL START SEC=%u\tVIRTUAL SIZE=%u\n", + partinfo->id, partinfo->name, partinfo->name2, + partinfo->type, partinfo->allocation_policy, + partinfo->filesystem_type, partinfo->virtual_start_sector, + partinfo->virtual_size); + printf("\t\tSTART SEC=%u\tEND SEC=%u\tTOTAL=%u\n", + partinfo->start_sector, partinfo->end_sector, + partinfo->end_sector + 1 - partinfo->start_sector); +#endif + } + + if (nvtegra_find_partition(pt, "LNX", &partinfo)) { + gd->kernel_offset = + partinfo->start_sector * nand_info->writesize; +#if DEBUG > 1 + printf + ("\nPart:\tID=%u\tNAME=%s\tNAME2=%s\n\t\tTYPE=%u\tALLOC_POLICY=%u\tFS_TYPE=%u\n\t\tVIRTUAL START SEC=%u\tVIRTUAL SIZE=%u\n", + partinfo->id, partinfo->name, partinfo->name2, + partinfo->type, partinfo->allocation_policy, + partinfo->filesystem_type, partinfo->virtual_start_sector, + partinfo->virtual_size); + printf("\t\tSTART SEC=%u\tEND SEC=%u\tTOTAL=%u\n", + partinfo->start_sector, partinfo->end_sector, + partinfo->end_sector + 1 - partinfo->start_sector); +#endif + } + + if (nvtegra_find_partition(pt, "USR", &partinfo)) { +#if DEBUG > 1 + printf + ("\nPart:\tID=%u\tNAME=%s\tNAME2=%s\n\t\tTYPE=%u\tALLOC_POLICY=%u\tFS_TYPE=%u\n\t\tVIRTUAL START SEC=%u\tVIRTUAL SIZE=%u\n", + partinfo->id, partinfo->name, partinfo->name2, + partinfo->type, partinfo->allocation_policy, + partinfo->filesystem_type, partinfo->virtual_start_sector, + partinfo->virtual_size); + printf("\t\tSTART SEC=%u\tEND SEC=%u\tTOTAL=%u\n", + partinfo->start_sector, partinfo->end_sector, + partinfo->end_sector + 1 - partinfo->start_sector); +#endif + } +#if DEBUG > 1 + printf("gd->env_offset=%u\n", gd->env_offset); + printf("gd->conf_blk_offset=%u\n", gd->conf_blk_offset); + printf("gd->kernel_offset=%u\n", gd->kernel_offset); +#endif + +#if DEBUG > 0 + nvtegra_print_partition_table(pt); +#endif + + free(pt); +} + diff --git a/board/toradex/common/tegra2_partitions.h b/board/toradex/common/tegra2_partitions.h new file mode 100644 index 0000000000..504cd1a5cf --- /dev/null +++ b/board/toradex/common/tegra2_partitions.h @@ -0,0 +1,38 @@ +#ifndef _TEGRA2_PARTITIONS_H_ +#define _TEGRA2_PARTITIONS_H_ + +#define TEGRA_MAX_PARTITIONS 24 + +typedef struct { + unsigned id; + char name[4]; + unsigned allocation_policy; + unsigned _unknown1[2]; + char name2[4]; + unsigned filesystem_type; + unsigned _unknown2[3]; + unsigned virtual_start_sector; + unsigned _unknown3; + unsigned virtual_size; + unsigned _unknown4; + unsigned start_sector; + unsigned _unknown5; + unsigned end_sector; + unsigned _unknown6[2]; + unsigned type; +} __attribute__ ((packed)) nvtegra_partinfo_t; + +typedef struct { + unsigned _unknown[18]; + nvtegra_partinfo_t partinfo[TEGRA_MAX_PARTITIONS]; +} __attribute__ ((packed)) nvtegra_parttable_t; + +void nvtegra_print_partition_table(nvtegra_parttable_t * pt); +int nvtegra_read_partition_table(nvtegra_parttable_t * pt); +int nvtegra_find_partition(nvtegra_parttable_t * pt, const char *name, + nvtegra_partinfo_t ** partinfo); +int nvtegra_mtdparts_string(char *output, int size); +void tegra_partition_init(void); + +#endif /* _TEGRA2_PARTITIONS_H_ */ + -- cgit v1.2.3 From 822ebe51342db269164a7dd7a5394e2e5892422d Mon Sep 17 00:00:00 2001 From: Marcel Ziswiler Date: Thu, 18 Oct 2012 12:53:36 +0200 Subject: colibri_t20: nand: change offset handling Rather than relying on hard-coded offsets actually make use of partition table parsing implementation. --- arch/arm/include/asm/global_data.h | 9 ++---- board/toradex/colibri_t20/colibri_t20.dts | 13 -------- board/toradex/common/board.c | 53 +++++++++++++------------------ board/toradex/common/tegra2_nand.c | 9 ------ common/fdt_decode.c | 5 --- include/configs/colibri_t20.h | 3 +- include/fdt_decode.h | 18 ----------- 7 files changed, 26 insertions(+), 84 deletions(-) diff --git a/arch/arm/include/asm/global_data.h b/arch/arm/include/asm/global_data.h index 800f5fe6a5..97cfbf67c6 100644 --- a/arch/arm/include/asm/global_data.h +++ b/arch/arm/include/asm/global_data.h @@ -80,12 +80,9 @@ typedef struct global_data { void **jt; /* jump table */ char env_buf[32]; /* buffer for getenv() before reloc. */ #if defined(CONFIG_COLIBRI_T20) || defined(CONFIG_COLIBRI_T30) - unsigned env_offset; /* offset to the u-boot environment in mass storage */ - unsigned conf_blk_offset; /* offset to the Toradex config block in mass storage */ - unsigned conf_blk_offset2; /* offset to the Toradex config block (WinCE) in mass storage */ - unsigned kernel_offset; /* offset to the kernel in mass storage */ - unsigned rootfs_size; /* size of the rootfs in mass storage */ - unsigned rootfs_offset; /* offset to the rootfs in mass storage */ + unsigned env_offset; /* offset to U-Boot environment */ + unsigned conf_blk_offset; /* offset to Toradex config block */ + unsigned kernel_offset; /* offset to kernel in mass storage */ #endif } gd_t; diff --git a/board/toradex/colibri_t20/colibri_t20.dts b/board/toradex/colibri_t20/colibri_t20.dts index af332c5dfb..fb12612060 100644 --- a/board/toradex/colibri_t20/colibri_t20.dts +++ b/board/toradex/colibri_t20/colibri_t20.dts @@ -159,14 +159,6 @@ * TWHR, Max(tCS, tCH, tALS, tALH), TWH, TWP, TRH, TADL */ timing = <12 100 20 80 20 10 12 10 70>; - - /* - * The offset of the start of - * u-boot-environment config-block config-block (WinCE) kernel rootfs-size rootfs-start - * rootfs: the numbers are concatenated to mtdparts=tegra_nand:K@K(userspace) - * take them from a download with NVFLASH - */ - /* unknown nv-partitions = <0xE00000 0x1000000 0x1000000 0x1200000 1018368 28160>; */ }; /* Colibri T20 256MB V1.2a new */ @@ -180,7 +172,6 @@ skipped-spare-bytes = <4>; page-spare-bytes = <128>; timing = <15 100 25 80 25 10 15 10 100>; - nv-partitions = <0x980000 0x11c0000 0x7380000 0xc80000 503552 19712>; }; /* Colibri T20 before V1.1x aka old */ @@ -194,7 +185,6 @@ skipped-spare-bytes = <4>; page-spare-bytes = <128>; timing = <12 100 20 60 15 10 12 10 70>; - nv-partitions = <0xE00000 0x1880000 0x7900000 0x1200000 1018368 28160>; }; /* Colibri T20 512MB V1.2a intermediate */ @@ -208,7 +198,6 @@ skipped-spare-bytes = <4>; page-spare-bytes = <64>; timing = <12 100 20 80 20 10 12 10 70>; - /* unknown nv-partitions = <0xE00000 0x1880000 0x1880000 0x1200000 1018368 28160>; */ }; /* Colibri T20 512MB V1.2a new */ @@ -222,7 +211,6 @@ skipped-spare-bytes = <4>; page-spare-bytes = <128>; timing = <15 100 25 80 25 10 15 10 100>; - nv-partitions = <0x980000 0x11c0000 0x7380000 0xc80000 1027840 19712>; }; /* Colibri T20 512MB 3.3V TSOP test */ @@ -236,7 +224,6 @@ skipped-spare-bytes = <4>; page-spare-bytes = <64>; timing = <20 100 20 60 20 10 12 10 70>; - nv-partitions = <0x740000 0xE60000 0x1880000 0x9C0000 1032576 15488>; }; nand-controller@0x70008000 { diff --git a/board/toradex/common/board.c b/board/toradex/common/board.c index b4461699b7..ca817eeeb6 100644 --- a/board/toradex/common/board.c +++ b/board/toradex/common/board.c @@ -65,6 +65,8 @@ #include #include +#include "tegra2_partitions.h" + DECLARE_GLOBAL_DATA_PTR; @@ -270,7 +272,7 @@ enum { UART_ALL = 0xf }; -#if defined(BOARD_LATE_INIT) && (defined(CONFIG_TRDX_CFG_BLOCK_OFFSET) || \ +#if defined(BOARD_LATE_INIT) && (defined(CONFIG_TRDX_CFG_BLOCK) || \ defined(CONFIG_REVISION_TAG) || defined(CONFIG_SERIAL_TAG)) static unsigned char *config_block = NULL; #endif @@ -549,7 +551,7 @@ int board_late_init(void) { char env_str[256 ]; -#ifdef CONFIG_TRDX_CFG_BLOCK_OFFSET +#ifdef CONFIG_TRDX_CFG_BLOCK char *addr_str, *end; unsigned char bi_enetaddr[6] = {0, 0, 0, 0, 0, 0}; /* Ethernet address */ int i; @@ -560,16 +562,15 @@ int board_late_init(void) unsigned char toradex_oui[3] = { 0x00, 0x14, 0x2d }; int valid = 0; - unsigned int offset; int ret; -#endif /* CONFIG_TRDX_CFG_BLOCK_OFFSET */ +#endif /* CONFIG_TRDX_CFG_BLOCK */ #ifdef CONFIG_VIDEO_TEGRA /* Make sure we finish initing the LCD */ tegra_lcd_check_next_stage(gd->blob, 1); #endif -#ifdef CONFIG_TRDX_CFG_BLOCK_OFFSET +#ifdef CONFIG_TRDX_CFG_BLOCK /* Allocate RAM area for config block */ config_block = malloc(size); if (!config_block) { @@ -577,31 +578,19 @@ int board_late_init(void) return -1; } - for (i = 0; i < 2; i++) { - if (i == 0) - offset = CONFIG_TRDX_CFG_BLOCK_OFFSET; - else - offset = CONFIG_TRDX_CFG_BLOCK_OFFSET2; - - /* Clear it */ - memset((void *)config_block, 0, size); + /* Clear it */ + memset((void *)config_block, 0, size); - /* Read production parameter config block */ + /* Read production parameter config block */ #ifdef CONFIG_CMD_NAND - ret = nand_read_skip_bad(&nand_info[0], offset, &size, (unsigned char *) config_block); -#endif - /* Check validity */ - if ( (ret==0) && (size>0) ) { - mac_addr = config_block + 8; - if (!(memcmp(mac_addr, toradex_oui, 3))) { - valid = 1; - break; - } - } - else { - /* probably there is no flash, - * give up reading the config block, the nand flash layer crashes on the second attempt */ - break; + ret = nand_read_skip_bad(&nand_info[0], gd->conf_blk_offset, &size, + (unsigned char *) config_block); +#endif + /* Check validity */ + if ((ret == 0) && (size > 0)) { + mac_addr = config_block + 8; + if (!(memcmp(mac_addr, toradex_oui, 3))) { + valid = 1; } } @@ -643,7 +632,7 @@ int board_late_init(void) } } -#endif /* CONFIG_TRDX_CFG_BLOCK_OFFSET */ +#endif /* CONFIG_TRDX_CFG_BLOCK */ /* set the nand kernel offset */ if (!getenv("lnxoffset")) { @@ -653,8 +642,10 @@ int board_late_init(void) /* set the mtdparts string */ if (!getenv("mtdparts")) { - sprintf(env_str, "mtdparts=tegra_nand:%uK@%uK(userspace)", - (unsigned)(gd->rootfs_size), (unsigned)(gd->rootfs_offset) ); + sprintf(env_str, "mtdparts=tegra_nand:"); + i = strlen(env_str); + nvtegra_mtdparts_string(env_str + i, sizeof(env_str) - i); + setenv("mtdparts", env_str); } diff --git a/board/toradex/common/tegra2_nand.c b/board/toradex/common/tegra2_nand.c index c1eaa8f429..1c39f655bd 100644 --- a/board/toradex/common/tegra2_nand.c +++ b/board/toradex/common/tegra2_nand.c @@ -1048,15 +1048,6 @@ int board_nand_init(struct nand_chip *nand) printf("Could not decode NAND flash device node\n"); return -1; } - - //copy partition information to global data - gd->env_offset = (unsigned)(config->nv_partitions[FDT_NAND_ENV_OFFSET]); - gd->conf_blk_offset = (unsigned)(config->nv_partitions[FDT_NAND_CONFIG_OFFSET]); - gd->conf_blk_offset2 = (unsigned)(config->nv_partitions[FDT_NAND_CONFIG_OFFSET2]); - gd->kernel_offset = (unsigned)(config->nv_partitions[FDT_NAND_KERNEL_OFFSET]); - gd->rootfs_size = (unsigned)(config->nv_partitions[FDT_NAND_ROOTFS_LENGTH]); - gd->rootfs_offset = (unsigned)(config->nv_partitions[FDT_NAND_ROOTFS_SIZE]); - if (!config->enabled) return -1; info->reg = config->reg; diff --git a/common/fdt_decode.c b/common/fdt_decode.c index afa070f2d6..bf56186af8 100644 --- a/common/fdt_decode.c +++ b/common/fdt_decode.c @@ -718,11 +718,6 @@ int fdt_decode_nand(const void *blob, int node, struct fdt_nand *config) if (err < 0) return err; - err = get_int_array(blob, node, "nv-partitions", config->nv_partitions, - FDT_NAND_PARTOFFSET_COUNT); - if (err < 0) - return err; - /* Now look up the controller and decode that */ node = lookup_phandle(blob, node, "controller"); if (node < 0) diff --git a/include/configs/colibri_t20.h b/include/configs/colibri_t20.h index 24721ff573..3888ac79b1 100644 --- a/include/configs/colibri_t20.h +++ b/include/configs/colibri_t20.h @@ -59,8 +59,7 @@ #define CONFIG_REVISION_TAG 1 #define CONFIG_SERIAL_TAG 1 -#define CONFIG_TRDX_CFG_BLOCK_OFFSET (gd->conf_blk_offset) -#define CONFIG_TRDX_CFG_BLOCK_OFFSET2 (gd->conf_blk_offset2) +#define CONFIG_TRDX_CFG_BLOCK #define CONFIG_CMD_ASKENV #define CONFIG_CMD_DIAG diff --git a/include/fdt_decode.h b/include/fdt_decode.h index 0969e29dec..7b9e94919c 100644 --- a/include/fdt_decode.h +++ b/include/fdt_decode.h @@ -244,17 +244,6 @@ enum { FDT_NAND_TIMING_COUNT }; -enum { - FDT_NAND_ENV_OFFSET, - FDT_NAND_CONFIG_OFFSET, - FDT_NAND_CONFIG_OFFSET2, - FDT_NAND_KERNEL_OFFSET, - FDT_NAND_ROOTFS_LENGTH, - FDT_NAND_ROOTFS_SIZE, - - FDT_NAND_PARTOFFSET_COUNT -}; - /* Information about an attached NAND chip */ struct fdt_nand { struct nand_ctlr *reg; @@ -273,13 +262,6 @@ struct fdt_nand { int page_spare_bytes; int page_data_bytes; /* Bytes in data area */ int timing[FDT_NAND_TIMING_COUNT]; - /* - * The offset of the start of - * u-boot-environment config-block kernel rootfs-size rootfs-start - * rootfs: the numbers are concatenated to mtdparts=tegra_nand:K@K(userspace) - * take them from a download with NVFLASH - */ - int nv_partitions[FDT_NAND_PARTOFFSET_COUNT]; }; /** -- cgit v1.2.3 From 16a9368a88a28252ea1daedc1df03ccc49ea5b22 Mon Sep 17 00:00:00 2001 From: Marcel Ziswiler Date: Thu, 18 Oct 2012 14:31:10 +0200 Subject: colibri_t20: fix SD boot If booting from SD card BCT contains information specific to SD card partition layout which is bogus if used for NAND partition parsing. Simply fall back to default offset just like in recovery BCT case. Note: in the future we could parse SD partition table as well to more generically support SD booting from various card densities. --- board/toradex/common/tegra2_partitions.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/board/toradex/common/tegra2_partitions.c b/board/toradex/common/tegra2_partitions.c index b8d8bf29ba..c64d5e7299 100644 --- a/board/toradex/common/tegra2_partitions.c +++ b/board/toradex/common/tegra2_partitions.c @@ -103,7 +103,11 @@ int nvtegra_read_partition_table(nvtegra_parttable_t * pt) pt_logical = readw(bct_start + BCT_PTINFO_OFFSET); /* In case we are running with a recovery BCT missing the partition table offset information */ +#ifdef CONFIG_ENV_IS_IN_MMC + if (1) { +#else if (pt_logical == 0) { +#endif /* BCT partition size is 3 M in our default layout */ pt_logical = 3 * 1024 * 1024 / nand_info->writesize; } -- cgit v1.2.3