From 3d6c9afde238d5d5fada82ebdcccc7479e43cabc Mon Sep 17 00:00:00 2001 From: =?utf8?q?Lothar=20Wa=C3=9Fmann?= Date: Mon, 27 Jan 2014 13:53:19 +0100 Subject: [PATCH] karo: tx6: add support for TX6-V2 (eMMC) --- board/karo/common/Makefile | 2 + board/karo/common/fdt.c | 44 -- board/karo/common/karo.h | 35 + board/karo/common/mmc.c | 165 ++++ board/karo/common/nand.c | 167 ++++ board/karo/common/splashimage.c | 132 +--- board/karo/tx6/Makefile | 5 + board/karo/tx6/tx6-1020.c | 1314 +++++++++++++++++++++++++++++++ boards.cfg | 3 + common/cmd_bootce.c | 2 + include/configs/tx6.h | 29 +- 11 files changed, 1721 insertions(+), 177 deletions(-) create mode 100644 board/karo/common/mmc.c create mode 100644 board/karo/common/nand.c create mode 100644 board/karo/tx6/tx6-1020.c diff --git a/board/karo/common/Makefile b/board/karo/common/Makefile index ca8b0f6c36..f951e49dd9 100644 --- a/board/karo/common/Makefile +++ b/board/karo/common/Makefile @@ -26,6 +26,8 @@ ifeq ($(CONFIG_SPL_BUILD),) COBJS-$(CONFIG_OF_BOARD_SETUP) += fdt.o COBJS-$(CONFIG_SPLASH_SCREEN) += splashimage.o endif +COBJS-$(CONFIG_CMD_NAND) += nand.o +COBJS-$(CONFIG_CMD_MMC) += mmc.o COBJS := $(COBJS-y) SOBJS := diff --git a/board/karo/common/fdt.c b/board/karo/common/fdt.c index 979804d45c..ea4b7ebe93 100644 --- a/board/karo/common/fdt.c +++ b/board/karo/common/fdt.c @@ -48,50 +48,6 @@ static void karo_set_fdtsize(void *fdt) setenv_hex("fdtsize", fdt_totalsize(fdt)); } -static int karo_load_part(const char *part, void *addr, size_t len) -{ - int ret; - struct mtd_device *dev; - struct part_info *part_info; - u8 part_num; - size_t actual; - - debug("Initializing mtd_parts\n"); - ret = mtdparts_init(); - if (ret) - return ret; - - debug("Trying to find NAND partition '%s'\n", part); - ret = find_dev_and_part(part, &dev, &part_num, &part_info); - if (ret) { - printf("Failed to find flash partition '%s': %d\n", - part, ret); - - return ret; - } - debug("Found partition '%s': offset=%08x size=%08x\n", - part, part_info->offset, part_info->size); - if (part_info->size < len) { - printf("Warning: partition '%s' smaller than requested size: %u; truncating data to %u byte\n", - part, len, part_info->size); - len = part_info->size; - } - debug("Reading NAND partition '%s' to %p\n", part, addr); - ret = nand_read_skip_bad(&nand_info[0], part_info->offset, &len, - &actual, len, addr); - if (ret) { - printf("Failed to load partition '%s' to %p\n", part, addr); - return ret; - } - if (actual < len) - printf("Read only %u of %u bytes due to bad blocks\n", - actual, len); - - debug("Read %u byte from partition '%s' @ offset %08x\n", - len, part, part_info->offset); - return 0; -} - static void *karo_fdt_load_dtb(void) { int ret; diff --git a/board/karo/common/karo.h b/board/karo/common/karo.h index a28890c743..a4a11ba56b 100644 --- a/board/karo/common/karo.h +++ b/board/karo/common/karo.h @@ -100,4 +100,39 @@ static inline const char *karo_get_vmode(const char *video_mode) return vmode ? vmode + 1 : video_mode; } +#ifdef CONFIG_SPLASH_SCREEN int karo_load_splashimage(int mode); +#else +static inline int karo_load_splashimage(int mode) +{ + return 0; +} +#endif + +#ifdef CONFIG_CMD_NAND +int karo_load_nand_part(const char *part, void *addr, size_t len); +#else +static inline int karo_load_nand_part(const char *part, void *addr, size_t len) +{ + return -EOPNOTSUPP; +} +#endif + +#ifdef CONFIG_CMD_MMC +int karo_load_mmc_part(const char *part, void *addr, size_t len); +#else +static inline int karo_load_mmc_part(const char *part, void *addr, size_t len) +{ + return -EOPNOTSUPP; +} +#endif + +static inline int karo_load_part(const char *part, void *addr, size_t len) +{ + int ret; + + ret = karo_load_nand_part(part, addr, len); + if (ret == -EOPNOTSUPP) + return karo_load_mmc_part(part, addr, len); + return ret; +} diff --git a/board/karo/common/mmc.c b/board/karo/common/mmc.c new file mode 100644 index 0000000000..635220e24b --- /dev/null +++ b/board/karo/common/mmc.c @@ -0,0 +1,165 @@ +/* + * (C) Copyright 2014 Lothar Waßmann + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * 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 General Public License for more details. + * +*/ + +#include +#include +#include +#include +//#include +#include +#include +#include +#include +#include +#include + +#include "karo.h" + +#define CONFIG_MMC_BOOT_DEV 0 + +DECLARE_GLOBAL_DATA_PTR; + +static void __maybe_unused memdmp(void *addr, size_t len) +{ + size_t i; + + for (i = 0; i < len; i+= 16) { + size_t j; + u32 *wp = addr + i; + + debug("%p: ", addr + i); + for (j = 0; j < 4; j++) { + debug(" %08x", wp[j]); + } + debug("\n"); + } +} + +#define MAX_SEARCH_PARTITIONS 16 + +static int find_efi_partition(const char *ifname, int devno, const char *part_str, + block_dev_desc_t **dev_desc, + disk_partition_t *info) +{ + int ret = -1; + char *dup_str = NULL; + int p; + int part; + block_dev_desc_t *dd; + +printf("Searching for partition '%s'\n", part_str); + + dd = get_dev(ifname, devno); + if (!dd || dd->type == DEV_TYPE_UNKNOWN) { + printf("** Bad device %s %d **\n", ifname, devno); + return -1; + } + init_part(dd); + + /* + * No partition table on device, + * or user requested partition 0 (entire device). + */ + if (dd->part_type == PART_TYPE_UNKNOWN) { + printf("** No partition table - %s %d **\n", ifname, + devno); + goto cleanup; + } + + part = 0; + for (p = 1; p <= MAX_SEARCH_PARTITIONS; p++) { + ret = get_partition_info(dd, p, info); + if (ret) + continue; + + if (strcmp((char *)info->name, part_str) == 0) { + part = p; + dd->log2blksz = LOG2(dd->blksz); + break; + } + } + if (!part) { + printf("** No valid partitions found **\n"); + ret = -1; + goto cleanup; + } + + ret = part; + *dev_desc = dd; + +cleanup: + free(dup_str); + return ret; +} + +int karo_load_mmc_part(const char *part, void *addr, size_t len) +{ + int ret; + struct mmc *mmc; + disk_partition_t part_info; + int devno = CONFIG_MMC_BOOT_DEV; + uint blk_start, blk_cnt; + + mmc = find_mmc_device(devno); + if (!mmc) { + printf("Failed to find mmc%u\n", devno); + return -ENODEV; + } + + mmc_init(mmc); + +// mmc_boot_part_access(mmc, 1, part_num, part_num); +#if 1 + block_dev_desc_t *mmc_dev; + + ret = find_efi_partition("mmc", devno, part, &mmc_dev, &part_info); + if (ret < 0) { + printf("eMMC partition '%s' not found: %d\n", part, ret); + goto out; + } + mmc_switch_part(devno, ret); + + blk_start = 0; + blk_cnt = DIV_ROUND_UP(len, part_info.blksz); + + printf("Using mmc%d blksz %lu blks %lu\n", devno, + mmc_dev->blksz, mmc_dev->lba); +#endif + debug("Found partition '%s': offset=%08x size=%08lx\n", + part, blk_start, part_info.size); + if (part_info.size < blk_cnt) { + printf("Warning: partition '%s' smaller than requested size: %u; truncating data to %lu blocks\n", + part, len, part_info.size * mmc->read_bl_len); + blk_cnt = part_info.size; + } + + debug("Reading %u blks from MMC partition '%s' offset %u to %p\n", + blk_cnt, part, blk_start, addr); + ret = mmc->block_dev.block_read(devno, blk_start, blk_cnt, addr); + if (ret == 0) { + printf("Failed to read MMC partition %s\n", part); + goto out; + } + debug("Read %u byte from partition '%s' @ offset %08x\n", + ret * mmc->read_bl_len, part, blk_start); + memdmp(addr, 512); + ret = 0; +out: +// mmc_boot_part_access(mmc, 1, part_num, 0); + mmc_switch_part(devno, 0); + return ret; +} diff --git a/board/karo/common/nand.c b/board/karo/common/nand.c new file mode 100644 index 0000000000..46fbf76c65 --- /dev/null +++ b/board/karo/common/nand.c @@ -0,0 +1,167 @@ +/* + * (C) Copyright 2014 Lothar Waßmann + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * 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 General Public License for more details. + * +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "karo.h" + +#ifdef CONFIG_MAX_DTB_SIZE +#define MAX_DTB_SIZE CONFIG_MAX_DTB_SIZE +#else +#define MAX_DTB_SIZE SZ_64K +#endif + +DECLARE_GLOBAL_DATA_PTR; + +int karo_load_nand_part(const char *part, void *addr, size_t len) +{ + int ret; + struct mtd_device *dev; + struct part_info *part_info; + u8 part_num; + size_t actual; + + debug("Initializing mtd_parts\n"); + ret = mtdparts_init(); + if (ret) + return ret; + + debug("Trying to find NAND partition '%s'\n", part); + ret = find_dev_and_part(part, &dev, &part_num, &part_info); + if (ret) { + printf("Failed to find flash partition '%s': %d\n", + part, ret); + + return ret; + } + debug("Found partition '%s': offset=%08x size=%08x\n", + part, part_info->offset, part_info->size); + if (part_info->size < len) { + printf("Warning: partition '%s' smaller than requested size: %u; truncating data to %u byte\n", + part, len, part_info->size); + len = part_info->size; + } + debug("Reading NAND partition '%s' to %p\n", part, addr); + ret = nand_read_skip_bad(&nand_info[0], part_info->offset, &len, + &actual, len, addr); + if (ret) { + printf("Failed to load partition '%s' to %p\n", part, addr); + return ret; + } + if (actual < len) + printf("Read only %u of %u bytes due to bad blocks\n", + actual, len); + + debug("Read %u byte from partition '%s' @ offset %08x\n", + len, part, part_info->offset); + return 0; +} + +#ifdef CONFIG_SPLASH_SCREEN_ +static int erase_flash(loff_t offs, size_t len) +{ + nand_erase_options_t nand_erase_options; + + memset(&nand_erase_options, 0, sizeof(nand_erase_options)); + nand_erase_options.length = len; + nand_erase_options.offset = offs; + + return nand_erase_opts(&nand_info[0], &nand_erase_options); +} + +int do_fbdump(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) +{ + int ret; + size_t fbsize = calc_fbsize(); + const char *part = "logo"; + struct mtd_device *dev; + struct part_info *part_info; + u8 part_num; + u_char *addr = (u_char *)gd->fb_base; + size_t actual; + + if (argc > 2) + return CMD_RET_USAGE; + + if (argc == 2) + part = argv[1]; + + if (!addr) { + printf("fb address unknown\n"); + return CMD_RET_FAILURE; + } + + debug("Initializing mtd_parts\n"); + ret = mtdparts_init(); + if (ret) + return ret; + + debug("Trying to find NAND partition '%s'\n", part); + ret = find_dev_and_part(part, &dev, &part_num, + &part_info); + if (ret) { + printf("Failed to find flash partition '%s': %d\n", + part, ret); + + return ret; + } + debug("Found partition '%s': offset=%08x size=%08x\n", + part, part_info->offset, part_info->size); + if (part_info->size < fbsize) { + printf("Error: partition '%s' smaller than frame buffer size: %u\n", + part, fbsize); + return CMD_RET_FAILURE; + } + debug("Writing framebuffer %p to NAND partition '%s'\n", + addr, part); + + ret = erase_flash(part_info->offset, fbsize); + if (ret) { + printf("Failed to erase partition '%s'\n", part); + return CMD_RET_FAILURE; + } + + ret = nand_write_skip_bad(&nand_info[0], part_info->offset, + &fbsize, &actual, part_info->size, + addr, WITH_DROP_FFS); + if (ret) { + printf("Failed to write partition '%s'\n", part); + return ret; + } + if (actual < fbsize) + printf("Wrote only %u of %u bytes due to bad blocks\n", + actual, fbsize); + + debug("Wrote %u byte from %p to partition '%s' @ offset %08x\n", + fbsize, addr, part, part_info->offset); + + return CMD_RET_SUCCESS; +} + +U_BOOT_CMD(fbdump, 2, 0, do_fbdump, "dump framebuffer contents to flash", + "[partition name]\n" + " default partition name: 'logo'\n"); +#endif diff --git a/board/karo/common/splashimage.c b/board/karo/common/splashimage.c index bd1b64c8aa..f7d93e536d 100644 --- a/board/karo/common/splashimage.c +++ b/board/karo/common/splashimage.c @@ -21,52 +21,9 @@ #include #include -DECLARE_GLOBAL_DATA_PTR; - -static int karo_load_part(const char *part, void *addr, size_t len) -{ - int ret; - struct mtd_device *dev; - struct part_info *part_info; - u8 part_num; - size_t actual; +#include "karo.h" - debug("Initializing mtd_parts\n"); - ret = mtdparts_init(); - if (ret) - return ret; - - debug("Trying to find NAND partition '%s'\n", part); - ret = find_dev_and_part(part, &dev, &part_num, - &part_info); - if (ret) { - printf("Failed to find flash partition '%s': %d\n", - part, ret); - - return ret; - } - debug("Found partition '%s': offset=%08x size=%08x\n", - part, part_info->offset, part_info->size); - if (part_info->size < len) { - printf("Warning: partition '%s' smaller than requested size: %u; truncating data to %u byte\n", - part, len, part_info->size); - len = part_info->size; - } - debug("Reading NAND partition '%s' to %p\n", part, addr); - ret = nand_read_skip_bad(&nand_info[0], part_info->offset, &len, - &actual, len, addr); - if (ret) { - printf("Failed to load partition '%s' to %p\n", part, addr); - return ret; - } - if (actual < len) - printf("Read only %u of %u bytes due to bad blocks\n", - actual, len); - - debug("Read %u byte from partition '%s' @ offset %08x\n", - len, part, part_info->offset); - return 0; -} +DECLARE_GLOBAL_DATA_PTR; static ulong calc_fbsize(void) { @@ -77,7 +34,6 @@ static ulong calc_fbsize(void) int karo_load_splashimage(int mode) { int ret; - int do_nand(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]); unsigned long la = gd->fb_base; char *splashimage = getenv("splashimage"); ulong fbsize = calc_fbsize(); @@ -106,87 +62,3 @@ int karo_load_splashimage(int mode) } return 0; } - -static int erase_flash(loff_t offs, size_t len) -{ - nand_erase_options_t nand_erase_options; - - memset(&nand_erase_options, 0, sizeof(nand_erase_options)); - nand_erase_options.length = len; - nand_erase_options.offset = offs; - - return nand_erase_opts(&nand_info[0], &nand_erase_options); -} - -int do_fbdump(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) -{ - int ret; - size_t fbsize = calc_fbsize(); - const char *part = "logo"; - struct mtd_device *dev; - struct part_info *part_info; - u8 part_num; - u_char *addr = (u_char *)gd->fb_base; - size_t actual; - - if (argc > 2) - return CMD_RET_USAGE; - - if (argc == 2) - part = argv[1]; - - if (!addr) { - printf("fb address unknown\n"); - return CMD_RET_FAILURE; - } - - debug("Initializing mtd_parts\n"); - ret = mtdparts_init(); - if (ret) - return ret; - - debug("Trying to find NAND partition '%s'\n", part); - ret = find_dev_and_part(part, &dev, &part_num, - &part_info); - if (ret) { - printf("Failed to find flash partition '%s': %d\n", - part, ret); - - return ret; - } - debug("Found partition '%s': offset=%08x size=%08x\n", - part, part_info->offset, part_info->size); - if (part_info->size < fbsize) { - printf("Error: partition '%s' smaller than frame buffer size: %u\n", - part, fbsize); - return CMD_RET_FAILURE; - } - debug("Writing framebuffer %p to NAND partition '%s'\n", - addr, part); - - ret = erase_flash(part_info->offset, fbsize); - if (ret) { - printf("Failed to erase partition '%s'\n", part); - return CMD_RET_FAILURE; - } - - ret = nand_write_skip_bad(&nand_info[0], part_info->offset, - &fbsize, &actual, part_info->size, - addr, WITH_DROP_FFS); - if (ret) { - printf("Failed to write partition '%s'\n", part); - return ret; - } - if (actual < fbsize) - printf("Wrote only %u of %u bytes due to bad blocks\n", - actual, fbsize); - - debug("Wrote %u byte from %p to partition '%s' @ offset %08x\n", - fbsize, addr, part, part_info->offset); - - return CMD_RET_SUCCESS; -} - -U_BOOT_CMD(fbdump, 2, 0, do_fbdump, "dump framebuffer contents to flash", - "[partition name]\n" - " default partition name: 'logo'\n"); diff --git a/board/karo/tx6/Makefile b/board/karo/tx6/Makefile index 37c90e7620..d7f169031a 100644 --- a/board/karo/tx6/Makefile +++ b/board/karo/tx6/Makefile @@ -9,7 +9,12 @@ include $(TOPDIR)/config.mk LIB = $(obj)lib$(BOARD).o +ifeq ($(CONFIG_TX6_V2),) COBJS := tx6qdl.o +else +COBJS := tx6-1020.o +endif + SOBJS := lowlevel_init.o ifeq ($(CONFIG_CMD_ROMUPDATE),y) COBJS += flash.o diff --git a/board/karo/tx6/tx6-1020.c b/board/karo/tx6/tx6-1020.c new file mode 100644 index 0000000000..4f64a6fdd5 --- /dev/null +++ b/board/karo/tx6/tx6-1020.c @@ -0,0 +1,1314 @@ +/* + * Copyright (C) 2012,2013 Lothar Waßmann + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * 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 General Public License for more details. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../common/karo.h" + +#define TX6_FEC_RST_GPIO IMX_GPIO_NR(7, 6) +#define TX6_FEC_PWR_GPIO IMX_GPIO_NR(3, 20) +#define TX6_FEC_INT_GPIO IMX_GPIO_NR(7, 1) +#define TX6_LED_GPIO IMX_GPIO_NR(2, 20) + +#define TX6_LCD_PWR_GPIO IMX_GPIO_NR(2, 31) +#define TX6_LCD_RST_GPIO IMX_GPIO_NR(3, 29) +#define TX6_LCD_BACKLIGHT_GPIO IMX_GPIO_NR(1, 1) + +#define TX6_RESET_OUT_GPIO IMX_GPIO_NR(7, 12) + +#define TEMPERATURE_MIN -40 +#define TEMPERATURE_HOT 80 +#define TEMPERATURE_MAX 125 + +DECLARE_GLOBAL_DATA_PTR; + +#define MUX_CFG_SION IOMUX_PAD(0, 0, IOMUX_CONFIG_SION, 0, 0, 0) + +static const iomux_v3_cfg_t tx6qdl_pads[] = { + /* RESET_OUT */ + MX6_PAD_GPIO_17__GPIO_7_12, + + /* UART pads */ +#if CONFIG_MXC_UART_BASE == UART1_BASE + MX6_PAD_SD3_DAT7__UART1_TXD, + MX6_PAD_SD3_DAT6__UART1_RXD, + MX6_PAD_SD3_DAT1__UART1_RTS, + MX6_PAD_SD3_DAT0__UART1_CTS, +#endif +#if CONFIG_MXC_UART_BASE == UART2_BASE + MX6_PAD_SD4_DAT4__UART2_RXD, + MX6_PAD_SD4_DAT7__UART2_TXD, + MX6_PAD_SD4_DAT5__UART2_RTS, + MX6_PAD_SD4_DAT6__UART2_CTS, +#endif +#if CONFIG_MXC_UART_BASE == UART3_BASE + MX6_PAD_EIM_D24__UART3_TXD, + MX6_PAD_EIM_D25__UART3_RXD, + MX6_PAD_SD3_RST__UART3_RTS, + MX6_PAD_SD3_DAT3__UART3_CTS, +#endif + /* internal I2C */ + MX6_PAD_EIM_D28__I2C1_SDA, + MX6_PAD_EIM_D21__I2C1_SCL, + + /* FEC PHY GPIO functions */ + MX6_PAD_EIM_D20__GPIO_3_20 | MUX_CFG_SION, /* PHY POWER */ + MX6_PAD_SD3_DAT2__GPIO_7_6 | MUX_CFG_SION, /* PHY RESET */ + MX6_PAD_SD3_DAT4__GPIO_7_1, /* PHY INT */ +}; + +static const iomux_v3_cfg_t tx6qdl_fec_pads[] = { + /* FEC functions */ + MX6_PAD_ENET_MDC__ENET_MDC, + MX6_PAD_ENET_MDIO__ENET_MDIO, + MX6_PAD_GPIO_16__ENET_ANATOP_ETHERNET_REF_OUT, + MX6_PAD_ENET_RX_ER__ENET_RX_ER, + MX6_PAD_ENET_CRS_DV__ENET_RX_EN, + MX6_PAD_ENET_RXD1__ENET_RDATA_1, + MX6_PAD_ENET_RXD0__ENET_RDATA_0, + MX6_PAD_ENET_TX_EN__ENET_TX_EN, + MX6_PAD_ENET_TXD1__ENET_TDATA_1, + MX6_PAD_ENET_TXD0__ENET_TDATA_0, +}; + +static const struct gpio tx6qdl_gpios[] = { + { TX6_RESET_OUT_GPIO, GPIOF_OUTPUT_INIT_HIGH, "#RESET_OUT", }, + { TX6_FEC_PWR_GPIO, GPIOF_OUTPUT_INIT_HIGH, "FEC PHY PWR", }, + { TX6_FEC_RST_GPIO, GPIOF_OUTPUT_INIT_LOW, "FEC PHY RESET", }, + { TX6_FEC_INT_GPIO, GPIOF_INPUT, "FEC PHY INT", }, +}; + +/* + * Functions + */ +/* placed in section '.data' to prevent overwriting relocation info + * overlayed with bss + */ +static u32 wrsr __attribute__((section(".data"))); + +#define WRSR_POR (1 << 4) +#define WRSR_TOUT (1 << 1) +#define WRSR_SFTW (1 << 0) + +static void print_reset_cause(void) +{ + struct src *src_regs = (struct src *)SRC_BASE_ADDR; + void __iomem *wdt_base = (void __iomem *)WDOG1_BASE_ADDR; + u32 srsr; + char *dlm = ""; + + printf("Reset cause: "); + + srsr = readl(&src_regs->srsr); + wrsr = readw(wdt_base + 4); + + if (wrsr & WRSR_POR) { + printf("%sPOR", dlm); + dlm = " | "; + } + if (srsr & 0x00004) { + printf("%sCSU", dlm); + dlm = " | "; + } + if (srsr & 0x00008) { + printf("%sIPP USER", dlm); + dlm = " | "; + } + if (srsr & 0x00010) { + if (wrsr & WRSR_SFTW) { + printf("%sSOFT", dlm); + dlm = " | "; + } + if (wrsr & WRSR_TOUT) { + printf("%sWDOG", dlm); + dlm = " | "; + } + } + if (srsr & 0x00020) { + printf("%sJTAG HIGH-Z", dlm); + dlm = " | "; + } + if (srsr & 0x00040) { + printf("%sJTAG SW", dlm); + dlm = " | "; + } + if (srsr & 0x10000) { + printf("%sWARM BOOT", dlm); + dlm = " | "; + } + if (dlm[0] == '\0') + printf("unknown"); + + printf("\n"); +} + +int read_cpu_temperature(void); +int check_cpu_temperature(int boot); + +static void tx6qdl_print_cpuinfo(void) +{ + u32 cpurev = get_cpu_rev(); + char *cpu_str = "?"; + + switch ((cpurev >> 12) & 0xff) { + case MXC_CPU_MX6SL: + cpu_str = "SL"; + break; + case MXC_CPU_MX6DL: + cpu_str = "DL"; + break; + case MXC_CPU_MX6SOLO: + cpu_str = "SOLO"; + break; + case MXC_CPU_MX6Q: + cpu_str = "Q"; + break; + } + + printf("CPU: Freescale i.MX6%s rev%d.%d at %d MHz\n", + cpu_str, + (cpurev & 0x000F0) >> 4, + (cpurev & 0x0000F) >> 0, + mxc_get_clock(MXC_ARM_CLK) / 1000000); + + print_reset_cause(); + check_cpu_temperature(1); +} + +#define RN5T618_NOETIMSET 0x11 +#define RN5T618_LDORTC1_SLOT 0x2a +#define RN5T618_DC1CTL 0x2c +#define RN5T618_DC1CTL2 0x2d +#define RN5T618_DC2CTL 0x2e +#define RN5T618_DC2CTL2 0x2f +#define RN5T618_DC3CTL 0x30 +#define RN5T618_DC3CTL2 0x31 +#define RN5T618_DC1DAC 0x36 /* CORE */ +#define RN5T618_DC2DAC 0x37 /* SOC */ +#define RN5T618_DC3DAC 0x38 /* DDR */ +#define RN5T618_DC1DAC_SLP 0x3b +#define RN5T618_DC2DAC_SLP 0x3c +#define RN5T618_DC3DAC_SLP 0x3d +#define RN5T618_LDOEN1 0x44 +#define RN5T618_LDODIS 0x46 +#define RN5T618_LDOEN2 0x48 +#define RN5T618_LDO3DAC 0x4e /* IO */ +#define RN5T618_LDORTCDAC 0x56 /* VBACKUP */ + +#define VDD_RTC_VAL mV_to_regval_rtc(3000 * 10) +#define VDD_HIGH_VAL mV_to_regval3(3000 * 10) +#define VDD_HIGH_VAL_LP mV_to_regval3(3000 * 10) +#define VDD_CORE_VAL mV_to_regval(1425 * 10) +#define VDD_CORE_VAL_LP mV_to_regval(900 * 10) +#define VDD_SOC_VAL mV_to_regval(1425 * 10) +#define VDD_SOC_VAL_LP mV_to_regval(900 * 10) +#define VDD_DDR_VAL mV_to_regval(1350 * 10) +#define VDD_DDR_VAL_LP mV_to_regval(1350 * 10) + +/* calculate voltages in 10mV */ +#define mV_to_regval(mV) DIV_ROUND(((((mV) < 6000) ? 6000 : (mV)) - 6000), 125) +#define regval_to_mV(v) (((v) * 125 + 6000)) + +#define mV_to_regval2(mV) DIV_ROUND(((((mV) < 9000) ? 9000 : (mV)) - 9000), 250) +#define regval2_to_mV(v) (((v) * 250 + 9000)) + +#define mV_to_regval3(mV) DIV_ROUND(((((mV) < 6000) ? 6000 : (mV)) - 6000), 250) +#define regval3_to_mV(v) (((v) * 250 + 6000)) + +#define mV_to_regval_rtc(mV) DIV_ROUND(((((mV) < 17000) ? 17000 : (mV)) - 17000), 250) +#define regval_rtc_to_mV(v) (((v) * 250 + 17000)) + +static struct rn5t618_regs { + u8 addr; + u8 val; + u8 mask; +} rn5t618_regs[] = { + { RN5T618_NOETIMSET, 0, }, + { RN5T618_DC1DAC, VDD_CORE_VAL, }, + { RN5T618_DC2DAC, VDD_SOC_VAL, }, + { RN5T618_DC3DAC, VDD_DDR_VAL, }, + { RN5T618_DC1DAC_SLP, VDD_CORE_VAL_LP, }, + { RN5T618_DC2DAC_SLP, VDD_SOC_VAL_LP, }, + { RN5T618_DC3DAC_SLP, VDD_DDR_VAL_LP, }, + { RN5T618_LDOEN1, 0x04, ~0x1f, }, + { RN5T618_LDOEN2, 0x10, ~0x30, }, + { RN5T618_LDODIS, 0x00, }, + { RN5T618_LDO3DAC, VDD_HIGH_VAL, }, + { RN5T618_LDORTCDAC, VDD_RTC_VAL, }, + { RN5T618_LDORTC1_SLOT, 0x0f, ~0x3f, }, +}; + +static int tx6_rn5t618_setup_regs(struct rn5t618_regs *r, size_t count) +{ + int ret; + int i; + + for (i = 0; i < count; i++, r++) { +#ifdef DEBUG + unsigned char value; + + ret = i2c_read(CONFIG_SYS_I2C_SLAVE, r->addr, 1, &value, 1); + if ((value & ~r->mask) != r->val) { + printf("Changing PMIC reg %02x from %02x to %02x\n", + r->addr, value, r->val); + } + if (ret) { + printf("%s: failed to read PMIC register %02x: %d\n", + __func__, r->addr, ret); + return ret; + } +#endif + ret = i2c_write(CONFIG_SYS_I2C_SLAVE, + r->addr, 1, &r->val, 1); + if (ret) { + printf("%s: failed to write PMIC register %02x: %d\n", + __func__, r->addr, ret); + return ret; + } +#ifdef DEBUG + ret = i2c_read(CONFIG_SYS_I2C_SLAVE, r->addr, 1, &value, 1); + printf("PMIC reg %02x is %02x\n", r->addr, value); +#endif + } + return 0; +} + +static int setup_pmic_voltages(void) +{ + int ret; + unsigned char value; + + ret = i2c_probe(CONFIG_SYS_I2C_SLAVE); + if (ret != 0) { + printf("Failed to initialize I2C\n"); + return ret; + } + + ret = i2c_read(CONFIG_SYS_I2C_SLAVE, 0x11, 1, &value, 1); + if (ret) { + printf("%s: i2c_read error: %d\n", __func__, ret); + return ret; + } + + ret = tx6_rn5t618_setup_regs(rn5t618_regs, ARRAY_SIZE(rn5t618_regs)); + if (ret) + return ret; + + printf("VDDCORE set to %umV\n", + DIV_ROUND(regval_to_mV(VDD_CORE_VAL), 10)); + printf("VDDSOC set to %umV\n", + DIV_ROUND(regval_to_mV(VDD_SOC_VAL), 10)); + + return ret; +} + +int board_early_init_f(void) +{ + gpio_request_array(tx6qdl_gpios, ARRAY_SIZE(tx6qdl_gpios)); + imx_iomux_v3_setup_multiple_pads(tx6qdl_pads, ARRAY_SIZE(tx6qdl_pads)); + + return 0; +} + +int board_init(void) +{ + int ret; + + /* Address of boot parameters */ + gd->bd->bi_boot_params = PHYS_SDRAM_1 + 0x1000; + gd->bd->bi_arch_number = -1; + + if (ctrlc()) { + printf("CTRL-C detected; Skipping PMIC setup\n"); + return 1; + } + + ret = setup_pmic_voltages(); + if (ret) { + printf("Failed to setup PMIC voltages\n"); + hang(); + } + return 0; +} + +int dram_init(void) +{ + /* dram_init must store complete ramsize in gd->ram_size */ + gd->ram_size = get_ram_size((void *)CONFIG_SYS_SDRAM_BASE, + PHYS_SDRAM_1_SIZE); + return 0; +} + +void dram_init_banksize(void) +{ + gd->bd->bi_dram[0].start = PHYS_SDRAM_1; + gd->bd->bi_dram[0].size = get_ram_size((void *)PHYS_SDRAM_1, + PHYS_SDRAM_1_SIZE); +#if CONFIG_NR_DRAM_BANKS > 1 + gd->bd->bi_dram[1].start = PHYS_SDRAM_2; + gd->bd->bi_dram[1].size = get_ram_size((void *)PHYS_SDRAM_2, + PHYS_SDRAM_2_SIZE); +#endif +} + +#ifdef CONFIG_CMD_MMC +#define USDHC_PAD_CTRL (PAD_CTL_PUS_47K_UP | \ + PAD_CTL_SPEED_LOW | PAD_CTL_DSE_80ohm | \ + PAD_CTL_SRE_FAST | PAD_CTL_HYS) + +static const iomux_v3_cfg_t mmc0_pads[] = { + MX6_PAD_SD1_CMD__USDHC1_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD1_CLK__USDHC1_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD1_DAT0__USDHC1_DAT0 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD1_DAT1__USDHC1_DAT1 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD1_DAT2__USDHC1_DAT2 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD1_DAT3__USDHC1_DAT3 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + /* SD1 CD */ + MX6_PAD_SD3_CMD__GPIO_7_2, +}; + +static const iomux_v3_cfg_t mmc1_pads[] = { + MX6_PAD_SD2_CMD__USDHC2_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD2_CLK__USDHC2_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD2_DAT0__USDHC2_DAT0 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD2_DAT1__USDHC2_DAT1 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD2_DAT2__USDHC2_DAT2 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD2_DAT3__USDHC2_DAT3 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + /* SD2 CD */ + MX6_PAD_SD3_CLK__GPIO_7_3, +}; + +static const iomux_v3_cfg_t mmc4_pads[] = { + MX6_PAD_SD4_CMD__USDHC4_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD4_CLK__USDHC4_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD4_DAT0__USDHC4_DAT0 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD4_DAT1__USDHC4_DAT1 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD4_DAT2__USDHC4_DAT2 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD4_DAT3__USDHC4_DAT3 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_NANDF_ALE__USDHC4_RST, +}; + +static struct tx6_esdhc_cfg { + const iomux_v3_cfg_t *pads; + int num_pads; + enum mxc_clock clkid; + struct fsl_esdhc_cfg cfg; + int cd_gpio; +} tx6qdl_esdhc_cfg[] = { + { + .pads = mmc0_pads, + .num_pads = ARRAY_SIZE(mmc0_pads), + .clkid = MXC_ESDHC_CLK, + .cfg = { + .esdhc_base = (void __iomem *)USDHC1_BASE_ADDR, + .max_bus_width = 4, + }, + .cd_gpio = IMX_GPIO_NR(7, 2), + }, + { + .pads = mmc1_pads, + .num_pads = ARRAY_SIZE(mmc1_pads), + .clkid = MXC_ESDHC2_CLK, + .cfg = { + .esdhc_base = (void __iomem *)USDHC2_BASE_ADDR, + .max_bus_width = 4, + }, + .cd_gpio = IMX_GPIO_NR(7, 3), + }, + { + .pads = mmc4_pads, + .num_pads = ARRAY_SIZE(mmc4_pads), + .clkid = MXC_ESDHC4_CLK, + .cfg = { + .esdhc_base = (void __iomem *)USDHC4_BASE_ADDR, + .max_bus_width = 4, + }, + .cd_gpio = -EINVAL, + }, +}; + +static inline struct tx6_esdhc_cfg *to_tx6_esdhc_cfg(struct fsl_esdhc_cfg *cfg) +{ + return container_of(cfg, struct tx6_esdhc_cfg, cfg); +} + +int board_mmc_getcd(struct mmc *mmc) +{ + struct tx6_esdhc_cfg *cfg = to_tx6_esdhc_cfg(mmc->priv); + + if (cfg->cd_gpio < 0) + return 1; + + debug("SD card %d is %spresent\n", + cfg - tx6qdl_esdhc_cfg, + gpio_get_value(cfg->cd_gpio) ? "NOT " : ""); + return !gpio_get_value(cfg->cd_gpio); +} + +int board_mmc_init(bd_t *bis) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(tx6qdl_esdhc_cfg); i++) { + struct mmc *mmc; + struct tx6_esdhc_cfg *cfg = &tx6qdl_esdhc_cfg[i]; + int ret; + + cfg->cfg.sdhc_clk = mxc_get_clock(cfg->clkid); + imx_iomux_v3_setup_multiple_pads(cfg->pads, cfg->num_pads); + + if (cfg->cd_gpio >= 0) { + ret = gpio_request_one(cfg->cd_gpio, + GPIOF_INPUT, "MMC CD"); + if (ret) { + printf("Error %d requesting GPIO%d_%d\n", + ret, cfg->cd_gpio / 32, cfg->cd_gpio % 32); + continue; + } + } + + debug("%s: Initializing MMC slot %d\n", __func__, i); + fsl_esdhc_initialize(bis, &cfg->cfg); + + mmc = find_mmc_device(i); + if (mmc == NULL) + continue; + if (board_mmc_getcd(mmc)) + mmc_init(mmc); + } + return 0; +} +#endif /* CONFIG_CMD_MMC */ + +#ifdef CONFIG_FEC_MXC + +#define FEC_PAD_CTL (PAD_CTL_DVS | PAD_CTL_DSE_HIGH | \ + PAD_CTL_SRE_FAST) +#define FEC_PAD_CTL2 (PAD_CTL_DVS | PAD_CTL_SRE_FAST) +#define GPIO_PAD_CTL (PAD_CTL_DVS | PAD_CTL_DSE_HIGH) + +#ifndef ETH_ALEN +#define ETH_ALEN 6 +#endif + +int board_eth_init(bd_t *bis) +{ + int ret; + + /* delay at least 21ms for the PHY internal POR signal to deassert */ + udelay(22000); + + imx_iomux_v3_setup_multiple_pads(tx6qdl_fec_pads, ARRAY_SIZE(tx6qdl_fec_pads)); + + /* Deassert RESET to the external phy */ + gpio_set_value(TX6_FEC_RST_GPIO, 1); + + ret = cpu_eth_init(bis); + if (ret) + printf("cpu_eth_init() failed: %d\n", ret); + + return ret; +} +#endif /* CONFIG_FEC_MXC */ + +enum { + LED_STATE_INIT = -1, + LED_STATE_OFF, + LED_STATE_ON, +}; + +static inline int calc_blink_rate(int tmp) +{ + return CONFIG_SYS_HZ + CONFIG_SYS_HZ / 10 - + (tmp - TEMPERATURE_MIN) * CONFIG_SYS_HZ / + (TEMPERATURE_HOT - TEMPERATURE_MIN); +} + +void show_activity(int arg) +{ + static int led_state = LED_STATE_INIT; + static int blink_rate; + static ulong last; + + if (led_state == LED_STATE_INIT) { + last = get_timer(0); + gpio_set_value(TX6_LED_GPIO, 1); + led_state = LED_STATE_ON; + blink_rate = calc_blink_rate(check_cpu_temperature(0)); + } else { + if (get_timer(last) > blink_rate) { + blink_rate = calc_blink_rate(check_cpu_temperature(0)); + last = get_timer_masked(); + if (led_state == LED_STATE_ON) { + gpio_set_value(TX6_LED_GPIO, 0); + } else { + gpio_set_value(TX6_LED_GPIO, 1); + } + led_state = 1 - led_state; + } + } +} + +static const iomux_v3_cfg_t stk5_pads[] = { + /* SW controlled LED on STK5 baseboard */ + MX6_PAD_EIM_A18__GPIO_2_20, + + /* LCD data pins */ + MX6_PAD_DISP0_DAT0__IPU1_DISP0_DAT_0, + MX6_PAD_DISP0_DAT1__IPU1_DISP0_DAT_1, + MX6_PAD_DISP0_DAT2__IPU1_DISP0_DAT_2, + MX6_PAD_DISP0_DAT3__IPU1_DISP0_DAT_3, + MX6_PAD_DISP0_DAT4__IPU1_DISP0_DAT_4, + MX6_PAD_DISP0_DAT5__IPU1_DISP0_DAT_5, + MX6_PAD_DISP0_DAT6__IPU1_DISP0_DAT_6, + MX6_PAD_DISP0_DAT7__IPU1_DISP0_DAT_7, + MX6_PAD_DISP0_DAT8__IPU1_DISP0_DAT_8, + MX6_PAD_DISP0_DAT9__IPU1_DISP0_DAT_9, + MX6_PAD_DISP0_DAT10__IPU1_DISP0_DAT_10, + MX6_PAD_DISP0_DAT11__IPU1_DISP0_DAT_11, + MX6_PAD_DISP0_DAT12__IPU1_DISP0_DAT_12, + MX6_PAD_DISP0_DAT13__IPU1_DISP0_DAT_13, + MX6_PAD_DISP0_DAT14__IPU1_DISP0_DAT_14, + MX6_PAD_DISP0_DAT15__IPU1_DISP0_DAT_15, + MX6_PAD_DISP0_DAT16__IPU1_DISP0_DAT_16, + MX6_PAD_DISP0_DAT17__IPU1_DISP0_DAT_17, + MX6_PAD_DISP0_DAT18__IPU1_DISP0_DAT_18, + MX6_PAD_DISP0_DAT19__IPU1_DISP0_DAT_19, + MX6_PAD_DISP0_DAT20__IPU1_DISP0_DAT_20, + MX6_PAD_DISP0_DAT21__IPU1_DISP0_DAT_21, + MX6_PAD_DISP0_DAT22__IPU1_DISP0_DAT_22, + MX6_PAD_DISP0_DAT23__IPU1_DISP0_DAT_23, + MX6_PAD_DI0_PIN2__IPU1_DI0_PIN2, /* HSYNC */ + MX6_PAD_DI0_PIN3__IPU1_DI0_PIN3, /* VSYNC */ + MX6_PAD_DI0_PIN15__IPU1_DI0_PIN15, /* OE_ACD */ + MX6_PAD_DI0_DISP_CLK__IPU1_DI0_DISP_CLK, /* LSCLK */ + + /* I2C bus on DIMM pins 40/41 */ + MX6_PAD_GPIO_6__I2C3_SDA, + MX6_PAD_GPIO_3__I2C3_SCL, + + /* TSC200x PEN IRQ */ + MX6_PAD_EIM_D26__GPIO_3_26, + + /* EDT-FT5x06 Polytouch panel */ + MX6_PAD_NANDF_CS2__GPIO_6_15, /* IRQ */ + MX6_PAD_EIM_A16__GPIO_2_22, /* RESET */ + MX6_PAD_EIM_A17__GPIO_2_21, /* WAKE */ + + /* USBH1 */ + MX6_PAD_EIM_D31__GPIO_3_31, /* VBUSEN */ + MX6_PAD_EIM_D30__GPIO_3_30, /* OC */ + /* USBOTG */ + MX6_PAD_EIM_D23__GPIO_3_23, /* USBOTG ID */ + MX6_PAD_GPIO_7__GPIO_1_7, /* VBUSEN */ + MX6_PAD_GPIO_8__GPIO_1_8, /* OC */ +}; + +static const struct gpio stk5_gpios[] = { + { TX6_LED_GPIO, GPIOF_OUTPUT_INIT_LOW, "HEARTBEAT LED", }, + + { IMX_GPIO_NR(3, 23), GPIOF_INPUT, "USBOTG ID", }, + { IMX_GPIO_NR(1, 8), GPIOF_INPUT, "USBOTG OC", }, + { IMX_GPIO_NR(1, 7), GPIOF_OUTPUT_INIT_LOW, "USBOTG VBUS enable", }, + { IMX_GPIO_NR(3, 30), GPIOF_INPUT, "USBH1 OC", }, + { IMX_GPIO_NR(3, 31), GPIOF_OUTPUT_INIT_LOW, "USBH1 VBUS enable", }, +}; + +#ifdef CONFIG_LCD +static u16 tx6_cmap[256]; +vidinfo_t panel_info = { + /* set to max. size supported by SoC */ + .vl_col = 1920, + .vl_row = 1080, + + .vl_bpix = LCD_COLOR24, /* Bits per pixel, 0: 1bpp, 1: 2bpp, 2: 4bpp, 3: 8bpp ... */ + .cmap = tx6_cmap, +}; + +static struct fb_videomode tx6_fb_modes[] = { +#ifndef CONFIG_SYS_LVDS_IF + { + /* Standard VGA timing */ + .name = "VGA", + .refresh = 60, + .xres = 640, + .yres = 480, + .pixclock = KHZ2PICOS(25175), + .left_margin = 48, + .hsync_len = 96, + .right_margin = 16, + .upper_margin = 31, + .vsync_len = 2, + .lower_margin = 12, + .sync = FB_SYNC_CLK_LAT_FALL, + }, + { + /* Emerging ETV570 640 x 480 display. Syncs low active, + * DE high active, 115.2 mm x 86.4 mm display area + * VGA compatible timing + */ + .name = "ETV570", + .refresh = 60, + .xres = 640, + .yres = 480, + .pixclock = KHZ2PICOS(25175), + .left_margin = 114, + .hsync_len = 30, + .right_margin = 16, + .upper_margin = 32, + .vsync_len = 3, + .lower_margin = 10, + .sync = FB_SYNC_CLK_LAT_FALL, + }, + { + /* Emerging ET0350G0DH6 320 x 240 display. + * 70.08 mm x 52.56 mm display area. + */ + .name = "ET0350", + .refresh = 60, + .xres = 320, + .yres = 240, + .pixclock = KHZ2PICOS(6500), + .left_margin = 68 - 34, + .hsync_len = 34, + .right_margin = 20, + .upper_margin = 18 - 3, + .vsync_len = 3, + .lower_margin = 4, + .sync = FB_SYNC_CLK_LAT_FALL, + }, + { + /* Emerging ET0430G0DH6 480 x 272 display. + * 95.04 mm x 53.856 mm display area. + */ + .name = "ET0430", + .refresh = 60, + .xres = 480, + .yres = 272, + .pixclock = KHZ2PICOS(9000), + .left_margin = 2, + .hsync_len = 41, + .right_margin = 2, + .upper_margin = 2, + .vsync_len = 10, + .lower_margin = 2, + .sync = FB_SYNC_CLK_LAT_FALL, + }, + { + /* Emerging ET0500G0DH6 800 x 480 display. + * 109.6 mm x 66.4 mm display area. + */ + .name = "ET0500", + .refresh = 60, + .xres = 800, + .yres = 480, + .pixclock = KHZ2PICOS(33260), + .left_margin = 216 - 128, + .hsync_len = 128, + .right_margin = 1056 - 800 - 216, + .upper_margin = 35 - 2, + .vsync_len = 2, + .lower_margin = 525 - 480 - 35, + .sync = FB_SYNC_CLK_LAT_FALL, + }, + { + /* Emerging ETQ570G0DH6 320 x 240 display. + * 115.2 mm x 86.4 mm display area. + */ + .name = "ETQ570", + .refresh = 60, + .xres = 320, + .yres = 240, + .pixclock = KHZ2PICOS(6400), + .left_margin = 38, + .hsync_len = 30, + .right_margin = 30, + .upper_margin = 16, /* 15 according to datasheet */ + .vsync_len = 3, /* TVP -> 1>x>5 */ + .lower_margin = 4, /* 4.5 according to datasheet */ + .sync = FB_SYNC_CLK_LAT_FALL, + }, + { + /* Emerging ET0700G0DH6 800 x 480 display. + * 152.4 mm x 91.44 mm display area. + */ + .name = "ET0700", + .refresh = 60, + .xres = 800, + .yres = 480, + .pixclock = KHZ2PICOS(33260), + .left_margin = 216 - 128, + .hsync_len = 128, + .right_margin = 1056 - 800 - 216, + .upper_margin = 35 - 2, + .vsync_len = 2, + .lower_margin = 525 - 480 - 35, + .sync = FB_SYNC_CLK_LAT_FALL, + }, + { + /* Emerging ET070001DM6 800 x 480 display. + * 152.4 mm x 91.44 mm display area. + */ + .name = "ET070001DM6", + .refresh = 60, + .xres = 800, + .yres = 480, + .pixclock = KHZ2PICOS(33260), + .left_margin = 216 - 128, + .hsync_len = 128, + .right_margin = 1056 - 800 - 216, + .upper_margin = 35 - 2, + .vsync_len = 2, + .lower_margin = 525 - 480 - 35, + .sync = 0, + }, +#else + { + /* HannStar HSD100PXN1 + * 202.7m mm x 152.06 mm display area. + */ + .name = "HSD100PXN1", + .refresh = 60, + .xres = 1024, + .yres = 768, + .pixclock = KHZ2PICOS(65000), + .left_margin = 0, + .hsync_len = 0, + .right_margin = 320, + .upper_margin = 0, + .vsync_len = 0, + .lower_margin = 38, + .sync = FB_SYNC_CLK_LAT_FALL, + }, +#endif + { + /* unnamed entry for assigning parameters parsed from 'video_mode' string */ + .refresh = 60, + .left_margin = 48, + .hsync_len = 96, + .right_margin = 16, + .upper_margin = 31, + .vsync_len = 2, + .lower_margin = 12, + .sync = FB_SYNC_CLK_LAT_FALL, + }, +}; + +static int lcd_enabled = 1; +static int lcd_bl_polarity; + +static int lcd_backlight_polarity(void) +{ + return lcd_bl_polarity; +} + +void lcd_enable(void) +{ + /* HACK ALERT: + * global variable from common/lcd.c + * Set to 0 here to prevent messages from going to LCD + * rather than serial console + */ + lcd_is_enabled = 0; + + karo_load_splashimage(1); + + if (lcd_enabled) { + debug("Switching LCD on\n"); + gpio_set_value(TX6_LCD_PWR_GPIO, 1); + udelay(100); + gpio_set_value(TX6_LCD_RST_GPIO, 1); + udelay(300000); + gpio_set_value(TX6_LCD_BACKLIGHT_GPIO, lcd_backlight_polarity()); + } +} + +void lcd_disable(void) +{ + if (lcd_enabled) { + printf("Disabling LCD\n"); + ipuv3_fb_shutdown(); + } +} + +void lcd_panel_disable(void) +{ + if (lcd_enabled) { + debug("Switching LCD off\n"); + gpio_set_value(TX6_LCD_BACKLIGHT_GPIO, !lcd_backlight_polarity()); + gpio_set_value(TX6_LCD_RST_GPIO, 0); + gpio_set_value(TX6_LCD_PWR_GPIO, 0); + } +} + +static const iomux_v3_cfg_t stk5_lcd_pads[] = { + /* LCD RESET */ + MX6_PAD_EIM_D29__GPIO_3_29, + /* LCD POWER_ENABLE */ + MX6_PAD_EIM_EB3__GPIO_2_31, + /* LCD Backlight (PWM) */ + MX6_PAD_GPIO_1__GPIO_1_1, + + /* Display */ + MX6_PAD_DI0_DISP_CLK__IPU1_DI0_DISP_CLK, + MX6_PAD_DI0_PIN15__IPU1_DI0_PIN15, + MX6_PAD_DI0_PIN2__IPU1_DI0_PIN2, + MX6_PAD_DI0_PIN3__IPU1_DI0_PIN3, + MX6_PAD_DISP0_DAT0__IPU1_DISP0_DAT_0, + MX6_PAD_DISP0_DAT1__IPU1_DISP0_DAT_1, + MX6_PAD_DISP0_DAT2__IPU1_DISP0_DAT_2, + MX6_PAD_DISP0_DAT3__IPU1_DISP0_DAT_3, + MX6_PAD_DISP0_DAT4__IPU1_DISP0_DAT_4, + MX6_PAD_DISP0_DAT5__IPU1_DISP0_DAT_5, + MX6_PAD_DISP0_DAT6__IPU1_DISP0_DAT_6, + MX6_PAD_DISP0_DAT7__IPU1_DISP0_DAT_7, + MX6_PAD_DISP0_DAT8__IPU1_DISP0_DAT_8, + MX6_PAD_DISP0_DAT9__IPU1_DISP0_DAT_9, + MX6_PAD_DISP0_DAT10__IPU1_DISP0_DAT_10, + MX6_PAD_DISP0_DAT11__IPU1_DISP0_DAT_11, + MX6_PAD_DISP0_DAT12__IPU1_DISP0_DAT_12, + MX6_PAD_DISP0_DAT13__IPU1_DISP0_DAT_13, + MX6_PAD_DISP0_DAT14__IPU1_DISP0_DAT_14, + MX6_PAD_DISP0_DAT15__IPU1_DISP0_DAT_15, + MX6_PAD_DISP0_DAT16__IPU1_DISP0_DAT_16, + MX6_PAD_DISP0_DAT17__IPU1_DISP0_DAT_17, + MX6_PAD_DISP0_DAT18__IPU1_DISP0_DAT_18, + MX6_PAD_DISP0_DAT19__IPU1_DISP0_DAT_19, + MX6_PAD_DISP0_DAT20__IPU1_DISP0_DAT_20, + MX6_PAD_DISP0_DAT21__IPU1_DISP0_DAT_21, + MX6_PAD_DISP0_DAT22__IPU1_DISP0_DAT_22, + MX6_PAD_DISP0_DAT23__IPU1_DISP0_DAT_23, +}; + +static const struct gpio stk5_lcd_gpios[] = { + { TX6_LCD_RST_GPIO, GPIOF_OUTPUT_INIT_LOW, "LCD RESET", }, + { TX6_LCD_PWR_GPIO, GPIOF_OUTPUT_INIT_LOW, "LCD POWER", }, + { TX6_LCD_BACKLIGHT_GPIO, GPIOF_OUTPUT_INIT_HIGH, "LCD BACKLIGHT", }, +}; + +void lcd_ctrl_init(void *lcdbase) +{ + int color_depth = 24; + const char *video_mode = karo_get_vmode(getenv("video_mode")); + const char *vm; + unsigned long val; + int refresh = 60; + struct fb_videomode *p = &tx6_fb_modes[0]; + struct fb_videomode fb_mode; + int xres_set = 0, yres_set = 0, bpp_set = 0, refresh_set = 0; + int pix_fmt; + int lcd_bus_width; + unsigned long di_clk_rate = 65000000; + + if (!lcd_enabled) { + debug("LCD disabled\n"); + return; + } + + if (had_ctrlc() || (wrsr & WRSR_TOUT)) { + debug("Disabling LCD\n"); + lcd_enabled = 0; + setenv("splashimage", NULL); + return; + } + + karo_fdt_move_fdt(); + lcd_bl_polarity = karo_fdt_get_backlight_polarity(working_fdt); + + if (video_mode == NULL) { + debug("Disabling LCD\n"); + lcd_enabled = 0; + return; + } + vm = video_mode; + if (karo_fdt_get_fb_mode(working_fdt, video_mode, &fb_mode) == 0) { + p = &fb_mode; + debug("Using video mode from FDT\n"); + vm += strlen(vm); + if (fb_mode.xres > panel_info.vl_col || + fb_mode.yres > panel_info.vl_row) { + printf("video resolution from DT: %dx%d exceeds hardware limits: %dx%d\n", + fb_mode.xres, fb_mode.yres, + panel_info.vl_col, panel_info.vl_row); + lcd_enabled = 0; + return; + } + } + if (p->name != NULL) + debug("Trying compiled-in video modes\n"); + while (p->name != NULL) { + if (strcmp(p->name, vm) == 0) { + debug("Using video mode: '%s'\n", p->name); + vm += strlen(vm); + break; + } + p++; + } + if (*vm != '\0') + debug("Trying to decode video_mode: '%s'\n", vm); + while (*vm != '\0') { + if (*vm >= '0' && *vm <= '9') { + char *end; + + val = simple_strtoul(vm, &end, 0); + if (end > vm) { + if (!xres_set) { + if (val > panel_info.vl_col) + val = panel_info.vl_col; + p->xres = val; + panel_info.vl_col = val; + xres_set = 1; + } else if (!yres_set) { + if (val > panel_info.vl_row) + val = panel_info.vl_row; + p->yres = val; + panel_info.vl_row = val; + yres_set = 1; + } else if (!bpp_set) { + switch (val) { + case 32: + case 24: + if (is_lvds()) + pix_fmt = IPU_PIX_FMT_LVDS888; + /* fallthru */ + case 16: + case 8: + color_depth = val; + break; + + case 18: + if (is_lvds()) { + color_depth = val; + break; + } + /* fallthru */ + default: + printf("Invalid color depth: '%.*s' in video_mode; using default: '%u'\n", + end - vm, vm, color_depth); + } + bpp_set = 1; + } else if (!refresh_set) { + refresh = val; + refresh_set = 1; + } + } + vm = end; + } + switch (*vm) { + case '@': + bpp_set = 1; + /* fallthru */ + case '-': + yres_set = 1; + /* fallthru */ + case 'x': + xres_set = 1; + /* fallthru */ + case 'M': + case 'R': + vm++; + break; + + default: + if (*vm != '\0') + vm++; + } + } + if (p->xres == 0 || p->yres == 0) { + printf("Invalid video mode: %s\n", getenv("video_mode")); + lcd_enabled = 0; + printf("Supported video modes are:"); + for (p = &tx6_fb_modes[0]; p->name != NULL; p++) { + printf(" %s", p->name); + } + printf("\n"); + return; + } + if (p->xres > panel_info.vl_col || p->yres > panel_info.vl_row) { + printf("video resolution: %dx%d exceeds hardware limits: %dx%d\n", + p->xres, p->yres, panel_info.vl_col, panel_info.vl_row); + lcd_enabled = 0; + return; + } + panel_info.vl_col = p->xres; + panel_info.vl_row = p->yres; + + switch (color_depth) { + case 8: + panel_info.vl_bpix = LCD_COLOR8; + break; + case 16: + panel_info.vl_bpix = LCD_COLOR16; + break; + default: + panel_info.vl_bpix = LCD_COLOR24; + } + + p->pixclock = KHZ2PICOS(refresh * + (p->xres + p->left_margin + p->right_margin + p->hsync_len) * + (p->yres + p->upper_margin + p->lower_margin + p->vsync_len) / + 1000); + debug("Pixel clock set to %lu.%03lu MHz\n", + PICOS2KHZ(p->pixclock) / 1000, PICOS2KHZ(p->pixclock) % 1000); + + if (p != &fb_mode) { + int ret; + + debug("Creating new display-timing node from '%s'\n", + video_mode); + ret = karo_fdt_create_fb_mode(working_fdt, video_mode, p); + if (ret) + printf("Failed to create new display-timing node from '%s': %d\n", + video_mode, ret); + } + + gpio_request_array(stk5_lcd_gpios, ARRAY_SIZE(stk5_lcd_gpios)); + imx_iomux_v3_setup_multiple_pads(stk5_lcd_pads, + ARRAY_SIZE(stk5_lcd_pads)); + + lcd_bus_width = karo_fdt_get_lcd_bus_width(working_fdt, 24); + switch (lcd_bus_width) { + case 24: + pix_fmt = is_lvds() ? IPU_PIX_FMT_LVDS888 : IPU_PIX_FMT_RGB24; + break; + + case 18: + pix_fmt = is_lvds() ? IPU_PIX_FMT_LVDS666 : IPU_PIX_FMT_RGB666; + break; + + case 16: + if (!is_lvds()) { + pix_fmt = IPU_PIX_FMT_RGB565; + break; + } + /* fallthru */ + default: + lcd_enabled = 0; + printf("Invalid %s bus width: %d\n", is_lvds() ? "LVDS" : "LCD", + lcd_bus_width); + return; + } + if (is_lvds()) { + int lvds_mapping = karo_fdt_get_lvds_mapping(working_fdt, 0); + int lvds_chan_mask = karo_fdt_get_lvds_channels(working_fdt); + uint32_t gpr2; + + if (lvds_chan_mask == 0) { + printf("No LVDS channel active\n"); + lcd_enabled = 0; + return; + } + + gpr2 = (lvds_mapping << 6) | (lvds_mapping << 8); + if (lcd_bus_width == 24) + gpr2 |= (1 << 5) | (1 << 7); + gpr2 |= (lvds_chan_mask & 1) ? 1 << 0 : 0; + gpr2 |= (lvds_chan_mask & 2) ? 3 << 2 : 0; + debug("writing %08x to GPR2[%08x]\n", gpr2, IOMUXC_BASE_ADDR + 8); + writel(gpr2, IOMUXC_BASE_ADDR + 8); + } + if (karo_load_splashimage(0) == 0) { + int ret; + + debug("Initializing LCD controller\n"); + ret = ipuv3_fb_init(p, 0, pix_fmt, DI_PCLK_PLL3, di_clk_rate, -1); + if (ret) { + printf("Failed to initialize FB driver: %d\n", ret); + lcd_enabled = 0; + } + } else { + debug("Skipping initialization of LCD controller\n"); + } +} +#else +#define lcd_enabled 0 +#endif /* CONFIG_LCD */ + +static void stk5_board_init(void) +{ + gpio_request_array(stk5_gpios, ARRAY_SIZE(stk5_gpios)); + imx_iomux_v3_setup_multiple_pads(stk5_pads, ARRAY_SIZE(stk5_pads)); +} + +static void stk5v3_board_init(void) +{ + stk5_board_init(); +} + +static void stk5v5_board_init(void) +{ + stk5_board_init(); + + gpio_request_one(IMX_GPIO_NR(4, 21), GPIOF_OUTPUT_INIT_HIGH, + "Flexcan Transceiver"); + imx_iomux_v3_setup_pad(MX6_PAD_DISP0_DAT0__GPIO_4_21); +} + +static void tx6qdl_set_cpu_clock(void) +{ + unsigned long cpu_clk = getenv_ulong("cpu_clk", 10, 0); + + if (had_ctrlc() || (wrsr & WRSR_TOUT)) + return; + + if (cpu_clk == 0 || cpu_clk == mxc_get_clock(MXC_ARM_CLK) / 1000000) + return; + + if (mxc_set_clock(CONFIG_SYS_MX6_HCLK, cpu_clk, MXC_ARM_CLK) == 0) { + cpu_clk = mxc_get_clock(MXC_ARM_CLK); + printf("CPU clock set to %lu.%03lu MHz\n", + cpu_clk / 1000000, cpu_clk / 1000 % 1000); + } else { + printf("Error: Failed to set CPU clock to %lu MHz\n", cpu_clk); + } +} + +static void tx6_init_mac(void) +{ + u8 mac[ETH_ALEN]; + + imx_get_mac_from_fuse(-1, mac); + if (!is_valid_ether_addr(mac)) { + printf("No valid MAC address programmed\n"); + return; + } + + printf("MAC addr from fuse: %pM\n", mac); + eth_setenv_enetaddr("ethaddr", mac); +} + +int board_late_init(void) +{ + int ret = 0; + const char *baseboard; + + tx6qdl_set_cpu_clock(); + karo_fdt_move_fdt(); + + baseboard = getenv("baseboard"); + if (!baseboard) + goto exit; + + printf("Baseboard: %s\n", baseboard); + + if (strncmp(baseboard, "stk5", 4) == 0) { + if ((strlen(baseboard) == 4) || + strcmp(baseboard, "stk5-v3") == 0) { + stk5v3_board_init(); + } else if (strcmp(baseboard, "stk5-v5") == 0) { + const char *otg_mode = getenv("otg_mode"); + + if (otg_mode && strcmp(otg_mode, "host") == 0) { + printf("otg_mode='%s' is incompatible with baseboard %s; setting to 'none'\n", + otg_mode, baseboard); + setenv("otg_mode", "none"); + } + stk5v5_board_init(); + } else { + printf("WARNING: Unsupported STK5 board rev.: %s\n", + baseboard + 4); + } + } else { + printf("WARNING: Unsupported baseboard: '%s'\n", + baseboard); + ret = -EINVAL; + } + +exit: + tx6_init_mac(); + + gpio_set_value(TX6_RESET_OUT_GPIO, 1); + clear_ctrlc(); + return ret; +} + +int checkboard(void) +{ + u32 cpurev = get_cpu_rev(); + int cpu_variant = (cpurev >> 12) & 0xff; + + tx6qdl_print_cpuinfo(); + + printf("Board: Ka-Ro TX6%c-%d%d2%d\n", + cpu_variant == MXC_CPU_MX6Q ? 'Q' : 'U', + cpu_variant == MXC_CPU_MX6Q ? 1 : 8, + is_lvds(), 1 - PHYS_SDRAM_1_WIDTH / 64); + + return 0; +} + +#ifdef CONFIG_SERIAL_TAG +void get_board_serial(struct tag_serialnr *serialnr) +{ + struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR; + struct fuse_bank0_regs *fuse = (void *)ocotp->bank[0].fuse_regs; + + serialnr->low = readl(&fuse->cfg0); + serialnr->high = readl(&fuse->cfg1); +} +#endif + +#ifdef CONFIG_OF_BOARD_SETUP +static const char *tx6_touchpanels[] = { + "ti,tsc2007", + "edt,edt-ft5x06", + "eeti,egalax_ts", +}; + +void ft_board_setup(void *blob, bd_t *bd) +{ + const char *baseboard = getenv("baseboard"); + int stk5_v5 = baseboard != NULL && (strcmp(baseboard, "stk5-v5") == 0); + const char *video_mode = karo_get_vmode(getenv("video_mode")); + int ret; + + ret = fdt_increase_size(blob, 4096); + if (ret) + printf("Failed to increase FDT size: %s\n", fdt_strerror(ret)); + + if (stk5_v5) + karo_fdt_enable_node(blob, "stk5led", 0); + + fdt_fixup_ethernet(blob); + + karo_fdt_fixup_touchpanel(blob, tx6_touchpanels, + ARRAY_SIZE(tx6_touchpanels)); + karo_fdt_fixup_usb_otg(blob, "usbotg", "fsl,usbphy"); + karo_fdt_fixup_flexcan(blob, stk5_v5); + + karo_fdt_update_fb_mode(blob, video_mode); +} +#endif /* CONFIG_OF_BOARD_SETUP */ diff --git a/boards.cfg b/boards.cfg index 4bfd901580..f3845dfc2d 100644 --- a/boards.cfg +++ b/boards.cfg @@ -293,6 +293,9 @@ tx6u-8111_noenv arm armv7 tx6 karo m tx6q-1110 arm armv7 tx6 karo mx6 tx6:MX6Q,SYS_LVDS_IF tx6q-1110_mfg arm armv7 tx6 karo mx6 tx6:MX6Q,MFG,SYS_LVDS_IF tx6q-1110_noenv arm armv7 tx6 karo mx6 tx6:MX6Q,ENV_IS_NOWHERE,SYS_LVDS_IF +tx6q-1020 arm armv7 tx6 karo mx6 tx6:MX6Q,TX6_V2,ENV_IS_IN_MMC +tx6q-1020_noenv arm armv7 tx6 karo mx6 tx6:MX6Q,TX6_V2,ENV_IS_NOWHERE +tx6q-1020_mfg arm armv7 tx6 karo mx6 tx6:MX6Q,TX6_V2,ENV_IS_IN_MMC,MFG mx6qarm2 arm armv7 mx6qarm2 freescale mx6 mx6qarm2:IMX_CONFIG=board/freescale/mx6qarm2/imximage.cfg mx6qsabreauto arm armv7 mx6qsabreauto freescale mx6 mx6qsabreauto:IMX_CONFIG=board/freescale/mx6qsabreauto/imximage.cfg,MX6Q mx6qsabrelite arm armv7 mx6qsabrelite freescale mx6 mx6qsabrelite:IMX_CONFIG=board/freescale/imx/ddr/mx6q_4x_mt41j128.cfg diff --git a/common/cmd_bootce.c b/common/cmd_bootce.c index 7ce254d4c0..d3580d2c21 100644 --- a/common/cmd_bootce.c +++ b/common/cmd_bootce.c @@ -457,6 +457,7 @@ U_BOOT_CMD( "\taddr\t\tboot image from address addr (default ${fileaddr})" ); +#ifdef CONFIG_CMD_NAND static int ce_nand_load(ce_bin *bin, loff_t *offset, void *buf, size_t max_len) { int ret; @@ -584,6 +585,7 @@ U_BOOT_CMD( "\toff\t\t- flash offset (hex)\n" "\tpartition\t- partition name" ); +#endif static int ce_send_write_ack(ce_net *net) { diff --git a/include/configs/tx6.h b/include/configs/tx6.h index 7bd3bacbcd..691cb90c26 100644 --- a/include/configs/tx6.h +++ b/include/configs/tx6.h @@ -28,8 +28,10 @@ /* LCD Logo and Splash screen support */ #define CONFIG_LCD #ifdef CONFIG_LCD +#ifndef CONFIG_TX6_V2 #define CONFIG_SPLASH_SCREEN #define CONFIG_SPLASH_SCREEN_ALIGN +#endif #define CONFIG_VIDEO_IPUV3 #define CONFIG_IPUV3_CLK 266000000 #define CONFIG_LCD_LOGO @@ -95,7 +97,9 @@ #ifndef CONFIG_MFG #define CONFIG_OF_LIBFDT #ifdef CONFIG_OF_LIBFDT +#ifndef CONFIG_TX6_V2 #define CONFIG_FDT_FIXUP_PARTITIONS +#endif #define CONFIG_OF_BOARD_SETUP #ifdef CONFIG_MX6Q #define CONFIG_DEFAULT_DEVICE_TREE tx6q @@ -185,9 +189,15 @@ #endif /* CONFIG_ENV_IS_NOWHERE */ #endif /* CONFIG_MFG */ +#ifndef CONFIG_TX6_V2 #define MTD_NAME "gpmi-nand" #define MTDIDS_DEFAULT "nand0=" MTD_NAME #define CONFIG_SYS_NAND_ONFI_DETECTION +#else +#define MTD_NAME "" +#define MTDIDS_DEFAULT "" +#define CONFIG_SUPPORT_EMMC_BOOT +#endif /* * U-Boot Commands @@ -195,8 +205,14 @@ #include #define CONFIG_CMD_CACHE #define CONFIG_CMD_MMC +#ifndef CONFIG_TX6_V2 #define CONFIG_CMD_NAND #define CONFIG_CMD_MTDPARTS +#else +#define CONFIG_PARTITION_UUIDS +#define CONFIG_EFI_PARTITION +#define CONFIG_CMD_GPT +#endif #define CONFIG_CMD_BOOTCE #define CONFIG_CMD_TIME #define CONFIG_CMD_I2C @@ -250,7 +266,11 @@ #define CONFIG_SYS_I2C_BASE I2C1_BASE_ADDR #define CONFIG_SYS_I2C_MX6_PORT1 #define CONFIG_SYS_I2C_SPEED 400000 +#ifndef CONFIG_TX6_V2 #define CONFIG_SYS_I2C_SLAVE 0x3c +#else +#define CONFIG_SYS_I2C_SLAVE 0x32 +#endif #endif #ifndef CONFIG_ENV_IS_NOWHERE @@ -326,9 +346,8 @@ #define CONFIG_SYS_MMC_ENV_DEV 0 #undef CONFIG_ENV_OFFSET #undef CONFIG_ENV_SIZE -/* Associated with the MMC layout defined in mmcops.c */ -#define CONFIG_ENV_OFFSET SZ_1K -#define CONFIG_ENV_SIZE (SZ_128K - CONFIG_ENV_OFFSET) +#define CONFIG_ENV_OFFSET (CONFIG_U_BOOT_IMG_SIZE + CONFIG_SYS_NAND_U_BOOT_OFFS) +#define CONFIG_ENV_SIZE SZ_128K #define CONFIG_DYNAMIC_MMC_DEVNO #endif /* CONFIG_ENV_IS_IN_MMC */ #else @@ -340,6 +359,7 @@ #define CONFIG_ENV_SIZE SZ_4K #endif +#ifndef CONFIG_TX6_V2 #define MTDPARTS_DEFAULT "mtdparts=" MTD_NAME ":" \ xstr(CONFIG_SYS_U_BOOT_PART_SIZE) \ "@" xstr(CONFIG_SYS_NAND_U_BOOT_OFFS) \ @@ -350,6 +370,9 @@ "(dtb)," \ xstr(CONFIG_SYS_NAND_BBT_SIZE) \ "@" xstr(CONFIG_SYS_NAND_BBT_OFFSET) "(bbt)ro" +#else +#define MTDPARTS_DEFAULT "" +#endif #define CONFIG_SYS_SDRAM_BASE PHYS_SDRAM_1 #define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_SDRAM_BASE + 0x1000 - /* Fix this */ \ -- 2.39.2