From b16a9ad7bd7ac6e5f3293c003b96d15fb2504a92 Mon Sep 17 00:00:00 2001 From: Max Krummenacher Date: Wed, 10 Dec 2014 14:31:19 +0100 Subject: apalis-imx6: add HW revision detection - Default to DTE UART mode, as used on HW V1.1 but automatically fall back to use DCE UART on V1.0 HW. - If using the default device tree filename imx6q-apalis-eval.dtb, switch to the V1.0 devicetree on V1.0 HW. If device tree name is not the default leave it alone. - Add board_rev to the U-Boot environment. On V1.0A HW: 010a - Add CONFIG_ENV_VARS_UBOOT_CONFIG --- board/toradex/apalis_imx6/apalis_imx6.c | 90 +++++++++++++++++++++++++-------- drivers/serial/serial_mxc.c | 8 +-- include/configs/apalis_imx6.h | 15 +++++- 3 files changed, 83 insertions(+), 30 deletions(-) diff --git a/board/toradex/apalis_imx6/apalis_imx6.c b/board/toradex/apalis_imx6/apalis_imx6.c index 605d8de3a1..870900d4bb 100644 --- a/board/toradex/apalis_imx6/apalis_imx6.c +++ b/board/toradex/apalis_imx6/apalis_imx6.c @@ -35,6 +35,8 @@ DECLARE_GLOBAL_DATA_PTR; +static u32 get_board_rev_local(void); + #if defined(CONFIG_BOARD_LATE_INIT) && (defined(CONFIG_TRDX_CFG_BLOCK) || \ defined(CONFIG_SERIAL_TAG)) /* buffer suitable for DMA */ @@ -85,14 +87,13 @@ int dram_init(void) } /* Apalis UART1 */ -iomux_v3_cfg_t const uart1_pads[] = { -#ifndef CONFIG_MXC_UART_DTE +iomux_v3_cfg_t const uart1_pads_dce[] = { MX6_PAD_CSI0_DAT10__UART1_TX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL), MX6_PAD_CSI0_DAT11__UART1_RX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL), -#else +}; +iomux_v3_cfg_t const uart1_pads_dte[] = { MX6_PAD_CSI0_DAT10__UART1_RX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL), MX6_PAD_CSI0_DAT11__UART1_TX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL), -#endif }; #define PC MUX_PAD_CTRL(I2C_PAD_CTRL) @@ -280,24 +281,32 @@ iomux_v3_cfg_t const usb_pads[] = { */ #define UFCR 0x90 /* FIFO Control Register */ #define UFCR_DCEDTE (1<<6) /* DCE=0 */ -#define SET_DCEDTE(p) (writel( (readl((u32 *) (p)) | UFCR_DCEDTE), (u32 *) (p))) -#ifdef CONFIG_MXC_UART_DTE static void setup_dtemode_uart(void) { - SET_DCEDTE(UART1_BASE + UFCR); - SET_DCEDTE(UART2_BASE + UFCR); - SET_DCEDTE(UART4_BASE + UFCR); - SET_DCEDTE(UART5_BASE + UFCR); + setbits_le32((u32 *)(UART1_BASE + UFCR), UFCR_DCEDTE); + setbits_le32((u32 *)(UART2_BASE + UFCR), UFCR_DCEDTE); + setbits_le32((u32 *)(UART4_BASE + UFCR), UFCR_DCEDTE); + setbits_le32((u32 *)(UART5_BASE + UFCR), UFCR_DCEDTE); +} +static void setup_dcemode_uart(void) +{ + clrbits_le32((u32 *)(UART1_BASE + UFCR), UFCR_DCEDTE); + clrbits_le32((u32 *)(UART2_BASE + UFCR), UFCR_DCEDTE); + clrbits_le32((u32 *)(UART4_BASE + UFCR), UFCR_DCEDTE); + clrbits_le32((u32 *)(UART5_BASE + UFCR), UFCR_DCEDTE); } -#endif -static void setup_iomux_uart(void) +static void setup_iomux_dte_uart(void) { -#ifdef CONFIG_MXC_UART_DTE setup_dtemode_uart(); -#endif - imx_iomux_v3_setup_multiple_pads(uart1_pads, ARRAY_SIZE(uart1_pads)); + imx_iomux_v3_setup_multiple_pads(uart1_pads_dte, ARRAY_SIZE(uart1_pads_dte)); +} + +static void setup_iomux_dce_uart(void) +{ + setup_dcemode_uart(); + imx_iomux_v3_setup_multiple_pads(uart1_pads_dce, ARRAY_SIZE(uart1_pads_dce)); } #ifdef CONFIG_USB_EHCI_MX6 @@ -816,7 +825,11 @@ int board_early_init_f(void) { imx_iomux_v3_setup_multiple_pads(pwr_intb_pads, ARRAY_SIZE(pwr_intb_pads)); - setup_iomux_uart(); +#ifndef CONFIG_APALIS_IMX6_V1_0 + setup_iomux_dte_uart(); +#else + setup_iomux_dce_uart(); +#endif #if defined(CONFIG_VIDEO_IPUV3) setup_display(); @@ -858,6 +871,7 @@ int board_late_init(void) char env_str[256]; int i; + u32 rev; unsigned size = 0; char *addr_str, *end; @@ -917,16 +931,38 @@ int board_late_init(void) } } #endif /* CONFIG_TRDX_CFG_BLOCK */ + + rev = get_board_rev_local(); + +#ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG + snprintf(env_str, ARRAY_SIZE(env_str), "%.4x", rev); + setenv("board_rev", env_str); +#endif + +#ifndef CONFIG_APALIS_IMX6_V1_0 + if((rev & 0xfff0) == 0x0100) { + char* fdt_env; + + /* reconfigure the UART to DCE mode dynamically if on V1.0 HW */ + setup_iomux_dce_uart(); + + /* if using the default device tree, use version for V1.0 HW */ + fdt_env = getenv("fdt_file"); + if((fdt_env != NULL) && (strcmp(FDT_FILE, fdt_env) == 0)) { + setenv("fdt_file", FDT_FILE_V1_0); + printf("patching fdt_file to " FDT_FILE_V1_0 "\n"); +#ifndef CONFIG_ENV_IS_NOWHERE + saveenv(); +#endif + } + } +#endif + return 0; } #endif /* CONFIG_BOARD_LATE_INIT */ -/* i.MX6 uses the 'standard' board revision for things, i.e. - video decoding no longer works. - so don't interfere with the Apalis iMX6 HW Revision */ -#if 0 -#ifdef CONFIG_REVISION_TAG -u32 get_board_rev(void) +u32 get_board_rev_local(void) { #ifdef CONFIG_BOARD_LATE_INIT int i; @@ -958,6 +994,16 @@ u32 get_board_rev(void) return 0; #endif /* CONFIG_BOARD_LATE_INIT */ } + +/* i.MX6 Kernel/Userspace 3.0.35 uses the 'standard' board revision for + things, i.e. video decoding no longer works, + so don't interfere with the Apalis iMX6 HW Revision */ +#if 0 +#ifdef CONFIG_REVISION_TAG +u32 get_board_rev(void) +{ + return get_board_rev_local(); +} #endif /* CONFIG_REVISION_TAG */ #endif diff --git a/drivers/serial/serial_mxc.c b/drivers/serial/serial_mxc.c index bfc473bf66..a94abfd645 100644 --- a/drivers/serial/serial_mxc.c +++ b/drivers/serial/serial_mxc.c @@ -194,12 +194,8 @@ static int mxc_serial_init(void) __REG(UART_PHYS + UTS) = 0x0; - __REG(UART_PHYS + UFCR) = -#ifdef CONFIG_MXC_UART_DTE - UFCR_DCEDTE; -#else - 0; -#endif + /* keep the DCE DTE setting */ + __REG(UART_PHYS + UFCR) = __REG(UART_PHYS + UFCR) & UFCR_DCEDTE; serial_setbrg(); diff --git a/include/configs/apalis_imx6.h b/include/configs/apalis_imx6.h index 06e8d5838e..5d3211849e 100644 --- a/include/configs/apalis_imx6.h +++ b/include/configs/apalis_imx6.h @@ -16,6 +16,11 @@ #define CONFIG_DISPLAY_CPUINFO #define CONFIG_DISPLAY_BOARDINFO +/* Define CONFIG_APALIS_IMX6_V1_0 to use the UARTS in DCE mode unconditionally. + Otherwise U-Boot uses the Configblock to fall back to DCE on V1.0 HW */ +/* #define CONFIG_APALIS_IMX6_V1_0 */ + + #define CONFIG_MACH_TYPE 4886 #include @@ -42,10 +47,10 @@ #define CONFIG_MXC_UART #define CONFIG_MXC_UART_BASE UART1_BASE -#define CONFIG_MXC_UART_DTE /* use the uart in DTE mode */ /* Make the HW version stuff available in u-boot env */ #define CONFIG_VERSION_VARIABLE /* ver environment variable */ +#define CONFIG_ENV_VARS_UBOOT_CONFIG #define CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG /* I2C Configs */ @@ -217,6 +222,12 @@ "sddtbload=setenv dtbparam; fatload mmc 1:1 ${fdt_addr_r} " \ "${fdt_file} && setenv dtbparam \" - ${fdt_addr_r}\" && true\0" +#ifndef CONFIG_APALIS_IMX6_V1_0 +#define FDT_FILE "imx6q-apalis-eval.dtb" +#define FDT_FILE_V1_0 "imx6q-apalis-eval_v1_0.dtb" +#else +#define FDT_FILE "imx6q-apalis-eval_v1_0.dtb" +#endif #define CONFIG_EXTRA_ENV_SETTINGS \ "bootcmd=run emmcboot ; echo ; echo emmcboot failed ; " \ "run nfsboot ; echo ; echo nfsboot failed ; " \ @@ -226,7 +237,7 @@ "console=ttymxc0\0" \ "defargs=enable_wait_mode=off vmalloc=400M\0" \ EMMC_BOOTCMD \ - "fdt_file=imx6q-apalis-eval.dtb\0" \ + "fdt_file=" FDT_FILE "\0" \ MEM_LAYOUT_ENV_SETTINGS \ NFS_BOOTCMD \ SD_BOOTCMD \ -- cgit v1.2.3