/* * Copyright (C) 2016 Freescale Semiconductor, Inc. * Copyright 2017 NXP * * SPDX-License-Identifier: GPL-2.0+ */ #include #include #include #include #include #include #include #include #include DECLARE_GLOBAL_DATA_PTR; #define ESDHC_PAD_CTRL (PAD_CTL_PUS_UP | PAD_CTL_DSE) #define ESDHC_CD_GPIO_PAD_CTRL (PAD_CTL_IBE_ENABLE | PAD_CTL_PUS_UP) #define UART_PAD_CTRL (PAD_CTL_PUS_UP) #define GPIO_PAD_CTRL (PAD_CTL_OBE_ENABLE | PAD_CTL_IBE_ENABLE) #define OTG_ID_GPIO_PAD_CTRL (PAD_CTL_IBE_ENABLE) #define OTG_PWR_GPIO_PAD_CTRL (PAD_CTL_OBE_ENABLE) #define QSPI_PAD_CTRL1 (PAD_CTL_PUS_UP | PAD_CTL_DSE) #define QSPI_PAD_CTRL0 (PAD_CTL_PUS_UP | PAD_CTL_DSE \ | PAD_CTL_OBE_ENABLE) int dram_init(void) { gd->ram_size = PHYS_SDRAM_SIZE; return 0; } static iomux_cfg_t const lpuart4_pads[] = { MX7ULP_PAD_PTC3__LPUART4_RX | MUX_PAD_CTRL(UART_PAD_CTRL), MX7ULP_PAD_PTC2__LPUART4_TX | MUX_PAD_CTRL(UART_PAD_CTRL), }; /* PTF11 and PTF10 also can mux to LPUART6 on 10x10 ARM2, depends on rework*/ static iomux_cfg_t const lpuart6_pads[] = { MX7ULP_PAD_PTE11__LPUART6_RX | MUX_PAD_CTRL(UART_PAD_CTRL), MX7ULP_PAD_PTE10__LPUART6_TX | MUX_PAD_CTRL(UART_PAD_CTRL), }; static void setup_iomux_uart(void) { #ifdef CONFIG_TARGET_MX7ULP_10X10_ARM2 mx7ulp_iomux_setup_multiple_pads(lpuart6_pads, ARRAY_SIZE(lpuart4_pads)); #else mx7ulp_iomux_setup_multiple_pads(lpuart4_pads, ARRAY_SIZE(lpuart4_pads)); #endif } #ifdef CONFIG_USB_EHCI_MX7 static iomux_cfg_t const usb_otg1_pads[] = { #ifdef CONFIG_TARGET_MX7ULP_10X10_ARM2 MX7ULP_PAD_PTC0__PTC0 | MUX_PAD_CTRL(OTG_ID_GPIO_PAD_CTRL), /* gpio for otgid */ MX7ULP_PAD_PTC1__PTC1 | MUX_PAD_CTRL(OTG_PWR_GPIO_PAD_CTRL), /* gpio for power en */ #else /*Need rework for ID and PWR_EN pins on 14x14 ARM2*/ MX7ULP_PAD_PTC18__PTC18 | MUX_PAD_CTRL(OTG_ID_GPIO_PAD_CTRL), /* gpio for otgid */ MX7ULP_PAD_PTA31__PTA31 | MUX_PAD_CTRL(OTG_PWR_GPIO_PAD_CTRL), /* gpio for power en */ #endif }; #ifdef CONFIG_TARGET_MX7ULP_10X10_ARM2 #define OTG0_ID_GPIO IMX_GPIO_NR(3, 0) #define OTG0_PWR_EN IMX_GPIO_NR(3, 1) #else #define OTG0_ID_GPIO IMX_GPIO_NR(3, 18) #define OTG0_PWR_EN IMX_GPIO_NR(1, 31) #endif static void setup_usb(void) { mx7ulp_iomux_setup_multiple_pads(usb_otg1_pads, ARRAY_SIZE(usb_otg1_pads)); gpio_request(OTG0_ID_GPIO, "otg_id"); gpio_direction_input(OTG0_ID_GPIO); } /*Needs to override the ehci power if controlled by GPIO */ int board_ehci_power(int port, int on) { switch (port) { case 0: if (on) gpio_direction_output(OTG0_PWR_EN, 1); else gpio_direction_output(OTG0_PWR_EN, 0); break; default: printf("MXC USB port %d not yet supported\n", port); return -EINVAL; } return 0; } int board_usb_phy_mode(int port) { int ret = 0; if (port == 0) { ret = gpio_get_value(OTG0_ID_GPIO); if (ret) return USB_INIT_DEVICE; else return USB_INIT_HOST; } return USB_INIT_HOST; } #endif int board_early_init_f(void) { setup_iomux_uart(); return 0; } #ifdef CONFIG_FSL_QSPI #ifdef CONFIG_TARGET_MX7ULP_10X10_ARM2 static iomux_cfg_t const quadspi_pads[] = { MX7ULP_PAD_PTB8__QSPIA_SS0_B | MUX_PAD_CTRL(QSPI_PAD_CTRL0), MX7ULP_PAD_PTB14__QSPIA_SS1_B | MUX_PAD_CTRL(QSPI_PAD_CTRL0), MX7ULP_PAD_PTB15__QSPIA_SCLK | MUX_PAD_CTRL(QSPI_PAD_CTRL0), MX7ULP_PAD_PTB16__QSPIA_DATA3 | MUX_PAD_CTRL(QSPI_PAD_CTRL1), MX7ULP_PAD_PTB17__QSPIA_DATA2 | MUX_PAD_CTRL(QSPI_PAD_CTRL1), MX7ULP_PAD_PTB18__QSPIA_DATA1 | MUX_PAD_CTRL(QSPI_PAD_CTRL1), MX7ULP_PAD_PTB19__QSPIA_DATA0 | MUX_PAD_CTRL(QSPI_PAD_CTRL1), MX7ULP_PAD_PTB5__PTB5 | MUX_PAD_CTRL(GPIO_PAD_CTRL), }; #define QSPI_RST_GPIO IMX_GPIO_NR(2, 5) #else /* MT35XU512ABA supports 8 bits I/O, since our driver only support 4, so mux 4 data pins*/ static iomux_cfg_t const quadspi_pads[] = { MX7ULP_PAD_PTB8__QSPIA_SS0_B | MUX_PAD_CTRL(QSPI_PAD_CTRL0), MX7ULP_PAD_PTB9__QSPIA_DQS | MUX_PAD_CTRL(QSPI_PAD_CTRL1), MX7ULP_PAD_PTB15__QSPIA_SCLK | MUX_PAD_CTRL(QSPI_PAD_CTRL0), MX7ULP_PAD_PTB16__QSPIA_DATA3 | MUX_PAD_CTRL(QSPI_PAD_CTRL1), MX7ULP_PAD_PTB17__QSPIA_DATA2 | MUX_PAD_CTRL(QSPI_PAD_CTRL1), MX7ULP_PAD_PTB18__QSPIA_DATA1 | MUX_PAD_CTRL(QSPI_PAD_CTRL1), MX7ULP_PAD_PTB19__QSPIA_DATA0 | MUX_PAD_CTRL(QSPI_PAD_CTRL1), MX7ULP_PAD_PTB12__PTB12 | MUX_PAD_CTRL(GPIO_PAD_CTRL), }; #define QSPI_RST_GPIO IMX_GPIO_NR(2, 12) #endif int board_qspi_init(void) { u32 val; mx7ulp_iomux_setup_multiple_pads(quadspi_pads, ARRAY_SIZE(quadspi_pads)); /* enable clock */ val = readl(PCC1_RBASE + 0x94); if (!(val & 0x20000000)) { writel(0x03000003, (PCC1_RBASE + 0x94)); writel(0x43000003, (PCC1_RBASE + 0x94)); } gpio_request(QSPI_RST_GPIO, "qspi_reset"); gpio_direction_output(QSPI_RST_GPIO, 0); mdelay(10); gpio_direction_output(QSPI_RST_GPIO, 1); return 0; } #endif int board_init(void) { /* address of boot parameters */ gd->bd->bi_boot_params = PHYS_SDRAM + 0x100; #ifdef CONFIG_USB_EHCI_MX7 setup_usb(); #endif #ifdef CONFIG_FSL_QSPI board_qspi_init(); #endif return 0; } #ifndef CONFIG_DM_MMC static struct fsl_esdhc_cfg usdhc_cfg[2] = { {USDHC0_RBASE, 0, 8}, {USDHC1_RBASE, 0}, }; static iomux_cfg_t const usdhc0_emmc_pads[] = { MX7ULP_PAD_PTD0__SDHC0_RESET_b | MUX_PAD_CTRL(ESDHC_PAD_CTRL), MX7ULP_PAD_PTD1__SDHC0_CMD | MUX_PAD_CTRL(ESDHC_PAD_CTRL), MX7ULP_PAD_PTD2__SDHC0_CLK | MUX_PAD_CTRL(ESDHC_PAD_CTRL), MX7ULP_PAD_PTD3__SDHC0_D7 | MUX_PAD_CTRL(ESDHC_PAD_CTRL), MX7ULP_PAD_PTD4__SDHC0_D6 | MUX_PAD_CTRL(ESDHC_PAD_CTRL), MX7ULP_PAD_PTD5__SDHC0_D5 | MUX_PAD_CTRL(ESDHC_PAD_CTRL), MX7ULP_PAD_PTD6__SDHC0_D4 | MUX_PAD_CTRL(ESDHC_PAD_CTRL), MX7ULP_PAD_PTD7__SDHC0_D3 | MUX_PAD_CTRL(ESDHC_PAD_CTRL), MX7ULP_PAD_PTD8__SDHC0_D2 | MUX_PAD_CTRL(ESDHC_PAD_CTRL), MX7ULP_PAD_PTD9__SDHC0_D1 | MUX_PAD_CTRL(ESDHC_PAD_CTRL), MX7ULP_PAD_PTD10__SDHC0_D0 | MUX_PAD_CTRL(ESDHC_PAD_CTRL), MX7ULP_PAD_PTD11__SDHC0_DQS | MUX_PAD_CTRL(ESDHC_PAD_CTRL), }; static iomux_cfg_t const usdhc1_pads[] = { MX7ULP_PAD_PTE11__SDHC1_RESET_b | MUX_PAD_CTRL(ESDHC_PAD_CTRL), MX7ULP_PAD_PTE3__SDHC1_CMD | MUX_PAD_CTRL(ESDHC_PAD_CTRL), MX7ULP_PAD_PTE2__SDHC1_CLK | MUX_PAD_CTRL(ESDHC_PAD_CTRL), MX7ULP_PAD_PTE9__SDHC1_D7 | MUX_PAD_CTRL(ESDHC_PAD_CTRL), MX7ULP_PAD_PTE8__SDHC1_D6 | MUX_PAD_CTRL(ESDHC_PAD_CTRL), MX7ULP_PAD_PTE7__SDHC1_D5 | MUX_PAD_CTRL(ESDHC_PAD_CTRL), MX7ULP_PAD_PTE6__SDHC1_D4 | MUX_PAD_CTRL(ESDHC_PAD_CTRL), MX7ULP_PAD_PTE4__SDHC1_D3 | MUX_PAD_CTRL(ESDHC_PAD_CTRL), MX7ULP_PAD_PTE5__SDHC1_D2 | MUX_PAD_CTRL(ESDHC_PAD_CTRL), MX7ULP_PAD_PTE0__SDHC1_D1 | MUX_PAD_CTRL(ESDHC_PAD_CTRL), MX7ULP_PAD_PTE1__SDHC1_D0 | MUX_PAD_CTRL(ESDHC_PAD_CTRL), MX7ULP_PAD_PTE10__SDHC1_DQS | MUX_PAD_CTRL(ESDHC_PAD_CTRL), MX7ULP_PAD_PTE13__PTE13 | MUX_PAD_CTRL(ESDHC_CD_GPIO_PAD_CTRL), /*CD*/ }; #define USDHC0_CD_GPIO IMX_GPIO_NR(5, 13) int board_mmc_init(bd_t *bis) { int i, ret; /* * According to the board_mmc_init() the following map is done: * (U-Boot device node) (Physical Port) * mmc0 USDHC0 * mmc1 USDHC1 */ for (i = 0; i < CONFIG_SYS_FSL_USDHC_NUM; i++) { switch (i) { case 0: mx7ulp_iomux_setup_multiple_pads(usdhc0_emmc_pads, ARRAY_SIZE(usdhc0_emmc_pads)); init_clk_usdhc(0); usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC_CLK); break; case 1: mx7ulp_iomux_setup_multiple_pads(usdhc1_pads, ARRAY_SIZE(usdhc1_pads)); init_clk_usdhc(1); usdhc_cfg[1].sdhc_clk = mxc_get_clock(MXC_ESDHC2_CLK); gpio_request(USDHC0_CD_GPIO, "usdhc1_cd"); gpio_direction_input(USDHC0_CD_GPIO); break; default: printf("Warning: you configured more USDHC controllers" "(%d) than supported by the board\n", i + 1); return -EINVAL; } ret = fsl_esdhc_initialize(bis, &usdhc_cfg[i]); if (ret) return ret; } return 0; } int board_mmc_getcd(struct mmc *mmc) { struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv; int ret = 0; switch (cfg->esdhc_base) { case USDHC0_RBASE: ret = 1; break; case USDHC1_RBASE: ret = !gpio_get_value(USDHC0_CD_GPIO); break; } return ret; } #endif int board_late_init(void) { return 0; } int checkboard(void) { #ifdef CONFIG_TARGET_MX7ULP_10X10_ARM2 printf("Board: i.MX7ULP 10x10 ARM2 board\n"); #else printf("Board: i.MX7ULP 14x14 ARM2 board\n"); #endif return 0; }