From c133c503ac9e037ccbc1b7a37c07c4068b32d802 Mon Sep 17 00:00:00 2001 From: Christopher Spinrath Date: Thu, 16 Jun 2016 14:02:56 +0200 Subject: ARM: board: cm-fx6: fix mmc for old revisions of utilite Old revisions of Utilite (based on cm-fx6) do not have a dedicated card detect pin. But the card is removable by the user and card detection can be realized with polling (e.g. supported by Linux). Add the broken-cd property to the mmc device tree instead of the non-removable property to make card detection possible if polling is supported. Signed-off-by: Christopher Spinrath Acked-by: Nikita Kiryanov --- board/compulab/cm_fx6/cm_fx6.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'board') diff --git a/board/compulab/cm_fx6/cm_fx6.c b/board/compulab/cm_fx6/cm_fx6.c index a21e7b00e1..712057a6c5 100644 --- a/board/compulab/cm_fx6/cm_fx6.c +++ b/board/compulab/cm_fx6/cm_fx6.c @@ -610,7 +610,7 @@ int ft_board_setup(void *blob, bd_t *bd) fdt_shrink_to_minimum(blob); /* Make room for new properties */ nodeoffset = fdt_path_offset(blob, USDHC3_PATH); fdt_delprop(blob, nodeoffset, "cd-gpios"); - fdt_find_and_setprop(blob, USDHC3_PATH, "non-removable", + fdt_find_and_setprop(blob, USDHC3_PATH, "broken-cd", NULL, 0, 1); fdt_find_and_setprop(blob, USDHC3_PATH, "keep-power-in-suspend", NULL, 0, 1); -- cgit From 8be4f40ecfd92257007e82a08e25044b447db18d Mon Sep 17 00:00:00 2001 From: Stefano Babic Date: Mon, 6 Jun 2016 11:19:42 +0200 Subject: mx6: add support for el6x board Custom Board based on MX6 Dual, 1GB RAM and eMMC. There are two variants of the board with and without PCIe (ZC5202 and ZC5601). Signed-off-by: Stefano Babic --- board/el/el6x/Kconfig | 25 ++ board/el/el6x/MAINTAINERS | 8 + board/el/el6x/Makefile | 7 + board/el/el6x/el6x.c | 640 ++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 680 insertions(+) create mode 100644 board/el/el6x/Kconfig create mode 100644 board/el/el6x/MAINTAINERS create mode 100644 board/el/el6x/Makefile create mode 100644 board/el/el6x/el6x.c (limited to 'board') diff --git a/board/el/el6x/Kconfig b/board/el/el6x/Kconfig new file mode 100644 index 0000000000..aa9bf25fb4 --- /dev/null +++ b/board/el/el6x/Kconfig @@ -0,0 +1,25 @@ +if TARGET_ZC5202 + +config SYS_BOARD + default "el6x" + +config SYS_VENDOR + default "el" + +config SYS_CONFIG_NAME + default "zc5202" + +endif + +if TARGET_ZC5601 + +config SYS_BOARD + default "el6x" + +config SYS_VENDOR + default "el" + +config SYS_CONFIG_NAME + default "zc5601" + +endif diff --git a/board/el/el6x/MAINTAINERS b/board/el/el6x/MAINTAINERS new file mode 100644 index 0000000000..9a40010f50 --- /dev/null +++ b/board/el/el6x/MAINTAINERS @@ -0,0 +1,8 @@ +EL6X BOARD +M: Stefano Babic +S: Maintained +F: board/el/el6x/ +F: include/configs/zc5202.h +F: include/configs/zc5601.h +F: configs/zc5202_defconfig +F: configs/zc5601_defconfig diff --git a/board/el/el6x/Makefile b/board/el/el6x/Makefile new file mode 100644 index 0000000000..48d5ad9440 --- /dev/null +++ b/board/el/el6x/Makefile @@ -0,0 +1,7 @@ +# +# Copyright (C) Stefano Babic +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-y := el6x.o diff --git a/board/el/el6x/el6x.c b/board/el/el6x/el6x.c new file mode 100644 index 0000000000..3b0fb323bd --- /dev/null +++ b/board/el/el6x/el6x.c @@ -0,0 +1,640 @@ +/* + * Copyright (C) Stefano Babic + * + * Based on other i.MX6 boards + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +#define OPEN_PAD_CTRL (PAD_CTL_ODE | PAD_CTL_DSE_DISABLE | (0 << 12)) + +#define UART_PAD_CTRL (PAD_CTL_PUS_100K_UP | \ + PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm | \ + PAD_CTL_SRE_FAST | PAD_CTL_HYS) + +#define USDHC_PAD_CTRL (PAD_CTL_PUS_47K_UP | \ + PAD_CTL_SPEED_LOW | PAD_CTL_DSE_80ohm | \ + PAD_CTL_SRE_FAST | PAD_CTL_HYS) + +#define ENET_PAD_CTRL (PAD_CTL_PUS_100K_UP | \ + PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm | PAD_CTL_HYS) + +#define ENET_PAD_CTRL_PD (PAD_CTL_PUS_100K_DOWN | \ + PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm | PAD_CTL_HYS) + +#define ENET_PAD_CTRL_CLK ((PAD_CTL_PUS_100K_UP & ~PAD_CTL_PKE) | \ + PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm | PAD_CTL_SRE_FAST) + +#define SPI_PAD_CTRL (PAD_CTL_HYS | PAD_CTL_SPEED_MED | \ + PAD_CTL_DSE_40ohm | PAD_CTL_SRE_FAST) + +#define I2C_PAD_CTRL (PAD_CTL_PUS_100K_UP | \ + PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm | PAD_CTL_HYS | \ + PAD_CTL_ODE | PAD_CTL_SRE_FAST) + +#define I2C_PMIC 1 + +#define I2C_PAD MUX_PAD_CTRL(I2C_PAD_CTRL) + +#define ETH_PHY_RESET IMX_GPIO_NR(2, 4) + +int dram_init(void) +{ + gd->ram_size = imx_ddr_size(); + + return 0; +} + +iomux_v3_cfg_t const uart2_pads[] = { + MX6_PAD_SD3_DAT5__UART2_TX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL), + MX6_PAD_SD3_DAT4__UART2_RX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL), +}; + +static void setup_iomux_uart(void) +{ + imx_iomux_v3_setup_multiple_pads(uart2_pads, ARRAY_SIZE(uart2_pads)); +} + +#ifdef CONFIG_TARGET_ZC5202 +iomux_v3_cfg_t const enet_pads[] = { + MX6_PAD_GPIO_18__ENET_RX_CLK | MUX_PAD_CTRL(ENET_PAD_CTRL), + MX6_PAD_ENET_RXD0__ENET_RX_DATA0 | MUX_PAD_CTRL(ENET_PAD_CTRL), + MX6_PAD_ENET_RXD1__ENET_RX_DATA1 | MUX_PAD_CTRL(ENET_PAD_CTRL), + MX6_PAD_KEY_COL2__ENET_RX_DATA2 | MUX_PAD_CTRL(ENET_PAD_CTRL), + MX6_PAD_KEY_COL0__ENET_RX_DATA3 | MUX_PAD_CTRL(ENET_PAD_CTRL), + MX6_PAD_ENET_CRS_DV__ENET_RX_EN | MUX_PAD_CTRL(ENET_PAD_CTRL), + MX6_PAD_ENET_REF_CLK__ENET_TX_CLK | MUX_PAD_CTRL(ENET_PAD_CTRL_CLK), + MX6_PAD_ENET_TXD0__ENET_TX_DATA0 | MUX_PAD_CTRL(ENET_PAD_CTRL), + MX6_PAD_ENET_TXD1__ENET_TX_DATA1 | MUX_PAD_CTRL(ENET_PAD_CTRL), + MX6_PAD_GPIO_19__ENET_TX_ER | MUX_PAD_CTRL(ENET_PAD_CTRL), + MX6_PAD_KEY_ROW2__ENET_TX_DATA2 | MUX_PAD_CTRL(ENET_PAD_CTRL), + MX6_PAD_KEY_ROW0__ENET_TX_DATA3 | MUX_PAD_CTRL(ENET_PAD_CTRL), + MX6_PAD_ENET_TX_EN__ENET_TX_EN | MUX_PAD_CTRL(ENET_PAD_CTRL), + MX6_PAD_ENET_RX_ER__ENET_RX_ER | MUX_PAD_CTRL(ENET_PAD_CTRL_PD), + /* Switch Reset */ + MX6_PAD_NANDF_D4__GPIO2_IO04 | MUX_PAD_CTRL(ENET_PAD_CTRL_PD), + /* Switch Interrupt */ + MX6_PAD_NANDF_D5__GPIO2_IO05 | MUX_PAD_CTRL(NO_PAD_CTRL), + /* use CRS and COL pads as GPIOs */ + MX6_PAD_KEY_COL3__GPIO4_IO12 | MUX_PAD_CTRL(OPEN_PAD_CTRL), + MX6_PAD_KEY_ROW1__GPIO4_IO09 | MUX_PAD_CTRL(OPEN_PAD_CTRL), + +}; + +#define BOARD_NAME "EL6x-ZC5202" +#else +iomux_v3_cfg_t const enet_pads[] = { + MX6_PAD_ENET_MDIO__ENET_MDIO | MUX_PAD_CTRL(ENET_PAD_CTRL), + MX6_PAD_ENET_MDC__ENET_MDC | MUX_PAD_CTRL(ENET_PAD_CTRL), + MX6_PAD_RGMII_TXC__RGMII_TXC | MUX_PAD_CTRL(ENET_PAD_CTRL), + MX6_PAD_RGMII_TD0__RGMII_TD0 | MUX_PAD_CTRL(ENET_PAD_CTRL), + MX6_PAD_RGMII_TD1__RGMII_TD1 | MUX_PAD_CTRL(ENET_PAD_CTRL), + MX6_PAD_RGMII_TD2__RGMII_TD2 | MUX_PAD_CTRL(ENET_PAD_CTRL), + MX6_PAD_RGMII_TD3__RGMII_TD3 | MUX_PAD_CTRL(ENET_PAD_CTRL), + MX6_PAD_RGMII_TX_CTL__RGMII_TX_CTL | MUX_PAD_CTRL(ENET_PAD_CTRL), + MX6_PAD_ENET_REF_CLK__ENET_TX_CLK | MUX_PAD_CTRL(ENET_PAD_CTRL_CLK), + MX6_PAD_RGMII_RXC__RGMII_RXC | MUX_PAD_CTRL(ENET_PAD_CTRL), + MX6_PAD_RGMII_RD0__RGMII_RD0 | MUX_PAD_CTRL(ENET_PAD_CTRL), + MX6_PAD_RGMII_RD1__RGMII_RD1 | MUX_PAD_CTRL(ENET_PAD_CTRL), + MX6_PAD_RGMII_RD2__RGMII_RD2 | MUX_PAD_CTRL(ENET_PAD_CTRL), + MX6_PAD_RGMII_RD3__RGMII_RD3 | MUX_PAD_CTRL(ENET_PAD_CTRL), + MX6_PAD_RGMII_RX_CTL__RGMII_RX_CTL | MUX_PAD_CTRL(ENET_PAD_CTRL), + MX6_PAD_NANDF_D4__GPIO2_IO04 | MUX_PAD_CTRL(NO_PAD_CTRL), + MX6_PAD_NANDF_D5__GPIO2_IO05 | MUX_PAD_CTRL(NO_PAD_CTRL), +}; +#define BOARD_NAME "EL6x-ZC5601" +#endif + +static void setup_iomux_enet(void) +{ + imx_iomux_v3_setup_multiple_pads(enet_pads, ARRAY_SIZE(enet_pads)); + +#ifdef CONFIG_TARGET_ZC5202 + /* set CRS and COL to input */ + gpio_direction_input(IMX_GPIO_NR(4, 9)); + gpio_direction_input(IMX_GPIO_NR(4, 12)); + + /* Reset Switch */ + gpio_direction_output(ETH_PHY_RESET , 0); + mdelay(2); + gpio_set_value(ETH_PHY_RESET, 1); +#endif +} + +int board_phy_config(struct phy_device *phydev) +{ + if (phydev->drv->config) + phydev->drv->config(phydev); + + return 0; +} + +#ifdef CONFIG_MXC_SPI +#ifdef CONFIG_TARGET_ZC5202 +iomux_v3_cfg_t const ecspi1_pads[] = { + MX6_PAD_DISP0_DAT20__ECSPI1_SCLK | MUX_PAD_CTRL(SPI_PAD_CTRL), + MX6_PAD_DISP0_DAT21__ECSPI1_MOSI | MUX_PAD_CTRL(SPI_PAD_CTRL), + MX6_PAD_DISP0_DAT22__ECSPI1_MISO | MUX_PAD_CTRL(SPI_PAD_CTRL), + MX6_PAD_DISP0_DAT23__GPIO5_IO17 | MUX_PAD_CTRL(NO_PAD_CTRL), + MX6_PAD_DISP0_DAT15__GPIO5_IO09 | MUX_PAD_CTRL(NO_PAD_CTRL), +}; + +iomux_v3_cfg_t const ecspi3_pads[] = { + MX6_PAD_DISP0_DAT0__ECSPI3_SCLK | MUX_PAD_CTRL(SPI_PAD_CTRL), + MX6_PAD_DISP0_DAT2__ECSPI3_MISO | MUX_PAD_CTRL(SPI_PAD_CTRL), + MX6_PAD_DISP0_DAT1__ECSPI3_MOSI | MUX_PAD_CTRL(SPI_PAD_CTRL), + MX6_PAD_DISP0_DAT7__GPIO4_IO28 | MUX_PAD_CTRL(SPI_PAD_CTRL), + MX6_PAD_DISP0_DAT8__GPIO4_IO29 | MUX_PAD_CTRL(SPI_PAD_CTRL), + MX6_PAD_DISP0_DAT9__GPIO4_IO30 | MUX_PAD_CTRL(SPI_PAD_CTRL), + MX6_PAD_DISP0_DAT10__GPIO4_IO31 | MUX_PAD_CTRL(SPI_PAD_CTRL), +}; +#endif + +iomux_v3_cfg_t const ecspi4_pads[] = { + MX6_PAD_EIM_D21__ECSPI4_SCLK | MUX_PAD_CTRL(SPI_PAD_CTRL), + MX6_PAD_EIM_D28__ECSPI4_MOSI | MUX_PAD_CTRL(SPI_PAD_CTRL), + MX6_PAD_EIM_D22__ECSPI4_MISO | MUX_PAD_CTRL(SPI_PAD_CTRL), + MX6_PAD_EIM_D20__GPIO3_IO20 | MUX_PAD_CTRL(NO_PAD_CTRL), +}; + +int board_spi_cs_gpio(unsigned bus, unsigned cs) +{ + return (bus == CONFIG_SF_DEFAULT_BUS && cs == CONFIG_SF_DEFAULT_CS) + ? (IMX_GPIO_NR(3, 20)) : -1; +} + +static void setup_spi(void) +{ +#ifdef CONFIG_TARGET_ZC5202 + gpio_request(IMX_GPIO_NR(5, 17), "spi_cs0"); + gpio_request(IMX_GPIO_NR(5, 9), "spi_cs1"); + gpio_direction_output(IMX_GPIO_NR(5, 17), 1); + gpio_direction_output(IMX_GPIO_NR(5, 9), 1); + imx_iomux_v3_setup_multiple_pads(ecspi1_pads, ARRAY_SIZE(ecspi1_pads)); +#endif + + gpio_request(IMX_GPIO_NR(3, 20), "spi4_cs0"); + gpio_direction_output(IMX_GPIO_NR(3, 20), 1); + imx_iomux_v3_setup_multiple_pads(ecspi4_pads, ARRAY_SIZE(ecspi4_pads)); + + enable_spi_clk(true, 3); +} +#endif + +static struct i2c_pads_info i2c_pad_info1 = { + .scl = { + .i2c_mode = MX6_PAD_EIM_EB2__I2C2_SCL | I2C_PAD, + .gpio_mode = MX6_PAD_EIM_EB2__GPIO2_IO30 | I2C_PAD, + .gp = IMX_GPIO_NR(2, 30) + }, + .sda = { + .i2c_mode = MX6_PAD_KEY_ROW3__I2C2_SDA | I2C_PAD, + .gpio_mode = MX6_PAD_KEY_ROW3__GPIO4_IO13 | I2C_PAD, + .gp = IMX_GPIO_NR(4, 13) + } +}; + +static struct i2c_pads_info i2c_pad_info2 = { + .scl = { + .i2c_mode = MX6_PAD_GPIO_5__I2C3_SCL | I2C_PAD, + .gpio_mode = MX6_PAD_GPIO_5__GPIO1_IO05 | I2C_PAD, + .gp = IMX_GPIO_NR(1, 5) + }, + .sda = { + .i2c_mode = MX6_PAD_GPIO_16__I2C3_SDA | I2C_PAD, + .gpio_mode = MX6_PAD_GPIO_16__GPIO7_IO11 | I2C_PAD, + .gp = IMX_GPIO_NR(7, 11) + } +}; + +iomux_v3_cfg_t const usdhc2_pads[] = { + MX6_PAD_SD2_CLK__SD2_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD2_CMD__SD2_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD2_DAT0__SD2_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD2_DAT1__SD2_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD2_DAT2__SD2_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD2_DAT3__SD2_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_GPIO_4__SD2_CD_B | MUX_PAD_CTRL(NO_PAD_CTRL), /* CD */ +}; + +iomux_v3_cfg_t const usdhc4_pads[] = { + MX6_PAD_SD4_CLK__SD4_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD4_CMD__SD4_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD4_DAT0__SD4_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD4_DAT1__SD4_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD4_DAT2__SD4_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD4_DAT3__SD4_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD4_DAT4__SD4_DATA4 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD4_DAT5__SD4_DATA5 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD4_DAT6__SD4_DATA6 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD4_DAT7__SD4_DATA7 | MUX_PAD_CTRL(USDHC_PAD_CTRL), +}; + +#ifdef CONFIG_FSL_ESDHC +struct fsl_esdhc_cfg usdhc_cfg[2] = { + {USDHC2_BASE_ADDR}, + {USDHC4_BASE_ADDR}, +}; + +#define USDHC2_CD_GPIO IMX_GPIO_NR(1, 4) + +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 USDHC2_BASE_ADDR: + ret = !gpio_get_value(USDHC2_CD_GPIO); + break; + case USDHC4_BASE_ADDR: + ret = 1; /* eMMC/uSDHC4 is always present */ + break; + } + + return ret; +} + +int board_mmc_init(bd_t *bis) +{ +#ifndef CONFIG_SPL_BUILD + int ret; + int i; + + /* + * According to the board_mmc_init() the following map is done: + * (U-boot device node) (Physical Port) + * mmc0 SD2 + * mmc1 SD3 + * mmc2 eMMC + */ + for (i = 0; i < CONFIG_SYS_FSL_USDHC_NUM; i++) { + switch (i) { + case 0: + imx_iomux_v3_setup_multiple_pads( + usdhc2_pads, ARRAY_SIZE(usdhc2_pads)); + gpio_direction_input(USDHC2_CD_GPIO); + usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC2_CLK); + break; + case 1: + imx_iomux_v3_setup_multiple_pads( + usdhc4_pads, ARRAY_SIZE(usdhc4_pads)); + usdhc_cfg[1].sdhc_clk = mxc_get_clock(MXC_ESDHC4_CLK); + break; + default: + printf("Warning: you configured more USDHC controllers" + "(%d) then supported by the board (%d)\n", + i + 1, CONFIG_SYS_FSL_USDHC_NUM); + return -EINVAL; + } + + ret = fsl_esdhc_initialize(bis, &usdhc_cfg[i]); + if (ret) + return ret; + } + + return 0; +#else + struct src *psrc = (struct src *)SRC_BASE_ADDR; + unsigned reg = readl(&psrc->sbmr1) >> 11; + + /* + * Upon reading BOOT_CFG register the following map is done: + * Bit 11 and 12 of BOOT_CFG register can determine the current + * mmc port + * 0x1 SD1 + * 0x2 SD2 + * 0x3 SD4 + */ + + switch (reg & 0x3) { + case 0x1: + imx_iomux_v3_setup_multiple_pads( + usdhc2_pads, ARRAY_SIZE(usdhc2_pads)); + usdhc_cfg[0].esdhc_base = USDHC2_BASE_ADDR; + usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC2_CLK); + gd->arch.sdhc_clk = usdhc_cfg[0].sdhc_clk; + break; + case 0x3: + imx_iomux_v3_setup_multiple_pads( + usdhc4_pads, ARRAY_SIZE(usdhc4_pads)); + usdhc_cfg[0].esdhc_base = USDHC4_BASE_ADDR; + usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC4_CLK); + gd->arch.sdhc_clk = usdhc_cfg[0].sdhc_clk; + break; + } + + return fsl_esdhc_initialize(bis, &usdhc_cfg[0]); +#endif + +} +#endif + + +/* + * Do not overwrite the console + * Use always serial for U-Boot console + */ +int overwrite_console(void) +{ + return 1; +} + +int board_eth_init(bd_t *bis) +{ + setup_iomux_enet(); + enable_enet_clk(1); + + return cpu_eth_init(bis); +} + +int board_early_init_f(void) +{ + + setup_iomux_uart(); + setup_spi(); + + return 0; +} + +int board_init(void) +{ + /* address of boot parameters */ + gd->bd->bi_boot_params = PHYS_SDRAM + 0x100; + + setup_i2c(1, CONFIG_SYS_I2C_SPEED, 0x7f, &i2c_pad_info1); + setup_i2c(2, CONFIG_SYS_I2C_SPEED, 0x7f, &i2c_pad_info2); + + return 0; +} + +int power_init_board(void) +{ + struct pmic *p; + int ret; + unsigned int reg; + + ret = power_pfuze100_init(I2C_PMIC); + if (ret) + return ret; + + p = pmic_get("PFUZE100"); + ret = pmic_probe(p); + if (ret) + return ret; + + pmic_reg_read(p, PFUZE100_DEVICEID, ®); + printf("PMIC: PFUZE100 ID=0x%02x\n", reg); + + /* Increase VGEN3 from 2.5 to 2.8V */ + pmic_reg_read(p, PFUZE100_VGEN3VOL, ®); + reg &= ~LDO_VOL_MASK; + reg |= LDOB_2_80V; + pmic_reg_write(p, PFUZE100_VGEN3VOL, reg); + + /* Increase VGEN5 from 2.8 to 3V */ + pmic_reg_read(p, PFUZE100_VGEN5VOL, ®); + reg &= ~LDO_VOL_MASK; + reg |= LDOB_3_00V; + pmic_reg_write(p, PFUZE100_VGEN5VOL, reg); + + /* Set SW1AB stanby volage to 0.975V */ + pmic_reg_read(p, PFUZE100_SW1ABSTBY, ®); + reg &= ~SW1x_STBY_MASK; + reg |= SW1x_0_975V; + pmic_reg_write(p, PFUZE100_SW1ABSTBY, reg); + + /* Set SW1AB/VDDARM step ramp up time from 16us to 4us/25mV */ + pmic_reg_read(p, PFUZE100_SW1ABCONF, ®); + reg &= ~SW1xCONF_DVSSPEED_MASK; + reg |= SW1xCONF_DVSSPEED_4US; + pmic_reg_write(p, PFUZE100_SW1ABCONF, reg); + + /* Set SW1C standby voltage to 0.975V */ + pmic_reg_read(p, PFUZE100_SW1CSTBY, ®); + reg &= ~SW1x_STBY_MASK; + reg |= SW1x_0_975V; + pmic_reg_write(p, PFUZE100_SW1CSTBY, reg); + + /* Set SW1C/VDDSOC step ramp up time from 16us to 4us/25mV */ + pmic_reg_read(p, PFUZE100_SW1CCONF, ®); + reg &= ~SW1xCONF_DVSSPEED_MASK; + reg |= SW1xCONF_DVSSPEED_4US; + pmic_reg_write(p, PFUZE100_SW1CCONF, reg); + + return 0; +} + +#ifdef CONFIG_CMD_BMODE +static const struct boot_mode board_boot_modes[] = { + /* 4 bit bus width */ + {"sd2", MAKE_CFGVAL(0x40, 0x28, 0x00, 0x00)}, + /* 8 bit bus width */ + {"emmc", MAKE_CFGVAL(0x40, 0x38, 0x00, 0x00)}, + {NULL, 0}, +}; +#endif + +int board_late_init(void) +{ +#ifdef CONFIG_CMD_BMODE + add_board_boot_modes(board_boot_modes); +#endif + + setenv("board_name", BOARD_NAME); + return 0; +} + +int checkboard(void) +{ + puts("Board: "); + puts(BOARD_NAME "\n"); + + return 0; +} + +#ifdef CONFIG_SPL_BUILD +#include +#include + +const struct mx6dq_iomux_ddr_regs mx6_ddr_ioregs = { + .dram_sdclk_0 = 0x00020030, + .dram_sdclk_1 = 0x00020030, + .dram_cas = 0x00020030, + .dram_ras = 0x00020030, + .dram_reset = 0x00020030, + .dram_sdcke0 = 0x00003000, + .dram_sdcke1 = 0x00003000, + .dram_sdba2 = 0x00000000, + .dram_sdodt0 = 0x00003030, + .dram_sdodt1 = 0x00003030, + .dram_sdqs0 = 0x00000030, + .dram_sdqs1 = 0x00000030, + .dram_sdqs2 = 0x00000030, + .dram_sdqs3 = 0x00000030, + .dram_sdqs4 = 0x00000030, + .dram_sdqs5 = 0x00000030, + .dram_sdqs6 = 0x00000030, + .dram_sdqs7 = 0x00000030, + .dram_dqm0 = 0x00020030, + .dram_dqm1 = 0x00020030, + .dram_dqm2 = 0x00020030, + .dram_dqm3 = 0x00020030, + .dram_dqm4 = 0x00020030, + .dram_dqm5 = 0x00020030, + .dram_dqm6 = 0x00020030, + .dram_dqm7 = 0x00020030, +}; + +const struct mx6dq_iomux_grp_regs mx6_grp_ioregs = { + .grp_ddr_type = 0x000C0000, + .grp_ddrmode_ctl = 0x00020000, + .grp_ddrpke = 0x00000000, + .grp_addds = 0x00000030, + .grp_ctlds = 0x00000030, + .grp_ddrmode = 0x00020000, + .grp_b0ds = 0x00000030, + .grp_b1ds = 0x00000030, + .grp_b2ds = 0x00000030, + .grp_b3ds = 0x00000030, + .grp_b4ds = 0x00000030, + .grp_b5ds = 0x00000030, + .grp_b6ds = 0x00000030, + .grp_b7ds = 0x00000030, +}; + +const struct mx6_mmdc_calibration mx6_mmcd_calib = { + .p0_mpwldectrl0 = 0x001F001F, + .p0_mpwldectrl1 = 0x001F001F, + .p1_mpwldectrl0 = 0x00440044, + .p1_mpwldectrl1 = 0x00440044, + .p0_mpdgctrl0 = 0x434B0350, + .p0_mpdgctrl1 = 0x034C0359, + .p1_mpdgctrl0 = 0x434B0350, + .p1_mpdgctrl1 = 0x03650348, + .p0_mprddlctl = 0x4436383B, + .p1_mprddlctl = 0x39393341, + .p0_mpwrdlctl = 0x35373933, + .p1_mpwrdlctl = 0x48254A36, +}; + +/* MT41K128M16JT-125 */ +static struct mx6_ddr3_cfg mem_ddr = { + .mem_speed = 1600, + .density = 2, + .width = 16, + .banks = 8, + .rowaddr = 14, + .coladdr = 10, + .pagesz = 2, + .trcd = 1375, + .trcmin = 4875, + .trasmin = 3500, +}; + +static void ccgr_init(void) +{ + struct mxc_ccm_reg *ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR; + + writel(0x00C03F3F, &ccm->CCGR0); + writel(0x0030FC03, &ccm->CCGR1); + writel(0x0FFFC000, &ccm->CCGR2); + writel(0x3FF00000, &ccm->CCGR3); + writel(0x00FFF300, &ccm->CCGR4); + writel(0x0F0000C3, &ccm->CCGR5); + writel(0x000003FF, &ccm->CCGR6); +} + +static void gpr_init(void) +{ + struct iomuxc *iomux = (struct iomuxc *)IOMUXC_BASE_ADDR; + + /* enable AXI cache for VDOA/VPU/IPU */ + writel(0xF00000CF, &iomux->gpr[4]); + /* set IPU AXI-id0 Qos=0xf(bypass) AXI-id1 Qos=0x7 */ + writel(0x007F007F, &iomux->gpr[6]); + writel(0x007F007F, &iomux->gpr[7]); +} + +/* + * This section requires the differentiation between iMX6 Sabre boards, but + * for now, it will configure only for the mx6q variant. + */ +static void spl_dram_init(void) +{ + struct mx6_ddr_sysinfo sysinfo = { + /* width of data bus:0=16,1=32,2=64 */ + .dsize = 2, + /* config for full 4GB range so that get_mem_size() works */ + .cs_density = 32, /* 32Gb per CS */ + /* single chip select */ + .ncs = 1, + .cs1_mirror = 0, + .rtt_wr = 1 /*DDR3_RTT_60_OHM*/, /* RTT_Wr = RZQ/4 */ + .rtt_nom = 1 /*DDR3_RTT_60_OHM*/, /* RTT_Nom = RZQ/4 */ + .walat = 1, /* Write additional latency */ + .ralat = 5, /* Read additional latency */ + .mif3_mode = 3, /* Command prediction working mode */ + .bi_on = 1, /* Bank interleaving enabled */ + .sde_to_rst = 0x10, /* 14 cycles, 200us (JEDEC default) */ + .rst_to_cke = 0x23, /* 33 cycles, 500us (JEDEC default) */ + .ddr_type = DDR_TYPE_DDR3, + }; + + mx6dq_dram_iocfg(64, &mx6_ddr_ioregs, &mx6_grp_ioregs); + mx6_dram_cfg(&sysinfo, &mx6_mmcd_calib, &mem_ddr); +} + +void board_init_f(ulong dummy) +{ + /* setup AIPS and disable watchdog */ + arch_cpu_init(); + + ccgr_init(); + gpr_init(); + + /* iomux and setup of i2c */ + board_early_init_f(); + + /* setup GP timer */ + timer_init(); + + /* UART clocks enabled and gd valid - init serial console */ + preloader_console_init(); + + /* DDR initialization */ + spl_dram_init(); + + /* Clear the BSS. */ + memset(__bss_start, 0, __bss_end - __bss_start); + + /* load/boot image from boot device */ + board_init_r(NULL, 0); +} + +#endif -- cgit From 876a25d289cf9ae6b052ea0dc61b7522e1dec4e1 Mon Sep 17 00:00:00 2001 From: Stefano Babic Date: Wed, 8 Jun 2016 10:50:20 +0200 Subject: mx6: Add Phytec PCM058 i.MX6 Quad Add Phytec-i.MX6 SOM with NAND Support: - 1GB RAM - Ethernet - SPI-NOR Flash - NAND (1024 MB) - external SD - UART Signed-off-by: Stefano Babic Reviewed-by: Fabio Estevam --- board/phytec/pcm058/Kconfig | 12 + board/phytec/pcm058/MAINTAINERS | 6 + board/phytec/pcm058/Makefile | 9 + board/phytec/pcm058/README | 35 +++ board/phytec/pcm058/pcm058.c | 582 ++++++++++++++++++++++++++++++++++++++++ 5 files changed, 644 insertions(+) create mode 100644 board/phytec/pcm058/Kconfig create mode 100644 board/phytec/pcm058/MAINTAINERS create mode 100644 board/phytec/pcm058/Makefile create mode 100644 board/phytec/pcm058/README create mode 100644 board/phytec/pcm058/pcm058.c (limited to 'board') diff --git a/board/phytec/pcm058/Kconfig b/board/phytec/pcm058/Kconfig new file mode 100644 index 0000000000..d099275d48 --- /dev/null +++ b/board/phytec/pcm058/Kconfig @@ -0,0 +1,12 @@ +if TARGET_PCM058 + +config SYS_BOARD + default "pcm058" + +config SYS_VENDOR + default "phytec" + +config SYS_CONFIG_NAME + default "pcm058" + +endif diff --git a/board/phytec/pcm058/MAINTAINERS b/board/phytec/pcm058/MAINTAINERS new file mode 100644 index 0000000000..b0ca40277f --- /dev/null +++ b/board/phytec/pcm058/MAINTAINERS @@ -0,0 +1,6 @@ +PHYTEC PHYBOARD MIRA +M: Stefano Babic +S: Maintained +F: board/phytec/pcm058/ +F: include/configs/pcm058.h +F: configs/pcm058_defconfig diff --git a/board/phytec/pcm058/Makefile b/board/phytec/pcm058/Makefile new file mode 100644 index 0000000000..97733b110c --- /dev/null +++ b/board/phytec/pcm058/Makefile @@ -0,0 +1,9 @@ +# +# Copyright (C) 2007, Guennadi Liakhovetski +# +# (C) Copyright 2011 Freescale Semiconductor, Inc. +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-y := pcm058.o diff --git a/board/phytec/pcm058/README b/board/phytec/pcm058/README new file mode 100644 index 0000000000..3327135645 --- /dev/null +++ b/board/phytec/pcm058/README @@ -0,0 +1,35 @@ +Board information +----------------- + +The SBC produced by Phytec has a SOM based on a i.MX6Q. +The SOM is sold in two versions, with eMMC or with NAND. Support +here is for the SOM with NAND. +The evaluation board "phyBoard-Mira" is thought to be used +together with the SOM. + +More information on the board can be found on manufacturer's +website: + +http://www.phytec.de/produkt/single-board-computer/phyboard-mira/ +http://www.phytec.de/fileadmin/user_upload/images/content/1.Products/SOMs/phyCORE-i.MX6/L-808e_1.pdf + +Building U-Boot +------------------------------- + +$ make pcm058_defconfig +$ make + +This generates the artifacts SPL and u-boot.img. +The SOM can boot from NAND or from SD-Card, having the SPI-NOR +as second option. +The dip switch "DIP-1" on the board let choose between +NAND and SD. + +DIP-1 set to off: Boot first from NAND, then try SPI +DIP-1 set to on: Boot first from SD, then try SPI + +The bootloader was tested with DIP-1 set to on. If a SD-card +is present, then the RBL tries to load SPL from the SD Card, if not, +RBL loads from SPI-NOR. The SPL tries then to load from the same +device where SPL was loaded (SD or SPI). Booting from NAND is +not supported. diff --git a/board/phytec/pcm058/pcm058.c b/board/phytec/pcm058/pcm058.c new file mode 100644 index 0000000000..0ba4a2e268 --- /dev/null +++ b/board/phytec/pcm058/pcm058.c @@ -0,0 +1,582 @@ +/* + * Copyright (C) 2016 Stefano Babic + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +/* + * Please note: there are two version of the board + * one with NAND and the other with eMMC. + * Both NAND and eMMC cannot be set because they share the + * same pins (SD4) + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +#define UART_PAD_CTRL (PAD_CTL_PUS_100K_UP | \ + PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm | \ + PAD_CTL_SRE_FAST | PAD_CTL_HYS) + +#define USDHC_PAD_CTRL (PAD_CTL_PUS_47K_UP | \ + PAD_CTL_SPEED_LOW | PAD_CTL_DSE_80ohm | \ + PAD_CTL_SRE_FAST | PAD_CTL_HYS) + +#define ENET_PAD_CTRL (PAD_CTL_PUS_100K_UP | \ + PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm | PAD_CTL_HYS) + +#define SPI_PAD_CTRL (PAD_CTL_HYS | PAD_CTL_SPEED_MED | \ + PAD_CTL_DSE_40ohm | PAD_CTL_SRE_FAST) + +#define I2C_PAD_CTRL (PAD_CTL_PUS_100K_UP | \ + PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm | PAD_CTL_HYS | \ + PAD_CTL_ODE | PAD_CTL_SRE_FAST) + +#define I2C_PAD MUX_PAD_CTRL(I2C_PAD_CTRL) + +#define ASRC_PAD_CTRL (PAD_CTL_HYS | PAD_CTL_PUS_100K_UP | \ + PAD_CTL_DSE_40ohm | PAD_CTL_SRE_FAST) + +#define NAND_PAD_CTRL (PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED | \ + PAD_CTL_DSE_40ohm | PAD_CTL_SRE_FAST) + +#define ENET_PHY_RESET_GPIO IMX_GPIO_NR(1, 14) +#define USDHC1_CD_GPIO IMX_GPIO_NR(6, 31) +#define USER_LED IMX_GPIO_NR(1, 4) +#define IMX6Q_DRIVE_STRENGTH 0x30 + +int dram_init(void) +{ + gd->ram_size = imx_ddr_size(); + return 0; +} + +void board_turn_off_led(void) +{ + gpio_direction_output(USER_LED, 0); +} + +static iomux_v3_cfg_t const uart1_pads[] = { + MX6_PAD_EIM_D26__UART2_TX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL), + MX6_PAD_EIM_D27__UART2_RX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL), +}; + +static iomux_v3_cfg_t const enet_pads[] = { + MX6_PAD_ENET_MDIO__ENET_MDIO | MUX_PAD_CTRL(ENET_PAD_CTRL), + MX6_PAD_ENET_MDC__ENET_MDC | MUX_PAD_CTRL(ENET_PAD_CTRL), + MX6_PAD_RGMII_TXC__RGMII_TXC | MUX_PAD_CTRL(ENET_PAD_CTRL), + MX6_PAD_RGMII_TD0__RGMII_TD0 | MUX_PAD_CTRL(ENET_PAD_CTRL), + MX6_PAD_RGMII_TD1__RGMII_TD1 | MUX_PAD_CTRL(ENET_PAD_CTRL), + MX6_PAD_RGMII_TD2__RGMII_TD2 | MUX_PAD_CTRL(ENET_PAD_CTRL), + MX6_PAD_RGMII_TD3__RGMII_TD3 | MUX_PAD_CTRL(ENET_PAD_CTRL), + MX6_PAD_RGMII_TX_CTL__RGMII_TX_CTL | MUX_PAD_CTRL(ENET_PAD_CTRL), + MX6_PAD_ENET_REF_CLK__ENET_TX_CLK | MUX_PAD_CTRL(ENET_PAD_CTRL), + MX6_PAD_RGMII_RXC__RGMII_RXC | MUX_PAD_CTRL(ENET_PAD_CTRL), + MX6_PAD_RGMII_RD0__RGMII_RD0 | MUX_PAD_CTRL(ENET_PAD_CTRL), + MX6_PAD_RGMII_RD1__RGMII_RD1 | MUX_PAD_CTRL(ENET_PAD_CTRL), + MX6_PAD_RGMII_RD2__RGMII_RD2 | MUX_PAD_CTRL(ENET_PAD_CTRL), + MX6_PAD_RGMII_RD3__RGMII_RD3 | MUX_PAD_CTRL(ENET_PAD_CTRL), + MX6_PAD_RGMII_RX_CTL__RGMII_RX_CTL | MUX_PAD_CTRL(ENET_PAD_CTRL), + MX6_PAD_SD2_DAT1__GPIO1_IO14 | MUX_PAD_CTRL(NO_PAD_CTRL), +}; + +static iomux_v3_cfg_t const ecspi1_pads[] = { + MX6_PAD_EIM_D16__ECSPI1_SCLK | MUX_PAD_CTRL(SPI_PAD_CTRL), + MX6_PAD_EIM_D17__ECSPI1_MISO | MUX_PAD_CTRL(SPI_PAD_CTRL), + MX6_PAD_EIM_D18__ECSPI1_MOSI | MUX_PAD_CTRL(SPI_PAD_CTRL), + MX6_PAD_EIM_D19__GPIO3_IO19 | MUX_PAD_CTRL(NO_PAD_CTRL), +}; + +/* NAND */ +static iomux_v3_cfg_t const nfc_pads[] = { + MX6_PAD_NANDF_CLE__NAND_CLE | MUX_PAD_CTRL(NAND_PAD_CTRL), + MX6_PAD_NANDF_ALE__NAND_ALE | MUX_PAD_CTRL(NAND_PAD_CTRL), + MX6_PAD_NANDF_WP_B__NAND_WP_B | MUX_PAD_CTRL(NAND_PAD_CTRL), + MX6_PAD_NANDF_RB0__NAND_READY_B | MUX_PAD_CTRL(NAND_PAD_CTRL), + MX6_PAD_NANDF_CS0__NAND_CE0_B | MUX_PAD_CTRL(NAND_PAD_CTRL), + MX6_PAD_NANDF_CS1__NAND_CE1_B | MUX_PAD_CTRL(NAND_PAD_CTRL), + MX6_PAD_NANDF_CS2__NAND_CE2_B | MUX_PAD_CTRL(NAND_PAD_CTRL), + MX6_PAD_NANDF_CS3__NAND_CE3_B | MUX_PAD_CTRL(NAND_PAD_CTRL), + MX6_PAD_SD4_CMD__NAND_RE_B | MUX_PAD_CTRL(NAND_PAD_CTRL), + MX6_PAD_SD4_CLK__NAND_WE_B | MUX_PAD_CTRL(NAND_PAD_CTRL), + MX6_PAD_NANDF_D0__NAND_DATA00 | MUX_PAD_CTRL(NAND_PAD_CTRL), + MX6_PAD_NANDF_D1__NAND_DATA01 | MUX_PAD_CTRL(NAND_PAD_CTRL), + MX6_PAD_NANDF_D2__NAND_DATA02 | MUX_PAD_CTRL(NAND_PAD_CTRL), + MX6_PAD_NANDF_D3__NAND_DATA03 | MUX_PAD_CTRL(NAND_PAD_CTRL), + MX6_PAD_NANDF_D4__NAND_DATA04 | MUX_PAD_CTRL(NAND_PAD_CTRL), + MX6_PAD_NANDF_D5__NAND_DATA05 | MUX_PAD_CTRL(NAND_PAD_CTRL), + MX6_PAD_NANDF_D6__NAND_DATA06 | MUX_PAD_CTRL(NAND_PAD_CTRL), + MX6_PAD_NANDF_D7__NAND_DATA07 | MUX_PAD_CTRL(NAND_PAD_CTRL), + MX6_PAD_SD4_DAT0__NAND_DQS | MUX_PAD_CTRL(NAND_PAD_CTRL), +}; + + +/* GPIOS */ +static iomux_v3_cfg_t const gpios_pads[] = { +}; + +static struct i2c_pads_info i2c_pad_info2 = { + .scl = { + .i2c_mode = MX6_PAD_GPIO_5__I2C3_SCL | I2C_PAD, + .gpio_mode = MX6_PAD_GPIO_5__GPIO1_IO05 | I2C_PAD, + .gp = IMX_GPIO_NR(1, 5) + }, + .sda = { + .i2c_mode = MX6_PAD_GPIO_6__I2C3_SDA | I2C_PAD, + .gpio_mode = MX6_PAD_GPIO_6__GPIO1_IO06 | I2C_PAD, + .gp = IMX_GPIO_NR(1, 6) + } +}; + +static struct fsl_esdhc_cfg usdhc_cfg[] = { + {.esdhc_base = USDHC1_BASE_ADDR, + .max_bus_width = 4}, +#ifndef CONFIG_CMD_NAND + {USDHC4_BASE_ADDR}, +#endif +}; + +static iomux_v3_cfg_t const usdhc1_pads[] = { + MX6_PAD_SD1_CLK__SD1_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD1_CMD__SD1_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD1_DAT0__SD1_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD1_DAT1__SD1_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD1_DAT2__SD1_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD1_DAT3__SD1_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_EIM_BCLK__GPIO6_IO31 | MUX_PAD_CTRL(NO_PAD_CTRL), /* CD */ +}; + +#ifndef CONFIG_CMD_NAND +static iomux_v3_cfg_t const usdhc4_pads[] = { + MX6_PAD_SD4_CLK__SD4_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD4_CMD__SD4_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD4_DAT0__SD4_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD4_DAT1__SD4_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD4_DAT2__SD4_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD4_DAT3__SD4_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD4_DAT4__SD4_DATA4 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD4_DAT5__SD4_DATA5 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD4_DAT6__SD4_DATA6 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD4_DAT7__SD4_DATA7 | MUX_PAD_CTRL(USDHC_PAD_CTRL), +}; +#endif + +int board_mmc_get_env_dev(int devno) +{ + return devno - 1; +} + +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 USDHC1_BASE_ADDR: + ret = !gpio_get_value(USDHC1_CD_GPIO); + break; + case USDHC4_BASE_ADDR: + ret = 1; /* eMMC/uSDHC4 is always present */ + break; + } + + return ret; +} + +int board_mmc_init(bd_t *bis) +{ +#ifndef CONFIG_SPL_BUILD + int ret; + int i; + + for (i = 0; i < CONFIG_SYS_FSL_USDHC_NUM; i++) { + switch (i) { + case 0: + imx_iomux_v3_setup_multiple_pads( + usdhc1_pads, ARRAY_SIZE(usdhc1_pads)); + gpio_direction_input(USDHC1_CD_GPIO); + usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC_CLK); + break; +#ifndef CONFIG_CMD_NAND + case 1: + imx_iomux_v3_setup_multiple_pads( + usdhc4_pads, ARRAY_SIZE(usdhc4_pads)); + usdhc_cfg[1].sdhc_clk = mxc_get_clock(MXC_ESDHC4_CLK); + break; +#endif + default: + printf("Warning: you configured more USDHC controllers" + "(%d) then supported by the board (%d)\n", + i + 1, CONFIG_SYS_FSL_USDHC_NUM); + return -EINVAL; + } + + ret = fsl_esdhc_initialize(bis, &usdhc_cfg[i]); + if (ret) + return ret; + } + + return 0; +#else + struct src *psrc = (struct src *)SRC_BASE_ADDR; + unsigned reg = readl(&psrc->sbmr1) >> 11; + /* + * Upon reading BOOT_CFG register the following map is done: + * Bit 11 and 12 of BOOT_CFG register can determine the current + * mmc port + * 0x1 SD1 + * 0x2 SD2 + * 0x3 SD4 + */ + + switch (reg & 0x3) { + case 0x0: + imx_iomux_v3_setup_multiple_pads( + usdhc1_pads, ARRAY_SIZE(usdhc1_pads)); + gpio_direction_input(USDHC1_CD_GPIO); + usdhc_cfg[0].esdhc_base = USDHC1_BASE_ADDR; + usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC_CLK); + usdhc_cfg[0].max_bus_width = 4; + gd->arch.sdhc_clk = usdhc_cfg[0].sdhc_clk; + break; + } + return fsl_esdhc_initialize(bis, &usdhc_cfg[0]); +#endif +} + +static void setup_iomux_uart(void) +{ + imx_iomux_v3_setup_multiple_pads(uart1_pads, ARRAY_SIZE(uart1_pads)); +} + +static void setup_iomux_enet(void) +{ + imx_iomux_v3_setup_multiple_pads(enet_pads, ARRAY_SIZE(enet_pads)); + + gpio_direction_output(ENET_PHY_RESET_GPIO, 0); + mdelay(10); + gpio_set_value(ENET_PHY_RESET_GPIO, 1); + mdelay(30); +} + +static void setup_spi(void) +{ + gpio_request(IMX_GPIO_NR(3, 19), "spi_cs0"); + gpio_direction_output(IMX_GPIO_NR(3, 19), 1); + + imx_iomux_v3_setup_multiple_pads(ecspi1_pads, ARRAY_SIZE(ecspi1_pads)); + + enable_spi_clk(true, 0); +} + +#ifdef CONFIG_CMD_NAND +static void setup_gpmi_nand(void) +{ + struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR; + + /* config gpmi nand iomux */ + imx_iomux_v3_setup_multiple_pads(nfc_pads, ARRAY_SIZE(nfc_pads)); + + /* gate ENFC_CLK_ROOT clock first,before clk source switch */ + clrbits_le32(&mxc_ccm->CCGR2, MXC_CCM_CCGR2_IOMUX_IPT_CLK_IO_MASK); + + /* config gpmi and bch clock to 100 MHz */ + clrsetbits_le32(&mxc_ccm->cs2cdr, + MXC_CCM_CS2CDR_ENFC_CLK_PODF_MASK | + MXC_CCM_CS2CDR_ENFC_CLK_PRED_MASK | + MXC_CCM_CS2CDR_ENFC_CLK_SEL_MASK, + MXC_CCM_CS2CDR_ENFC_CLK_PODF(0) | + MXC_CCM_CS2CDR_ENFC_CLK_PRED(3) | + MXC_CCM_CS2CDR_ENFC_CLK_SEL(3)); + + /* enable ENFC_CLK_ROOT clock */ + setbits_le32(&mxc_ccm->CCGR2, MXC_CCM_CCGR2_IOMUX_IPT_CLK_IO_MASK); + + /* enable gpmi and bch clock gating */ + setbits_le32(&mxc_ccm->CCGR4, + MXC_CCM_CCGR4_RAWNAND_U_BCH_INPUT_APB_MASK | + MXC_CCM_CCGR4_RAWNAND_U_GPMI_BCH_INPUT_BCH_MASK | + MXC_CCM_CCGR4_RAWNAND_U_GPMI_BCH_INPUT_GPMI_IO_MASK | + MXC_CCM_CCGR4_RAWNAND_U_GPMI_INPUT_APB_MASK | + MXC_CCM_CCGR4_PL301_MX6QPER1_BCH_OFFSET); + + /* enable apbh clock gating */ + setbits_le32(&mxc_ccm->CCGR0, MXC_CCM_CCGR0_APBHDMA_MASK); +} +#endif + +int board_spi_cs_gpio(unsigned bus, unsigned cs) +{ + if (bus != 0 || (cs != 0)) + return -EINVAL; + + return IMX_GPIO_NR(3, 19); +} + +int board_eth_init(bd_t *bis) +{ + setup_iomux_enet(); + + return cpu_eth_init(bis); +} + +int board_early_init_f(void) +{ + setup_iomux_uart(); + + return 0; +} + +int board_init(void) +{ + /* address of boot parameters */ + gd->bd->bi_boot_params = PHYS_SDRAM + 0x100; + +#ifdef CONFIG_SYS_I2C_MXC + setup_i2c(2, CONFIG_SYS_I2C_SPEED, 0x7f, &i2c_pad_info2); +#endif + +#ifdef CONFIG_MXC_SPI + setup_spi(); +#endif + +#ifdef CONFIG_CMD_NAND + setup_gpmi_nand(); +#endif + return 0; +} + + +#ifdef CONFIG_CMD_BMODE +/* + * BOOT_CFG1, BOOT_CFG2, BOOT_CFG3, BOOT_CFG4 + * see Table 8-11 and Table 5-9 + * BOOT_CFG1[7] = 1 (boot from NAND) + * BOOT_CFG1[5] = 0 - raw NAND + * BOOT_CFG1[4] = 0 - default pad settings + * BOOT_CFG1[3:2] = 00 - devices = 1 + * BOOT_CFG1[1:0] = 00 - Row Address Cycles = 3 + * BOOT_CFG2[4:3] = 00 - Boot Search Count = 2 + * BOOT_CFG2[2:1] = 01 - Pages In Block = 64 + * BOOT_CFG2[0] = 0 - Reset time 12ms + */ +static const struct boot_mode board_boot_modes[] = { + /* NAND: 64pages per block, 3 row addr cycles, 2 copies of FCB/DBBT */ + {"nand", MAKE_CFGVAL(0x80, 0x02, 0x00, 0x00)}, + {"mmc0", MAKE_CFGVAL(0x40, 0x20, 0x00, 0x00)}, + {NULL, 0}, +}; +#endif + +int board_late_init(void) +{ +#ifdef CONFIG_CMD_BMODE + add_board_boot_modes(board_boot_modes); +#endif + + return 0; +} + +#ifdef CONFIG_SPL_BUILD +#include +#include + +static const struct mx6dq_iomux_ddr_regs mx6_ddr_ioregs = { + .dram_sdclk_0 = 0x00000030, + .dram_sdclk_1 = 0x00000030, + .dram_cas = 0x00000030, + .dram_ras = 0x00000030, + .dram_reset = 0x00000030, + .dram_sdcke0 = 0x00000030, + .dram_sdcke1 = 0x00000030, + .dram_sdba2 = 0x00000000, + .dram_sdodt0 = 0x00000030, + .dram_sdodt1 = 0x00000030, + .dram_sdqs0 = 0x00000030, + .dram_sdqs1 = 0x00000030, + .dram_sdqs2 = 0x00000030, + .dram_sdqs3 = 0x00000030, + .dram_sdqs4 = 0x00000030, + .dram_sdqs5 = 0x00000030, + .dram_sdqs6 = 0x00000030, + .dram_sdqs7 = 0x00000030, + .dram_dqm0 = 0x00000030, + .dram_dqm1 = 0x00000030, + .dram_dqm2 = 0x00000030, + .dram_dqm3 = 0x00000030, + .dram_dqm4 = 0x00000030, + .dram_dqm5 = 0x00000030, + .dram_dqm6 = 0x00000030, + .dram_dqm7 = 0x00000030, +}; + +static const struct mx6dq_iomux_grp_regs mx6_grp_ioregs = { + .grp_ddr_type = 0x000C0000, + .grp_ddrmode_ctl = 0x00020000, + .grp_ddrpke = 0x00000000, + .grp_addds = IMX6Q_DRIVE_STRENGTH, + .grp_ctlds = IMX6Q_DRIVE_STRENGTH, + .grp_ddrmode = 0x00020000, + .grp_b0ds = IMX6Q_DRIVE_STRENGTH, + .grp_b1ds = IMX6Q_DRIVE_STRENGTH, + .grp_b2ds = IMX6Q_DRIVE_STRENGTH, + .grp_b3ds = IMX6Q_DRIVE_STRENGTH, + .grp_b4ds = IMX6Q_DRIVE_STRENGTH, + .grp_b5ds = IMX6Q_DRIVE_STRENGTH, + .grp_b6ds = IMX6Q_DRIVE_STRENGTH, + .grp_b7ds = IMX6Q_DRIVE_STRENGTH, +}; + +static const struct mx6_mmdc_calibration mx6_mmcd_calib = { + .p0_mpwldectrl0 = 0x00140014, + .p0_mpwldectrl1 = 0x000A0015, + .p1_mpwldectrl0 = 0x000A001E, + .p1_mpwldectrl1 = 0x000A0015, + .p0_mpdgctrl0 = 0x43080314, + .p0_mpdgctrl1 = 0x02680300, + .p1_mpdgctrl0 = 0x430C0318, + .p1_mpdgctrl1 = 0x03000254, + .p0_mprddlctl = 0x3A323234, + .p1_mprddlctl = 0x3E3C3242, + .p0_mpwrdlctl = 0x2A2E3632, + .p1_mpwrdlctl = 0x3C323E34, +}; + +static struct mx6_ddr3_cfg mem_ddr = { + .mem_speed = 1600, + .density = 2, + .width = 16, + .banks = 8, + .rowaddr = 14, + .coladdr = 10, + .pagesz = 2, + .trcd = 1375, + .trcmin = 4875, + .trasmin = 3500, + .SRT = 1, +}; + +static void ccgr_init(void) +{ + struct mxc_ccm_reg *ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR; + + writel(0x00C03F3F, &ccm->CCGR0); + writel(0x0030FC03, &ccm->CCGR1); + writel(0x0FFFC000, &ccm->CCGR2); + writel(0x3FF00000, &ccm->CCGR3); + writel(0x00FFF300, &ccm->CCGR4); + writel(0x0F0000C3, &ccm->CCGR5); + writel(0x000003FF, &ccm->CCGR6); +} + +static void gpr_init(void) +{ + struct iomuxc *iomux = (struct iomuxc *)IOMUXC_BASE_ADDR; + + /* enable AXI cache for VDOA/VPU/IPU */ + writel(0xF00000CF, &iomux->gpr[4]); + /* set IPU AXI-id0 Qos=0xf(bypass) AXI-id1 Qos=0x7 */ + writel(0x007F007F, &iomux->gpr[6]); + writel(0x007F007F, &iomux->gpr[7]); +} + + +static void spl_dram_init(void) +{ + struct mx6_ddr_sysinfo sysinfo = { + /* width of data bus:0=16,1=32,2=64 */ + .dsize = 2, + /* config for full 4GB range so that get_mem_size() works */ + .cs_density = 32, /* 32Gb per CS */ + /* single chip select */ + .ncs = 1, + .cs1_mirror = 0, + .rtt_wr = 1 /*DDR3_RTT_60_OHM*/, /* RTT_Wr = RZQ/4 */ + .rtt_nom = 1 /*DDR3_RTT_60_OHM*/, /* RTT_Nom = RZQ/4 */ + .walat = 1, /* Write additional latency */ + .ralat = 5, /* Read additional latency */ + .mif3_mode = 3, /* Command prediction working mode */ + .bi_on = 1, /* Bank interleaving enabled */ + .sde_to_rst = 0x10, /* 14 cycles, 200us (JEDEC default) */ + .rst_to_cke = 0x23, /* 33 cycles, 500us (JEDEC default) */ + .ddr_type = DDR_TYPE_DDR3, + }; + + mx6dq_dram_iocfg(64, &mx6_ddr_ioregs, &mx6_grp_ioregs); + mx6_dram_cfg(&sysinfo, &mx6_mmcd_calib, &mem_ddr); +} + +void board_boot_order(u32 *spl_boot_list) +{ + spl_boot_list[0] = spl_boot_device(); + printf("Boot device %x\n", spl_boot_list[0]); + switch (spl_boot_list[0]) { + case BOOT_DEVICE_SPI: + spl_boot_list[1] = BOOT_DEVICE_UART; + break; + case BOOT_DEVICE_MMC1: + spl_boot_list[1] = BOOT_DEVICE_SPI; + spl_boot_list[2] = BOOT_DEVICE_UART; + break; + default: + printf("Boot device %x\n", spl_boot_list[0]); + } +} + +void board_init_f(ulong dummy) +{ +#ifdef CONFIG_CMD_NAND + /* Enable NAND */ + setup_gpmi_nand(); +#endif + + /* setup clock gating */ + ccgr_init(); + + /* setup AIPS and disable watchdog */ + arch_cpu_init(); + + /* setup AXI */ + gpr_init(); + + board_early_init_f(); + + /* setup GP timer */ + timer_init(); + + setup_spi(); + + /* UART clocks enabled and gd valid - init serial console */ + preloader_console_init(); + + /* DDR initialization */ + spl_dram_init(); + + /* Clear the BSS. */ + memset(__bss_start, 0, __bss_end - __bss_start); + + /* load/boot image from boot device */ + board_init_r(NULL, 0); +} +#endif -- cgit From 369012e7e96761c1ac4ccb0cd9052c6f56468082 Mon Sep 17 00:00:00 2001 From: Vanessa Maegima Date: Wed, 8 Jun 2016 15:17:54 -0300 Subject: mx6qsabreauto: Avoid hardcoded RAM size Instead of passing the total RAM size via PHYS_SDRAM_SIZE option, we should better use imx_ddr_size() function, which automatically determines the RAM size. Signed-off-by: Vanessa Maegima Acked-by: Fabio Estevam --- board/freescale/mx6qsabreauto/mx6qsabreauto.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'board') diff --git a/board/freescale/mx6qsabreauto/mx6qsabreauto.c b/board/freescale/mx6qsabreauto/mx6qsabreauto.c index d63a979be5..a3ed4cd466 100644 --- a/board/freescale/mx6qsabreauto/mx6qsabreauto.c +++ b/board/freescale/mx6qsabreauto/mx6qsabreauto.c @@ -64,7 +64,7 @@ DECLARE_GLOBAL_DATA_PTR; int dram_init(void) { - gd->ram_size = get_ram_size((void *)PHYS_SDRAM, PHYS_SDRAM_SIZE); + gd->ram_size = imx_ddr_size(); return 0; } -- cgit From e355eec79dd150d6f44e52357b5e805aed6ebc4a Mon Sep 17 00:00:00 2001 From: Gilles Chanteperdrix Date: Thu, 9 Jun 2016 10:33:27 +0200 Subject: wandboard: enable SATA with imx6q Signed-off-by: Gilles Chanteperdrix --- board/wandboard/wandboard.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'board') diff --git a/board/wandboard/wandboard.c b/board/wandboard/wandboard.c index 4ce74cd971..8340dd1a86 100644 --- a/board/wandboard/wandboard.c +++ b/board/wandboard/wandboard.c @@ -345,6 +345,12 @@ int board_early_init_f(void) #if defined(CONFIG_VIDEO_IPUV3) setup_display(); #endif +#ifdef CONFIG_CMD_SATA + /* Only mx6q wandboard has SATA */ + if (is_cpu_type(MXC_CPU_MX6Q)) + setup_sata(); +#endif + return 0; } -- cgit From 8259e9c9adc263a3e9619bd4713dfddea19509b8 Mon Sep 17 00:00:00 2001 From: Vanessa Maegima Date: Thu, 9 Jun 2016 15:28:31 -0300 Subject: mx6slevk: Avoid hardcoded RAM size Instead of passing the total RAM size via PHYS_SDRAM_SIZE option, we should better use imx_ddr_size() function, which automatically determines the RAM size. Signed-off-by: Vanessa Maegima Reviewed-by: Fabio Estevam Reviewed-by: Fabio Estevam --- board/freescale/mx6slevk/mx6slevk.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'board') diff --git a/board/freescale/mx6slevk/mx6slevk.c b/board/freescale/mx6slevk/mx6slevk.c index 256d6029b4..f978e5044e 100644 --- a/board/freescale/mx6slevk/mx6slevk.c +++ b/board/freescale/mx6slevk/mx6slevk.c @@ -61,7 +61,7 @@ DECLARE_GLOBAL_DATA_PTR; int dram_init(void) { - gd->ram_size = get_ram_size((void *)PHYS_SDRAM, PHYS_SDRAM_SIZE); + gd->ram_size = imx_ddr_size(); return 0; } -- cgit From 432a8a55478d431e036e695c3f8b9d9e2536f744 Mon Sep 17 00:00:00 2001 From: Vanessa Maegima Date: Thu, 9 Jun 2016 15:28:32 -0300 Subject: mx6sxsabreauto: Avoid hardcoded RAM size Instead of passing the total RAM size via PHYS_SDRAM_SIZE option, we should better use imx_ddr_size() function, which automatically determines the RAM size. Signed-off-by: Vanessa Maegima Reviewed-by: Fabio Estevam --- board/freescale/mx6sxsabreauto/mx6sxsabreauto.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'board') diff --git a/board/freescale/mx6sxsabreauto/mx6sxsabreauto.c b/board/freescale/mx6sxsabreauto/mx6sxsabreauto.c index 886373c901..44e6a7d141 100644 --- a/board/freescale/mx6sxsabreauto/mx6sxsabreauto.c +++ b/board/freescale/mx6sxsabreauto/mx6sxsabreauto.c @@ -106,7 +106,7 @@ static int port_exp_direction_output(unsigned gpio, int value) int dram_init(void) { - gd->ram_size = PHYS_SDRAM_SIZE; + gd->ram_size = imx_ddr_size(); return 0; } -- cgit From d6b0c468189fad76addd09e9796e87ab61c227df Mon Sep 17 00:00:00 2001 From: Vanessa Maegima Date: Thu, 9 Jun 2016 15:28:33 -0300 Subject: mx6sxsabresd: Avoid hardcoded RAM size Instead of passing the total RAM size via PHYS_SDRAM_SIZE option, we should better use imx_ddr_size() function, which automatically determines the RAM size. Signed-off-by: Vanessa Maegima --- board/freescale/mx6sxsabresd/mx6sxsabresd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'board') diff --git a/board/freescale/mx6sxsabresd/mx6sxsabresd.c b/board/freescale/mx6sxsabresd/mx6sxsabresd.c index 25e009ee9b..8d95c51aaf 100644 --- a/board/freescale/mx6sxsabresd/mx6sxsabresd.c +++ b/board/freescale/mx6sxsabresd/mx6sxsabresd.c @@ -64,7 +64,7 @@ DECLARE_GLOBAL_DATA_PTR; int dram_init(void) { - gd->ram_size = PHYS_SDRAM_SIZE; + gd->ram_size = imx_ddr_size(); return 0; } -- cgit From 6d7aa51accd3ae19ad25259f46a6043ef3f02ce2 Mon Sep 17 00:00:00 2001 From: Diego Dorta Date: Fri, 10 Jun 2016 12:07:29 -0300 Subject: pico-imx6ul: Add Ethernet support Pico-imx6ul has a KSZ8081 Ethernet PHY. Add support for it. Signed-off-by: Diego Dorta Acked-by: Fabio Estevam Reviewed-by: Stefano Babic --- board/technexion/pico-imx6ul/pico-imx6ul.c | 84 ++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) (limited to 'board') diff --git a/board/technexion/pico-imx6ul/pico-imx6ul.c b/board/technexion/pico-imx6ul/pico-imx6ul.c index c038d4326e..fc746ec965 100644 --- a/board/technexion/pico-imx6ul/pico-imx6ul.c +++ b/board/technexion/pico-imx6ul/pico-imx6ul.c @@ -16,6 +16,8 @@ #include #include #include +#include +#include #include #include #include @@ -34,6 +36,87 @@ DECLARE_GLOBAL_DATA_PTR; PAD_CTL_PUS_47K_UP | PAD_CTL_SPEED_LOW | \ PAD_CTL_DSE_80ohm | PAD_CTL_SRE_FAST | PAD_CTL_HYS) +#define MDIO_PAD_CTRL (PAD_CTL_PUS_100K_UP | PAD_CTL_PUE | \ + PAD_CTL_DSE_48ohm | PAD_CTL_SRE_FAST | PAD_CTL_ODE) + +#define ENET_PAD_CTRL (PAD_CTL_PUS_100K_UP | PAD_CTL_PUE | \ + PAD_CTL_SPEED_HIGH | \ + PAD_CTL_DSE_48ohm | PAD_CTL_SRE_FAST) + +#define ENET_CLK_PAD_CTRL (PAD_CTL_DSE_40ohm | PAD_CTL_SRE_FAST) + +#define RMII_PHY_RESET IMX_GPIO_NR(1, 28) + +static iomux_v3_cfg_t const fec_pads[] = { + MX6_PAD_ENET1_TX_EN__ENET2_MDC | MUX_PAD_CTRL(MDIO_PAD_CTRL), + MX6_PAD_ENET1_TX_DATA1__ENET2_MDIO | MUX_PAD_CTRL(MDIO_PAD_CTRL), + MX6_PAD_ENET2_TX_DATA0__ENET2_TDATA00 | MUX_PAD_CTRL(ENET_PAD_CTRL), + MX6_PAD_ENET2_TX_DATA1__ENET2_TDATA01 | MUX_PAD_CTRL(ENET_PAD_CTRL), + MX6_PAD_ENET2_TX_CLK__ENET2_REF_CLK2 | MUX_PAD_CTRL(ENET_CLK_PAD_CTRL), + MX6_PAD_ENET2_TX_EN__ENET2_TX_EN | MUX_PAD_CTRL(ENET_PAD_CTRL), + MX6_PAD_ENET2_RX_DATA0__ENET2_RDATA00 | MUX_PAD_CTRL(ENET_PAD_CTRL), + MX6_PAD_ENET2_RX_DATA1__ENET2_RDATA01 | MUX_PAD_CTRL(ENET_PAD_CTRL), + MX6_PAD_ENET2_RX_EN__ENET2_RX_EN | MUX_PAD_CTRL(ENET_PAD_CTRL), + MX6_PAD_ENET2_RX_ER__ENET2_RX_ER | MUX_PAD_CTRL(ENET_PAD_CTRL), + MX6_PAD_UART4_TX_DATA__GPIO1_IO28 | MUX_PAD_CTRL(NO_PAD_CTRL), +}; + +static void setup_iomux_fec(void) +{ + imx_iomux_v3_setup_multiple_pads(fec_pads, ARRAY_SIZE(fec_pads)); +} + +int board_eth_init(bd_t *bis) +{ + setup_iomux_fec(); + + gpio_direction_output(RMII_PHY_RESET, 0); + /* + * According to KSZ8081MNX-RNB manual: + * For warm reset, the reset (RST#) pin should be asserted low for a + * minimum of 500μs. The strap-in pin values are read and updated + * at the de-assertion of reset. + */ + udelay(500); + + gpio_direction_output(RMII_PHY_RESET, 1); + /* + * According to KSZ8081MNX-RNB manual: + * After the de-assertion of reset, wait a minimum of 100μs before + * starting programming on the MIIM (MDC/MDIO) interface. + */ + udelay(100); + + return fecmxc_initialize(bis); +} + +static int setup_fec(void) +{ + struct iomuxc *const iomuxc_regs = (struct iomuxc *)IOMUXC_BASE_ADDR; + int ret; + + clrsetbits_le32(&iomuxc_regs->gpr[1], IOMUX_GPR1_FEC2_MASK, + IOMUX_GPR1_FEC2_CLOCK_MUX1_SEL_MASK); + + ret = enable_fec_anatop_clock(1, ENET_50MHZ); + if (ret) + return ret; + + enable_enet_clk(1); + + return 0; +} + +int board_phy_config(struct phy_device *phydev) +{ + phy_write(phydev, MDIO_DEVAD_NONE, 0x1f, 0x8190); + + if (phydev->drv->config) + phydev->drv->config(phydev); + + return 0; +} + int dram_init(void) { gd->ram_size = imx_ddr_size(); @@ -106,6 +189,7 @@ int board_init(void) /* Address of boot parameters */ gd->bd->bi_boot_params = PHYS_SDRAM + 0x100; + setup_fec(); setup_usb(); return 0; -- cgit From dab149345930b9b5bdc55e88d761d8494c692aa2 Mon Sep 17 00:00:00 2001 From: Vanessa Maegima Date: Wed, 15 Jun 2016 12:48:15 -0300 Subject: pico-imx6ul: Add a README file Add a README file to help users to install U-boot binary into the eMMC. Signed-off-by: Vanessa Maegima Reviewed-by: Fabio Estevam --- board/technexion/pico-imx6ul/README | 57 +++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 board/technexion/pico-imx6ul/README (limited to 'board') diff --git a/board/technexion/pico-imx6ul/README b/board/technexion/pico-imx6ul/README new file mode 100644 index 0000000000..2f66095097 --- /dev/null +++ b/board/technexion/pico-imx6ul/README @@ -0,0 +1,57 @@ +How to Update U-Boot on Pico-imx6ul board +----------------------------------------- + +Required software on the host PC: + +- imx_usb_loader: https://github.com/boundarydevices/imx_usb_loader + +- dfu-util: http://dfu-util.sourceforge.net/releases/ + +Build U-Boot for Pico: + +$ make mrproper +$ make pico-imx6ul_defconfig +$ make + +This will generate the U-Boot binary called u-boot.imx. + +Put pico board in USB download mode (refer to the document +http://www.wandboard.org/images/hobbit/hobbitboard-imx6ul-reva1.pdf page 15) + +Connect a USB to serial adapter between the host PC and pico + +Connect a USB cable between the OTG pico port and the host PC + +Open a terminal program such as minicom + +Copy u-boot.imx to the imx_usb_loader folder. + +Load u-boot.imx via USB: + +$ sudo ./imx_usb u-boot.imx + +Then U-Boot should start and its messages will appear in the console program. + +Use the default environment variables: + +=> env default -f -a +=> saveenv + +Run the DFU command: +=> dfu 0 mmc 0 + +Transfer u-boot.imx that will be flashed into the eMMC: + +$ sudo dfu-util -D u-boot.imx -a boot + +Then on the U-Boot prompt the following message should be seen after a +successful upgrade: + +#DOWNLOAD ... OK +Ctrl+C to exit ... + +Remove power from the pico board. + +Put pico board into normal boot mode + +Power up the board and the new updated U-Boot should boot from eMMC. -- cgit From ca103e09960cb09a0501e558bfa9c921fb61d0bc Mon Sep 17 00:00:00 2001 From: Vanessa Maegima Date: Mon, 13 Jun 2016 13:01:38 -0300 Subject: pico-imx6ul: Add USB Host support Add USB host support. Tested by connecting a USB pen drive: => usb start starting USB... USB0: Port not available. USB1: USB EHCI 1.00 scanning bus 1 for devices... 2 USB Device(s) found scanning usb for storage devices... 1 Storage Device(s) found Signed-off-by: Vanessa Maegima Reviewed-by: Fabio Estevam --- board/technexion/pico-imx6ul/pico-imx6ul.c | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) (limited to 'board') diff --git a/board/technexion/pico-imx6ul/pico-imx6ul.c b/board/technexion/pico-imx6ul/pico-imx6ul.c index fc746ec965..b0b8f054c1 100644 --- a/board/technexion/pico-imx6ul/pico-imx6ul.c +++ b/board/technexion/pico-imx6ul/pico-imx6ul.c @@ -142,6 +142,9 @@ static iomux_v3_cfg_t const usdhc1_pads[] = { MX6_PAD_NAND_CLE__USDHC1_DATA7 | MUX_PAD_CTRL(USDHC_PAD_CTRL), }; +#define USB_OTHERREGS_OFFSET 0x800 +#define UCTRL_PWR_POL (1 << 9) + static iomux_v3_cfg_t const usb_otg_pad[] = { MX6_PAD_GPIO1_IO00__ANATOP_OTG1_ID | MUX_PAD_CTRL(OTG_ID_PAD_CTRL), }; @@ -181,7 +184,26 @@ int board_early_init_f(void) int board_usb_phy_mode(int port) { - return USB_INIT_DEVICE; + if (port == 1) + return USB_INIT_HOST; + else + return USB_INIT_DEVICE; +} + +int board_ehci_hcd_init(int port) +{ + u32 *usbnc_usb_ctrl; + + if (port > 1) + return -EINVAL; + + usbnc_usb_ctrl = (u32 *)(USB_BASE_ADDR + USB_OTHERREGS_OFFSET + + port * 4); + + /* Set Power polarity */ + setbits_le32(usbnc_usb_ctrl, UCTRL_PWR_POL); + + return 0; } int board_init(void) -- cgit From a02ab5eaff966ecf746bc4e90696c84efb4b113b Mon Sep 17 00:00:00 2001 From: Andrej Rosano Date: Mon, 20 Jun 2016 17:21:49 +0200 Subject: usbarmory: Add board_run_command() function Define a default board_run_command() function. This function contains the commands needed to boot the board when CLI is disabled (CONFIG_CMDLINE=n). Signed-off-by: Andrej Rosano --- board/inversepath/usbarmory/usbarmory.c | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) (limited to 'board') diff --git a/board/inversepath/usbarmory/usbarmory.c b/board/inversepath/usbarmory/usbarmory.c index a809039ac5..c875e786a4 100644 --- a/board/inversepath/usbarmory/usbarmory.c +++ b/board/inversepath/usbarmory/usbarmory.c @@ -415,3 +415,34 @@ int checkboard(void) puts("Board: Inverse Path USB armory MkI\n"); return 0; } + +#ifndef CONFIG_CMDLINE +static char *ext2_argv[] = { + "ext2load", + "mmc", + "0:1", + USBARMORY_FIT_ADDR, + USBARMORY_FIT_PATH +}; + +static char *bootm_argv[] = { + "bootm", + USBARMORY_FIT_ADDR +}; + +int board_run_command(const char *cmdline) +{ + printf("%s %s %s %s %s\n", ext2_argv[0], ext2_argv[1], ext2_argv[2], + ext2_argv[3], ext2_argv[4]); + + if (do_ext2load(NULL, 0, 5, ext2_argv) != 0) { + udelay(5*1000*1000); + return 1; + } + + printf("%s %s\n", bootm_argv[0], bootm_argv[1]); + do_bootm(NULL, 0, 2, bootm_argv); + + return 1; +} +#endif -- cgit From 88e4774efdf6ae4bf43969ad95ce67d0f228b91a Mon Sep 17 00:00:00 2001 From: Vanessa Maegima Date: Wed, 13 Jul 2016 14:27:32 -0300 Subject: pico-imx6ul: Add PMIC support Add PMIC support. Tested by command "pmic PFUZE3000 dump". Signed-off-by: Vanessa Maegima Reviewed-by: Fabio Estevam --- board/technexion/pico-imx6ul/pico-imx6ul.c | 70 ++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) (limited to 'board') diff --git a/board/technexion/pico-imx6ul/pico-imx6ul.c b/board/technexion/pico-imx6ul/pico-imx6ul.c index b0b8f054c1..5cbf803e7e 100644 --- a/board/technexion/pico-imx6ul/pico-imx6ul.c +++ b/board/technexion/pico-imx6ul/pico-imx6ul.c @@ -14,13 +14,18 @@ #include #include #include +#include #include #include #include #include #include +#include #include #include +#include +#include +#include "../../freescale/common/pfuze.h" DECLARE_GLOBAL_DATA_PTR; @@ -32,6 +37,11 @@ DECLARE_GLOBAL_DATA_PTR; PAD_CTL_PUS_22K_UP | PAD_CTL_SPEED_LOW | \ PAD_CTL_DSE_80ohm | PAD_CTL_SRE_FAST | PAD_CTL_HYS) +#define I2C_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE | \ + PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED | \ + PAD_CTL_DSE_40ohm | PAD_CTL_HYS | \ + PAD_CTL_ODE) + #define OTG_ID_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE | \ PAD_CTL_PUS_47K_UP | PAD_CTL_SPEED_LOW | \ PAD_CTL_DSE_80ohm | PAD_CTL_SRE_FAST | PAD_CTL_HYS) @@ -47,6 +57,23 @@ DECLARE_GLOBAL_DATA_PTR; #define RMII_PHY_RESET IMX_GPIO_NR(1, 28) +#ifdef CONFIG_SYS_I2C_MXC +#define PC MUX_PAD_CTRL(I2C_PAD_CTRL) +/* I2C2 for PMIC */ +struct i2c_pads_info i2c_pad_info1 = { + .scl = { + .i2c_mode = MX6_PAD_GPIO1_IO02__I2C1_SCL | PC, + .gpio_mode = MX6_PAD_GPIO1_IO02__GPIO1_IO02 | PC, + .gp = IMX_GPIO_NR(1, 2), + }, + .sda = { + .i2c_mode = MX6_PAD_GPIO1_IO03__I2C1_SDA | PC, + .gpio_mode = MX6_PAD_GPIO1_IO03__GPIO1_IO03 | PC, + .gp = IMX_GPIO_NR(1, 3), + }, +}; +#endif + static iomux_v3_cfg_t const fec_pads[] = { MX6_PAD_ENET1_TX_EN__ENET2_MDC | MUX_PAD_CTRL(MDIO_PAD_CTRL), MX6_PAD_ENET1_TX_DATA1__ENET2_MDIO | MUX_PAD_CTRL(MDIO_PAD_CTRL), @@ -182,6 +209,45 @@ int board_early_init_f(void) return 0; } +#ifdef CONFIG_POWER +#define I2C_PMIC 0 +static struct pmic *pfuze; +int power_init_board(void) +{ + int ret; + unsigned int reg, rev_id; + + ret = power_pfuze3000_init(I2C_PMIC); + if (ret) + return ret; + + pfuze = pmic_get("PFUZE3000"); + ret = pmic_probe(pfuze); + if (ret) + return ret; + + pmic_reg_read(pfuze, PFUZE3000_DEVICEID, ®); + pmic_reg_read(pfuze, PFUZE3000_REVID, &rev_id); + printf("PMIC: PFUZE3000 DEV_ID=0x%x REV_ID=0x%x\n", reg, rev_id); + + /* disable Low Power Mode during standby mode */ + pmic_reg_read(pfuze, PFUZE3000_LDOGCTL, ®); + reg |= 0x1; + pmic_reg_write(pfuze, PFUZE3000_LDOGCTL, reg); + + /* SW1B step ramp up time from 2us to 4us/25mV */ + pmic_reg_write(pfuze, PFUZE3000_SW1BCONF, 0x40); + + /* SW1B mode to APS/PFM */ + pmic_reg_write(pfuze, PFUZE3000_SW1BMODE, 0xc); + + /* SW1B standby voltage set to 0.975V */ + pmic_reg_write(pfuze, PFUZE3000_SW1BSTBY, 0xb); + + return 0; +} +#endif + int board_usb_phy_mode(int port) { if (port == 1) @@ -211,6 +277,10 @@ int board_init(void) /* Address of boot parameters */ gd->bd->bi_boot_params = PHYS_SDRAM + 0x100; + #ifdef CONFIG_SYS_I2C_MXC + setup_i2c(0, CONFIG_SYS_I2C_SPEED, 0x7f, &i2c_pad_info1); + #endif + setup_fec(); setup_usb(); -- cgit From 62d6bac66038163641d6ba43ac47347447fedb82 Mon Sep 17 00:00:00 2001 From: Christopher Spinrath Date: Tue, 12 Jul 2016 23:37:36 +0200 Subject: ARM: board: cm_fx6: fixup mtd partitions in the fdt The cm-fx6 module has an on-board st,m25p compatible spi flash chip used for U-Boot (binary & environment). Overwrite the partitions in the device tree by the partition table provided in the mtdparts environment variable, if it is set. This allows to specify a kernel independent partitioning in the environment and provides a convient way for the user to adapt the partition table. Signed-off-by: Christopher Spinrath Acked-by: Igor Grinberg --- board/compulab/cm_fx6/cm_fx6.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) (limited to 'board') diff --git a/board/compulab/cm_fx6/cm_fx6.c b/board/compulab/cm_fx6/cm_fx6.c index 712057a6c5..566c19b4c9 100644 --- a/board/compulab/cm_fx6/cm_fx6.c +++ b/board/compulab/cm_fx6/cm_fx6.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -28,6 +29,7 @@ #include #include #include +#include #include "common.h" #include "../common/eeprom.h" #include "../common/common.h" @@ -581,6 +583,17 @@ int cm_fx6_setup_ecspi(void) { return 0; } #ifdef CONFIG_OF_BOARD_SETUP #define USDHC3_PATH "/soc/aips-bus@02100000/usdhc@02198000/" + +struct node_info nodes[] = { + /* + * Both entries target the same flash chip. The st,m25p compatible + * is used in the vendor device trees, while upstream uses (the + * documented) jedec,spi-nor comptatible. + */ + { "st,m25p", MTD_DEV_TYPE_NOR, }, + { "jedec,spi-nor", MTD_DEV_TYPE_NOR, }, +}; + int ft_board_setup(void *blob, bd_t *bd) { u32 baseboard_rev; @@ -589,6 +602,8 @@ int ft_board_setup(void *blob, bd_t *bd) char baseboard_name[16]; int err; + fdt_shrink_to_minimum(blob); /* Make room for new properties */ + /* MAC addr */ if (eth_getenv_enetaddr("ethaddr", enetaddr)) { fdt_find_and_setprop(blob, @@ -607,7 +622,6 @@ int ft_board_setup(void *blob, bd_t *bd) return 0; /* Assume not an early revision SB-FX6m baseboard */ if (!strncmp("SB-FX6m", baseboard_name, 7) && baseboard_rev <= 120) { - fdt_shrink_to_minimum(blob); /* Make room for new properties */ nodeoffset = fdt_path_offset(blob, USDHC3_PATH); fdt_delprop(blob, nodeoffset, "cd-gpios"); fdt_find_and_setprop(blob, USDHC3_PATH, "broken-cd", @@ -616,6 +630,8 @@ int ft_board_setup(void *blob, bd_t *bd) NULL, 0, 1); } + fdt_fixup_mtdparts(blob, nodes, ARRAY_SIZE(nodes)); + return 0; } #endif -- cgit From a5ad8ec9207cd30a6e1ddb5f4e334a295fc0d2e8 Mon Sep 17 00:00:00 2001 From: Stefano Babic Date: Wed, 20 Jul 2016 17:53:56 +0200 Subject: mx6: wandboard: fix warning due to missing prototype Signed-off-by: Stefano Babic CC: Fabio Estevam Reviewed-by: Fabio Estevam --- board/wandboard/wandboard.c | 1 + 1 file changed, 1 insertion(+) (limited to 'board') diff --git a/board/wandboard/wandboard.c b/board/wandboard/wandboard.c index 8340dd1a86..10cad3fd80 100644 --- a/board/wandboard/wandboard.c +++ b/board/wandboard/wandboard.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include -- cgit From 5a08ad6fdc43cc756ef1ebe046bbfd4290204fbe Mon Sep 17 00:00:00 2001 From: Tim Harvey Date: Fri, 17 Jun 2016 06:10:41 -0700 Subject: imx: ventana: add dt fixup for GW16082 irq mapping The GW16082 mini-PCI expansion mezzanine uses a TI XIO2001 PCIe-to-PCI bridge with legacy INTA/B/C/D interrupts. These interrupts are assigned in the reverse order according to the PCI spec. If the TI bridge is found on the Ventana PCI bus, add device-tree nodes according to bus enumeration explicitly defining the interrupt mapping to override the default PCI mapping in the Linux kernel. This allows the GW16082 to work with upstream kernels that support device-tree irq parsing. Signed-off-by: Tim Harvey --- board/gateworks/gw_ventana/gw_ventana.c | 228 ++++++++++++++++++++++++++++++++ 1 file changed, 228 insertions(+) (limited to 'board') diff --git a/board/gateworks/gw_ventana/gw_ventana.c b/board/gateworks/gw_ventana/gw_ventana.c index 70395ac91d..7d569ad625 100644 --- a/board/gateworks/gw_ventana/gw_ventana.c +++ b/board/gateworks/gw_ventana/gw_ventana.c @@ -491,14 +491,54 @@ int imx6_pcie_toggle_reset(void) * GPIO's as PERST# signals for its downstream ports - configure the GPIO's * properly and assert reset for 100ms. */ +#define MAX_PCI_DEVS 32 +struct pci_dev { + pci_dev_t devfn; + unsigned short vendor; + unsigned short device; + unsigned short class; + unsigned short busno; /* subbordinate busno */ + struct pci_dev *ppar; +}; +struct pci_dev pci_devs[MAX_PCI_DEVS]; +int pci_devno; +int pci_bridgeno; + void board_pci_fixup_dev(struct pci_controller *hose, pci_dev_t dev, unsigned short vendor, unsigned short device, unsigned short class) { + int i; u32 dw; + struct pci_dev *pdev = &pci_devs[pci_devno++]; debug("%s: %02d:%02d.%02d: %04x:%04x\n", __func__, PCI_BUS(dev), PCI_DEV(dev), PCI_FUNC(dev), vendor, device); + + /* store array of devs for later use in device-tree fixup */ + pdev->devfn = dev; + pdev->vendor = vendor; + pdev->device = device; + pdev->class = class; + pdev->ppar = NULL; + if (class == PCI_CLASS_BRIDGE_PCI) + pdev->busno = ++pci_bridgeno; + else + pdev->busno = 0; + + /* fixup RC - it should be 00:00.0 not 00:01.0 */ + if (PCI_BUS(dev) == 0) + pdev->devfn = 0; + + /* find dev's parent */ + for (i = 0; i < pci_devno; i++) { + if (pci_devs[i].busno == PCI_BUS(pdev->devfn)) { + pdev->ppar = &pci_devs[i]; + break; + } + } + + /* assert downstream PERST# */ if (vendor == PCI_VENDOR_ID_PLX && (device & 0xfff0) == 0x8600 && PCI_DEV(dev) == 0 && PCI_FUNC(dev) == 0) { @@ -802,6 +842,189 @@ static inline void ft_delprop_path(void *blob, const char *path, } } +#if defined(CONFIG_CMD_PCI) +#define PCI_ID(x) ( \ + (PCI_BUS(x->devfn)<<16)| \ + (PCI_DEV(x->devfn)<<11)| \ + (PCI_FUNC(x->devfn)<<8) \ + ) +#define PCIE_PATH "/soc/pcie@0x01000000" +int fdt_add_pci_node(void *blob, int par, struct pci_dev *dev) +{ + uint32_t reg[5]; + char node[32]; + int np; + + sprintf(node, "pcie@%d,%d,%d", PCI_BUS(dev->devfn), + PCI_DEV(dev->devfn), PCI_FUNC(dev->devfn)); + + np = fdt_subnode_offset(blob, par, node); + if (np >= 0) + return np; + np = fdt_add_subnode(blob, par, node); + if (np < 0) { + printf(" %s failed: no space\n", __func__); + return np; + } + + memset(reg, 0, sizeof(reg)); + reg[0] = cpu_to_fdt32(PCI_ID(dev)); + fdt_setprop(blob, np, "reg", reg, sizeof(reg)); + + return np; +} + +/* build a path of nested PCI devs for all bridges passed through */ +int fdt_add_pci_path(void *blob, struct pci_dev *dev) +{ + struct pci_dev *bridges[MAX_PCI_DEVS]; + int k, np; + + /* build list of parents */ + np = fdt_path_offset(blob, PCIE_PATH); + if (np < 0) + return np; + + k = 0; + while (dev) { + bridges[k++] = dev; + dev = dev->ppar; + }; + + /* now add them the to DT in reverse order */ + while (k--) { + np = fdt_add_pci_node(blob, np, bridges[k]); + if (np < 0) + break; + } + + return np; +} + +/* + * The GW16082 has a hardware errata errata such that it's + * INTA/B/C/D are mis-mapped to its four slots (slot12-15). Because + * of this normal PCI interrupt swizzling will not work so we will + * provide an irq-map via device-tree. + */ +int fdt_fixup_gw16082(void *blob, int np, struct pci_dev *dev) +{ + int len; + int host; + uint32_t imap_new[8*4*4]; + const uint32_t *imap; + uint32_t irq[4]; + uint32_t reg[4]; + int i; + + /* build irq-map based on host controllers map */ + host = fdt_path_offset(blob, PCIE_PATH); + if (host < 0) { + printf(" %s failed: missing host\n", __func__); + return host; + } + + /* use interrupt data from root complex's node */ + imap = fdt_getprop(blob, host, "interrupt-map", &len); + if (!imap || len != 128) { + printf(" %s failed: invalid interrupt-map\n", + __func__); + return -FDT_ERR_NOTFOUND; + } + + /* obtain irq's of host controller in pin order */ + for (i = 0; i < 4; i++) + irq[(fdt32_to_cpu(imap[(i*8)+3])-1)%4] = imap[(i*8)+6]; + + /* + * determine number of swizzles necessary: + * For each bridge we pass through we need to swizzle + * the number of the slot we are on. + */ + struct pci_dev *d; + int b; + b = 0; + d = dev->ppar; + while(d && d->ppar) { + b += PCI_DEV(d->devfn); + d = d->ppar; + } + + /* create new irq mappings for slots12-15 + * + * J3 AD28 12 INTD INTA + * J4 AD29 13 INTC INTD + * J5 AD30 14 INTB INTC + * J2 AD31 15 INTA INTB + */ + for (i = 0; i < 4; i++) { + /* addr matches bus:dev:func */ + u32 addr = dev->busno << 16 | (12+i) << 11; + + /* default cells from root complex */ + memcpy(&imap_new[i*32], imap, 128); + /* first cell is PCI device address (BDF) */ + imap_new[(i*32)+(0*8)+0] = cpu_to_fdt32(addr); + imap_new[(i*32)+(1*8)+0] = cpu_to_fdt32(addr); + imap_new[(i*32)+(2*8)+0] = cpu_to_fdt32(addr); + imap_new[(i*32)+(3*8)+0] = cpu_to_fdt32(addr); + /* third cell is pin */ + imap_new[(i*32)+(0*8)+3] = cpu_to_fdt32(1); + imap_new[(i*32)+(1*8)+3] = cpu_to_fdt32(2); + imap_new[(i*32)+(2*8)+3] = cpu_to_fdt32(3); + imap_new[(i*32)+(3*8)+3] = cpu_to_fdt32(4); + /* sixth cell is relative interrupt */ + imap_new[(i*32)+(0*8)+6] = irq[(15-(12+i)+b+0)%4]; + imap_new[(i*32)+(1*8)+6] = irq[(15-(12+i)+b+1)%4]; + imap_new[(i*32)+(2*8)+6] = irq[(15-(12+i)+b+2)%4]; + imap_new[(i*32)+(3*8)+6] = irq[(15-(12+i)+b+3)%4]; + } + fdt_setprop(blob, np, "interrupt-map", imap_new, + sizeof(imap_new)); + reg[0] = cpu_to_fdt32(0xfff00); + reg[1] = 0; + reg[2] = 0; + reg[3] = cpu_to_fdt32(0x7); + fdt_setprop(blob, np, "interrupt-map-mask", reg, sizeof(reg)); + fdt_setprop_cell(blob, np, "#interrupt-cells", 1); + fdt_setprop_string(blob, np, "device_type", "pci"); + fdt_setprop_cell(blob, np, "#address-cells", 3); + fdt_setprop_cell(blob, np, "#size-cells", 2); + printf(" Added custom interrupt-map for GW16082\n"); + + return 0; +} + +/* + * PCI DT nodes must be nested therefore if we need to apply a DT fixup + * we will walk the PCI bus and add bridge nodes up to the device receiving + * the fixup. + */ +void ft_board_pci_fixup(void *blob, bd_t *bd) +{ + int i, np; + struct pci_dev *dev; + + for (i = 0; i < pci_devno; i++) { + dev = &pci_devs[i]; + + /* + * The GW16082 consists of a TI XIO2001 PCIe-to-PCI bridge and + * an EEPROM at i2c1-0x50. + */ + if ((dev->vendor == PCI_VENDOR_ID_TI) && + (dev->device == 0x8240) && + (i2c_set_bus_num(1) == 0) && + (i2c_probe(0x50) == 0)) + { + np = fdt_add_pci_path(blob, dev); + if (np > 0) + fdt_fixup_gw16082(blob, np, dev); + } + } +} +#endif /* if defined(CONFIG_CMD_PCI) */ + /* * called prior to booting kernel or by 'fdt boardsetup' command * @@ -976,6 +1199,11 @@ int ft_board_setup(void *blob, bd_t *bd) "no-1-8-v"); } +#if defined(CONFIG_CMD_PCI) + if (!getenv("nopcifixup")) + ft_board_pci_fixup(blob, bd); +#endif + /* * Peripheral Config: * remove nodes by alias path if EEPROM config tells us the -- cgit From 5c34c2abb86a8e74234390300e4c852603b11621 Mon Sep 17 00:00:00 2001 From: Tim Harvey Date: Fri, 17 Jun 2016 06:10:42 -0700 Subject: imx: ventana: add dt fixup for eth1 mac-address Ventana boards with a PCI Marvell Sky2 GigE MAC require the MAC address to be placed in a DT node in order for the mainline linux driver to obtain it. Signed-off-by: Tim Harvey --- board/gateworks/gw_ventana/gw_ventana.c | 35 +++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) (limited to 'board') diff --git a/board/gateworks/gw_ventana/gw_ventana.c b/board/gateworks/gw_ventana/gw_ventana.c index 7d569ad625..b3390a17b9 100644 --- a/board/gateworks/gw_ventana/gw_ventana.c +++ b/board/gateworks/gw_ventana/gw_ventana.c @@ -995,6 +995,32 @@ int fdt_fixup_gw16082(void *blob, int np, struct pci_dev *dev) return 0; } +/* The sky2 GigE MAC obtains it's MAC addr from device-tree by default */ +int fdt_fixup_sky2(void *blob, int np, struct pci_dev *dev) +{ + char *tmp, *end; + char mac[16]; + unsigned char mac_addr[6]; + int j; + + sprintf(mac, "eth1addr"); + tmp = getenv(mac); + if (tmp) { + for (j = 0; j < 6; j++) { + mac_addr[j] = tmp ? + simple_strtoul(tmp, &end,16) : 0; + if (tmp) + tmp = (*end) ? end+1 : end; + } + fdt_setprop(blob, np, "local-mac-address", mac_addr, + sizeof(mac_addr)); + printf(" Added mac addr for eth1\n"); + return 0; + } + + return -1; +} + /* * PCI DT nodes must be nested therefore if we need to apply a DT fixup * we will walk the PCI bus and add bridge nodes up to the device receiving @@ -1021,6 +1047,15 @@ void ft_board_pci_fixup(void *blob, bd_t *bd) if (np > 0) fdt_fixup_gw16082(blob, np, dev); } + + /* ethernet1 mac address */ + else if ((dev->vendor == PCI_VENDOR_ID_MARVELL) && + (dev->device == 0x4380)) + { + np = fdt_add_pci_path(blob, dev); + if (np > 0) + fdt_fixup_sky2(blob, np, dev); + } } } #endif /* if defined(CONFIG_CMD_PCI) */ -- cgit From e49621b357b1ea86170eacd3de8f03af422743e6 Mon Sep 17 00:00:00 2001 From: Tim Harvey Date: Fri, 15 Jul 2016 07:14:22 -0700 Subject: imx: ventana: make RS232 enable board specific Not all Ventana boards have an RS232 transceiver, make it board specific. Signed-off-by: Tim Harvey --- board/gateworks/gw_ventana/common.c | 34 +++++++++++++++++++++++++--------- board/gateworks/gw_ventana/common.h | 2 ++ 2 files changed, 27 insertions(+), 9 deletions(-) (limited to 'board') diff --git a/board/gateworks/gw_ventana/common.c b/board/gateworks/gw_ventana/common.c index 929dde9880..9546f31acb 100644 --- a/board/gateworks/gw_ventana/common.c +++ b/board/gateworks/gw_ventana/common.c @@ -132,14 +132,14 @@ void setup_ventana_i2c(void) /* common to add baseboards */ static iomux_v3_cfg_t const gw_gpio_pads[] = { - /* RS232_EN# */ - IOMUX_PADS(PAD_SD4_DAT3__GPIO2_IO11 | DIO_PAD_CFG), /* SD3_VSELECT */ IOMUX_PADS(PAD_NANDF_CS1__GPIO6_IO14 | DIO_PAD_CFG), }; /* prototype */ static iomux_v3_cfg_t const gwproto_gpio_pads[] = { + /* RS232_EN# */ + IOMUX_PADS(PAD_SD4_DAT3__GPIO2_IO11 | DIO_PAD_CFG), /* PANLEDG# */ IOMUX_PADS(PAD_KEY_COL0__GPIO4_IO06 | DIO_PAD_CFG), /* PANLEDR# */ @@ -183,6 +183,8 @@ static iomux_v3_cfg_t const gw51xx_gpio_pads[] = { }; static iomux_v3_cfg_t const gw52xx_gpio_pads[] = { + /* RS232_EN# */ + IOMUX_PADS(PAD_SD4_DAT3__GPIO2_IO11 | DIO_PAD_CFG), /* MSATA_EN */ IOMUX_PADS(PAD_SD4_DAT0__GPIO2_IO08 | DIO_PAD_CFG), /* PANLEDG# */ @@ -214,6 +216,8 @@ static iomux_v3_cfg_t const gw52xx_gpio_pads[] = { }; static iomux_v3_cfg_t const gw53xx_gpio_pads[] = { + /* RS232_EN# */ + IOMUX_PADS(PAD_SD4_DAT3__GPIO2_IO11 | DIO_PAD_CFG), /* MSATA_EN */ IOMUX_PADS(PAD_SD4_DAT0__GPIO2_IO08 | DIO_PAD_CFG), /* CAN_STBY */ @@ -245,6 +249,8 @@ static iomux_v3_cfg_t const gw53xx_gpio_pads[] = { }; static iomux_v3_cfg_t const gw54xx_gpio_pads[] = { + /* RS232_EN# */ + IOMUX_PADS(PAD_SD4_DAT3__GPIO2_IO11 | DIO_PAD_CFG), /* MSATA_EN */ IOMUX_PADS(PAD_SD4_DAT0__GPIO2_IO08 | DIO_PAD_CFG), /* CAN_STBY */ @@ -468,6 +474,7 @@ struct ventana gpio_cfg[GW_UNKNOWN] = { .usb_sel = IMX_GPIO_NR(1, 2), .wdis = IMX_GPIO_NR(7, 12), .msata_en = GP_MSATA_SEL, + .rs232_en = GP_RS232_EN, }, /* GW53xx */ @@ -513,6 +520,7 @@ struct ventana gpio_cfg[GW_UNKNOWN] = { .vidin_en = IMX_GPIO_NR(3, 31), .wdis = IMX_GPIO_NR(7, 12), .msata_en = GP_MSATA_SEL, + .rs232_en = GP_RS232_EN, }, /* GW54xx */ @@ -560,6 +568,7 @@ struct ventana gpio_cfg[GW_UNKNOWN] = { .pcie_sson = IMX_GPIO_NR(1, 20), .wdis = IMX_GPIO_NR(5, 17), .msata_en = GP_MSATA_SEL, + .rs232_en = GP_RS232_EN, }, /* GW551x */ @@ -682,10 +691,6 @@ void setup_iomux_gpio(int board, struct ventana_board_info *info) gpio_request(GP_USB_OTG_PWR, "usbotg_pwr"); gpio_direction_output(GP_USB_OTG_PWR, 0); - /* RS232_EN# */ - gpio_request(GP_RS232_EN, "rs232_en"); - gpio_direction_output(GP_RS232_EN, 0); - if (board >= GW_UNKNOWN) return; @@ -693,6 +698,12 @@ void setup_iomux_gpio(int board, struct ventana_board_info *info) imx_iomux_v3_setup_multiple_pads(gpio_cfg[board].gpio_pads, gpio_cfg[board].num_pads); + /* RS232_EN# */ + if (gpio_cfg[board].rs232_en) { + gpio_request(gpio_cfg[board].rs232_en, "rs232_en"); + gpio_direction_output(gpio_cfg[board].rs232_en, 0); + } + /* GW522x Uses GPIO3_IO23 for PCIE_RST# */ if (board == GW52xx && info->model[4] == '2') gpio_cfg[board].pcie_rst = IMX_GPIO_NR(3, 23); @@ -788,7 +799,10 @@ void setup_board_gpio(int board, struct ventana_board_info *info) return; /* RS232_EN# */ - gpio_direction_output(GP_RS232_EN, (hwconfig("rs232")) ? 0 : 1); + if (gpio_cfg[board].rs232_en) { + gpio_direction_output(gpio_cfg[board].rs232_en, + (hwconfig("rs232")) ? 0 : 1); + } /* MSATA Enable */ if (gpio_cfg[board].msata_en && is_cpu_type(MXC_CPU_MX6Q)) { @@ -851,8 +865,10 @@ void setup_board_gpio(int board, struct ventana_board_info *info) printf("MSATA: %s\n", (hwconfig("msata") ? "enabled" : "disabled")); } - printf("RS232: %s\n", (hwconfig("rs232")) ? - "enabled" : "disabled"); + if (gpio_cfg[board].rs232_en) { + printf("RS232: %s\n", (hwconfig("rs232")) ? + "enabled" : "disabled"); + } } } diff --git a/board/gateworks/gw_ventana/common.h b/board/gateworks/gw_ventana/common.h index d037767ecc..389d3aa4ee 100644 --- a/board/gateworks/gw_ventana/common.h +++ b/board/gateworks/gw_ventana/common.h @@ -78,6 +78,8 @@ struct ventana { int usb_sel; int wdis; int msata_en; + int rs232_en; + /* various features */ bool usd_vsel; }; -- cgit From 1800ffa83e3fe4a3178606a2254d902503b7c80d Mon Sep 17 00:00:00 2001 From: Tim Harvey Date: Fri, 15 Jul 2016 07:14:23 -0700 Subject: imx: ventana: make number of digital I/O's dynamic Replace the static list of board-specific digital I/O's with a dynamic list. Signed-off-by: Tim Harvey --- board/gateworks/gw_ventana/common.c | 399 ++++++++++++++++---------------- board/gateworks/gw_ventana/common.h | 8 +- board/gateworks/gw_ventana/gw_ventana.c | 2 +- 3 files changed, 199 insertions(+), 210 deletions(-) (limited to 'board') diff --git a/board/gateworks/gw_ventana/common.c b/board/gateworks/gw_ventana/common.c index 9546f31acb..59e3ff88b2 100644 --- a/board/gateworks/gw_ventana/common.c +++ b/board/gateworks/gw_ventana/common.c @@ -338,6 +338,183 @@ static iomux_v3_cfg_t const gw553x_gpio_pads[] = { IOMUX_PADS(PAD_GPIO_17__GPIO7_IO12 | DIO_PAD_CFG), }; +/* Digital I/O */ +struct dio_cfg gw51xx_dio[] = { + { + { IOMUX_PADS(PAD_SD1_DAT0__GPIO1_IO16) }, + IMX_GPIO_NR(1, 16), + { 0, 0 }, + 0 + }, + { + { IOMUX_PADS(PAD_SD1_DAT2__GPIO1_IO19) }, + IMX_GPIO_NR(1, 19), + { IOMUX_PADS(PAD_SD1_DAT2__PWM2_OUT) }, + 2 + }, + { + { IOMUX_PADS(PAD_SD1_DAT1__GPIO1_IO17) }, + IMX_GPIO_NR(1, 17), + { IOMUX_PADS(PAD_SD1_DAT1__PWM3_OUT) }, + 3 + }, + { + { IOMUX_PADS(PAD_SD1_CMD__GPIO1_IO18) }, + IMX_GPIO_NR(1, 18), + { IOMUX_PADS(PAD_SD1_CMD__PWM4_OUT) }, + 4 + }, +}; + +struct dio_cfg gw52xx_dio[] = { + { + { IOMUX_PADS(PAD_SD1_DAT0__GPIO1_IO16) }, + IMX_GPIO_NR(1, 16), + { 0, 0 }, + 0 + }, + { + { IOMUX_PADS(PAD_SD1_DAT2__GPIO1_IO19) }, + IMX_GPIO_NR(1, 19), + { IOMUX_PADS(PAD_SD1_DAT2__PWM2_OUT) }, + 2 + }, + { + { IOMUX_PADS(PAD_SD1_DAT1__GPIO1_IO17) }, + IMX_GPIO_NR(1, 17), + { IOMUX_PADS(PAD_SD1_DAT1__PWM3_OUT) }, + 3 + }, + { + { IOMUX_PADS(PAD_SD1_CLK__GPIO1_IO20) }, + IMX_GPIO_NR(1, 20), + { 0, 0 }, + 0 + }, +}; + +struct dio_cfg gw53xx_dio[] = { + { + { IOMUX_PADS(PAD_SD1_DAT0__GPIO1_IO16) }, + IMX_GPIO_NR(1, 16), + { 0, 0 }, + 0 + }, + { + { IOMUX_PADS(PAD_SD1_DAT2__GPIO1_IO19) }, + IMX_GPIO_NR(1, 19), + { IOMUX_PADS(PAD_SD1_DAT2__PWM2_OUT) }, + 2 + }, + { + { IOMUX_PADS(PAD_SD1_DAT1__GPIO1_IO17) }, + IMX_GPIO_NR(1, 17), + { IOMUX_PADS(PAD_SD1_DAT1__PWM3_OUT) }, + 3 + }, + { + {IOMUX_PADS(PAD_SD1_CLK__GPIO1_IO20) }, + IMX_GPIO_NR(1, 20), + { 0, 0 }, + 0 + }, +}; + +struct dio_cfg gw54xx_dio[] = { + { + { IOMUX_PADS(PAD_GPIO_9__GPIO1_IO09) }, + IMX_GPIO_NR(1, 9), + { IOMUX_PADS(PAD_GPIO_9__PWM1_OUT) }, + 1 + }, + { + { IOMUX_PADS(PAD_SD1_DAT2__GPIO1_IO19) }, + IMX_GPIO_NR(1, 19), + { IOMUX_PADS(PAD_SD1_DAT2__PWM2_OUT) }, + 2 + }, + { + { IOMUX_PADS(PAD_SD4_DAT1__GPIO2_IO09) }, + IMX_GPIO_NR(2, 9), + { IOMUX_PADS(PAD_SD4_DAT1__PWM3_OUT) }, + 3 + }, + { + { IOMUX_PADS(PAD_SD4_DAT2__GPIO2_IO10) }, + IMX_GPIO_NR(2, 10), + { IOMUX_PADS(PAD_SD4_DAT2__PWM4_OUT) }, + 4 + }, +}; + +struct dio_cfg gw551x_dio[] = { + { + { IOMUX_PADS(PAD_SD1_DAT2__GPIO1_IO19) }, + IMX_GPIO_NR(1, 19), + { IOMUX_PADS(PAD_SD1_DAT2__PWM2_OUT) }, + 2 + }, + { + { IOMUX_PADS(PAD_SD1_DAT1__GPIO1_IO17) }, + IMX_GPIO_NR(1, 17), + { IOMUX_PADS(PAD_SD1_DAT1__PWM3_OUT) }, + 3 + }, +}; + +struct dio_cfg gw552x_dio[] = { + { + { IOMUX_PADS(PAD_SD1_DAT0__GPIO1_IO16) }, + IMX_GPIO_NR(1, 16), + { 0, 0 }, + 0 + }, + { + { IOMUX_PADS(PAD_SD1_DAT2__GPIO1_IO19) }, + IMX_GPIO_NR(1, 19), + { IOMUX_PADS(PAD_SD1_DAT2__PWM2_OUT) }, + 2 + }, + { + { IOMUX_PADS(PAD_SD1_DAT1__GPIO1_IO17) }, + IMX_GPIO_NR(1, 17), + { IOMUX_PADS(PAD_SD1_DAT1__PWM3_OUT) }, + 3 + }, + { + {IOMUX_PADS(PAD_SD1_CLK__GPIO1_IO20) }, + IMX_GPIO_NR(1, 20), + { 0, 0 }, + 0 + }, +}; + +struct dio_cfg gw553x_dio[] = { + { + { IOMUX_PADS(PAD_SD1_DAT0__GPIO1_IO16) }, + IMX_GPIO_NR(1, 16), + { 0, 0 }, + 0 + }, + { + { IOMUX_PADS(PAD_SD1_DAT2__GPIO1_IO19) }, + IMX_GPIO_NR(1, 19), + { IOMUX_PADS(PAD_SD1_DAT2__PWM2_OUT) }, + 2 + }, + { + { IOMUX_PADS(PAD_SD1_DAT1__GPIO1_IO17) }, + IMX_GPIO_NR(1, 17), + { IOMUX_PADS(PAD_SD1_DAT1__PWM3_OUT) }, + 3 + }, + { + { IOMUX_PADS(PAD_SD1_CMD__GPIO1_IO18) }, + IMX_GPIO_NR(1, 18), + { IOMUX_PADS(PAD_SD1_CMD__PWM4_OUT) }, + 4 + }, +}; /* * Board Specific GPIO @@ -347,33 +524,8 @@ struct ventana gpio_cfg[GW_UNKNOWN] = { { .gpio_pads = gw54xx_gpio_pads, .num_pads = ARRAY_SIZE(gw54xx_gpio_pads)/2, - .dio_cfg = { - { - { IOMUX_PADS(PAD_GPIO_9__GPIO1_IO09) }, - IMX_GPIO_NR(1, 9), - { IOMUX_PADS(PAD_GPIO_9__PWM1_OUT) }, - 1 - }, - { - { IOMUX_PADS(PAD_SD1_DAT2__GPIO1_IO19) }, - IMX_GPIO_NR(1, 19), - { IOMUX_PADS(PAD_SD1_DAT2__PWM2_OUT) }, - 2 - }, - { - { IOMUX_PADS(PAD_SD4_DAT1__GPIO2_IO09) }, - IMX_GPIO_NR(2, 9), - { IOMUX_PADS(PAD_SD4_DAT1__PWM3_OUT) }, - 3 - }, - { - { IOMUX_PADS(PAD_SD4_DAT2__GPIO2_IO10) }, - IMX_GPIO_NR(2, 10), - { IOMUX_PADS(PAD_SD4_DAT2__PWM4_OUT) }, - 4 - }, - }, - .num_gpios = 4, + .dio_cfg = gw54xx_dio, + .dio_num = ARRAY_SIZE(gw54xx_dio), .leds = { IMX_GPIO_NR(4, 6), IMX_GPIO_NR(4, 10), @@ -391,33 +543,8 @@ struct ventana gpio_cfg[GW_UNKNOWN] = { { .gpio_pads = gw51xx_gpio_pads, .num_pads = ARRAY_SIZE(gw51xx_gpio_pads)/2, - .dio_cfg = { - { - { IOMUX_PADS(PAD_SD1_DAT0__GPIO1_IO16) }, - IMX_GPIO_NR(1, 16), - { 0, 0 }, - 0 - }, - { - { IOMUX_PADS(PAD_SD1_DAT2__GPIO1_IO19) }, - IMX_GPIO_NR(1, 19), - { IOMUX_PADS(PAD_SD1_DAT2__PWM2_OUT) }, - 2 - }, - { - { IOMUX_PADS(PAD_SD1_DAT1__GPIO1_IO17) }, - IMX_GPIO_NR(1, 17), - { IOMUX_PADS(PAD_SD1_DAT1__PWM3_OUT) }, - 3 - }, - { - { IOMUX_PADS(PAD_SD1_CMD__GPIO1_IO18) }, - IMX_GPIO_NR(1, 18), - { IOMUX_PADS(PAD_SD1_CMD__PWM4_OUT) }, - 4 - }, - }, - .num_gpios = 4, + .dio_cfg = gw51xx_dio, + .dio_num = ARRAY_SIZE(gw51xx_dio), .leds = { IMX_GPIO_NR(4, 6), IMX_GPIO_NR(4, 10), @@ -434,33 +561,8 @@ struct ventana gpio_cfg[GW_UNKNOWN] = { { .gpio_pads = gw52xx_gpio_pads, .num_pads = ARRAY_SIZE(gw52xx_gpio_pads)/2, - .dio_cfg = { - { - { IOMUX_PADS(PAD_SD1_DAT0__GPIO1_IO16) }, - IMX_GPIO_NR(1, 16), - { 0, 0 }, - 0 - }, - { - { IOMUX_PADS(PAD_SD1_DAT2__GPIO1_IO19) }, - IMX_GPIO_NR(1, 19), - { IOMUX_PADS(PAD_SD1_DAT2__PWM2_OUT) }, - 2 - }, - { - { IOMUX_PADS(PAD_SD1_DAT1__GPIO1_IO17) }, - IMX_GPIO_NR(1, 17), - { IOMUX_PADS(PAD_SD1_DAT1__PWM3_OUT) }, - 3 - }, - { - { IOMUX_PADS(PAD_SD1_CLK__GPIO1_IO20) }, - IMX_GPIO_NR(1, 20), - { 0, 0 }, - 0 - }, - }, - .num_gpios = 4, + .dio_cfg = gw52xx_dio, + .dio_num = ARRAY_SIZE(gw52xx_dio), .leds = { IMX_GPIO_NR(4, 6), IMX_GPIO_NR(4, 7), @@ -481,33 +583,8 @@ struct ventana gpio_cfg[GW_UNKNOWN] = { { .gpio_pads = gw53xx_gpio_pads, .num_pads = ARRAY_SIZE(gw53xx_gpio_pads)/2, - .dio_cfg = { - { - { IOMUX_PADS(PAD_SD1_DAT0__GPIO1_IO16) }, - IMX_GPIO_NR(1, 16), - { 0, 0 }, - 0 - }, - { - { IOMUX_PADS(PAD_SD1_DAT2__GPIO1_IO19) }, - IMX_GPIO_NR(1, 19), - { IOMUX_PADS(PAD_SD1_DAT2__PWM2_OUT) }, - 2 - }, - { - { IOMUX_PADS(PAD_SD1_DAT1__GPIO1_IO17) }, - IMX_GPIO_NR(1, 17), - { IOMUX_PADS(PAD_SD1_DAT1__PWM3_OUT) }, - 3 - }, - { - {IOMUX_PADS(PAD_SD1_CLK__GPIO1_IO20) }, - IMX_GPIO_NR(1, 20), - { 0, 0 }, - 0 - }, - }, - .num_gpios = 4, + .dio_cfg = gw53xx_dio, + .dio_num = ARRAY_SIZE(gw53xx_dio), .leds = { IMX_GPIO_NR(4, 6), IMX_GPIO_NR(4, 7), @@ -527,33 +604,8 @@ struct ventana gpio_cfg[GW_UNKNOWN] = { { .gpio_pads = gw54xx_gpio_pads, .num_pads = ARRAY_SIZE(gw54xx_gpio_pads)/2, - .dio_cfg = { - { - { IOMUX_PADS(PAD_GPIO_9__GPIO1_IO09) }, - IMX_GPIO_NR(1, 9), - { IOMUX_PADS(PAD_GPIO_9__PWM1_OUT) }, - 1 - }, - { - { IOMUX_PADS(PAD_SD1_DAT2__GPIO1_IO19) }, - IMX_GPIO_NR(1, 19), - { IOMUX_PADS(PAD_SD1_DAT2__PWM2_OUT) }, - 2 - }, - { - { IOMUX_PADS(PAD_SD4_DAT1__GPIO2_IO09) }, - IMX_GPIO_NR(2, 9), - { IOMUX_PADS(PAD_SD4_DAT1__PWM3_OUT) }, - 3 - }, - { - { IOMUX_PADS(PAD_SD4_DAT2__GPIO2_IO10) }, - IMX_GPIO_NR(2, 10), - { IOMUX_PADS(PAD_SD4_DAT2__PWM4_OUT) }, - 4 - }, - }, - .num_gpios = 4, + .dio_cfg = gw54xx_dio, + .dio_num = ARRAY_SIZE(gw54xx_dio), .leds = { IMX_GPIO_NR(4, 6), IMX_GPIO_NR(4, 7), @@ -575,21 +627,8 @@ struct ventana gpio_cfg[GW_UNKNOWN] = { { .gpio_pads = gw551x_gpio_pads, .num_pads = ARRAY_SIZE(gw551x_gpio_pads)/2, - .dio_cfg = { - { - { IOMUX_PADS(PAD_SD1_DAT2__GPIO1_IO19) }, - IMX_GPIO_NR(1, 19), - { IOMUX_PADS(PAD_SD1_DAT2__PWM2_OUT) }, - 2 - }, - { - { IOMUX_PADS(PAD_SD1_DAT1__GPIO1_IO17) }, - IMX_GPIO_NR(1, 17), - { IOMUX_PADS(PAD_SD1_DAT1__PWM3_OUT) }, - 3 - }, - }, - .num_gpios = 2, + .dio_cfg = gw551x_dio, + .dio_num = ARRAY_SIZE(gw551x_dio), .leds = { IMX_GPIO_NR(4, 7), }, @@ -601,33 +640,8 @@ struct ventana gpio_cfg[GW_UNKNOWN] = { { .gpio_pads = gw552x_gpio_pads, .num_pads = ARRAY_SIZE(gw552x_gpio_pads)/2, - .dio_cfg = { - { - { IOMUX_PADS(PAD_SD1_DAT0__GPIO1_IO16) }, - IMX_GPIO_NR(1, 16), - { 0, 0 }, - 0 - }, - { - { IOMUX_PADS(PAD_SD1_DAT2__GPIO1_IO19) }, - IMX_GPIO_NR(1, 19), - { IOMUX_PADS(PAD_SD1_DAT2__PWM2_OUT) }, - 2 - }, - { - { IOMUX_PADS(PAD_SD1_DAT1__GPIO1_IO17) }, - IMX_GPIO_NR(1, 17), - { IOMUX_PADS(PAD_SD1_DAT1__PWM3_OUT) }, - 3 - }, - { - {IOMUX_PADS(PAD_SD1_CLK__GPIO1_IO20) }, - IMX_GPIO_NR(1, 20), - { 0, 0 }, - 0 - }, - }, - .num_gpios = 4, + .dio_cfg = gw552x_dio, + .dio_num = ARRAY_SIZE(gw552x_dio), .leds = { IMX_GPIO_NR(4, 6), IMX_GPIO_NR(4, 7), @@ -643,33 +657,8 @@ struct ventana gpio_cfg[GW_UNKNOWN] = { { .gpio_pads = gw553x_gpio_pads, .num_pads = ARRAY_SIZE(gw553x_gpio_pads)/2, - .dio_cfg = { - { - { IOMUX_PADS(PAD_SD1_DAT0__GPIO1_IO16) }, - IMX_GPIO_NR(1, 16), - { 0, 0 }, - 0 - }, - { - { IOMUX_PADS(PAD_SD1_DAT2__GPIO1_IO19) }, - IMX_GPIO_NR(1, 19), - { IOMUX_PADS(PAD_SD1_DAT2__PWM2_OUT) }, - 2 - }, - { - { IOMUX_PADS(PAD_SD1_DAT1__GPIO1_IO17) }, - IMX_GPIO_NR(1, 17), - { IOMUX_PADS(PAD_SD1_DAT1__PWM3_OUT) }, - 3 - }, - { - { IOMUX_PADS(PAD_SD1_CMD__GPIO1_IO18) }, - IMX_GPIO_NR(1, 18), - { IOMUX_PADS(PAD_SD1_CMD__PWM4_OUT) }, - 4 - }, - }, - .num_gpios = 4, + .dio_cfg = gw553x_dio, + .dio_num = ARRAY_SIZE(gw553x_dio), .leds = { IMX_GPIO_NR(4, 10), IMX_GPIO_NR(4, 11), @@ -820,7 +809,7 @@ void setup_board_gpio(int board, struct ventana_board_info *info) * Configure DIO pinmux/padctl registers * see IMX6DQRM/IMX6SDLRM IOMUXC_SW_PAD_CTL_PAD_* register definitions */ - for (i = 0; i < gpio_cfg[board].num_gpios; i++) { + for (i = 0; i < gpio_cfg[board].dio_num; i++) { struct dio_cfg *cfg = &gpio_cfg[board].dio_cfg[i]; iomux_v3_cfg_t ctrl = DIO_PAD_CFG; unsigned cputype = is_cpu_type(MXC_CPU_MX6Q) ? 0 : 1; diff --git a/board/gateworks/gw_ventana/common.h b/board/gateworks/gw_ventana/common.h index 389d3aa4ee..3d7aff1077 100644 --- a/board/gateworks/gw_ventana/common.h +++ b/board/gateworks/gw_ventana/common.h @@ -48,8 +48,8 @@ #define PC MUX_PAD_CTRL(I2C_PAD_CTRL) /* - * each baseboard has 4 user configurable Digital IO lines which can - * be pinmuxed as a GPIO or in some cases a PWM + * each baseboard has an optional set user configurable Digital IO lines which + * can be pinmuxed as a GPIO or in some cases a PWM */ struct dio_cfg { iomux_v3_cfg_t gpio_padmux[2]; @@ -63,8 +63,8 @@ struct ventana { iomux_v3_cfg_t const *gpio_pads; int num_pads; /* DIO pinmux/val */ - struct dio_cfg dio_cfg[4]; - int num_gpios; + struct dio_cfg *dio_cfg; + int dio_num; /* various gpios (0 if non-existent) */ int leds[3]; int pcie_rst; diff --git a/board/gateworks/gw_ventana/gw_ventana.c b/board/gateworks/gw_ventana/gw_ventana.c index b3390a17b9..930cec8c5a 100644 --- a/board/gateworks/gw_ventana/gw_ventana.c +++ b/board/gateworks/gw_ventana/gw_ventana.c @@ -1209,7 +1209,7 @@ int ft_board_setup(void *blob, bd_t *bd) } /* Configure DIO */ - for (i = 0; i < gpio_cfg[board_type].num_gpios; i++) { + for (i = 0; i < gpio_cfg[board_type].dio_num; i++) { struct dio_cfg *cfg = &gpio_cfg[board_type].dio_cfg[i]; char arg[10]; -- cgit From e86b7adfa3cfe8d87ecb67bc0f02789c51293f51 Mon Sep 17 00:00:00 2001 From: Tim Harvey Date: Fri, 15 Jul 2016 07:14:24 -0700 Subject: imx: ventana: add extra DIO's for GW5520 The GW5520 has 10 DIO's instead of the typical 4 found on the Ventana product family. Signed-off-by: Tim Harvey --- board/gateworks/gw_ventana/common.c | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) (limited to 'board') diff --git a/board/gateworks/gw_ventana/common.c b/board/gateworks/gw_ventana/common.c index 59e3ff88b2..4065c5655a 100644 --- a/board/gateworks/gw_ventana/common.c +++ b/board/gateworks/gw_ventana/common.c @@ -487,6 +487,42 @@ struct dio_cfg gw552x_dio[] = { { 0, 0 }, 0 }, + { + {IOMUX_PADS(PAD_CSI0_PIXCLK__GPIO5_IO18) }, + IMX_GPIO_NR(5, 18), + { 0, 0 }, + 0 + }, + { + {IOMUX_PADS(PAD_CSI0_DATA_EN__GPIO5_IO20) }, + IMX_GPIO_NR(5, 20), + { 0, 0 }, + 0 + }, + { + {IOMUX_PADS(PAD_CSI0_VSYNC__GPIO5_IO21) }, + IMX_GPIO_NR(5, 21), + { 0, 0 }, + 0 + }, + { + {IOMUX_PADS(PAD_CSI0_DAT4__GPIO5_IO22) }, + IMX_GPIO_NR(5, 22), + { 0, 0 }, + 0 + }, + { + {IOMUX_PADS(PAD_CSI0_DAT5__GPIO5_IO23) }, + IMX_GPIO_NR(5, 23), + { 0, 0 }, + 0 + }, + { + {IOMUX_PADS(PAD_CSI0_DAT7__GPIO5_IO25) }, + IMX_GPIO_NR(5, 25), + { 0, 0 }, + 0 + }, }; struct dio_cfg gw553x_dio[] = { -- cgit From 5911c0924f403561d8f1f2f437fd9a6efc5ad82a Mon Sep 17 00:00:00 2001 From: Tim Harvey Date: Fri, 15 Jul 2016 07:14:25 -0700 Subject: imx: ventana: make hwconfig initialize based on board configuration The hwconfig env var allows user to control hardware specific configuration of board specific features but not all Ventana boards have the same features. We will use the magic default value of "_UNKNOWN_" to signify that the bootloader should create this based on detected board model. Signed-off-by: Tim Harvey --- board/gateworks/gw_ventana/gw_ventana.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) (limited to 'board') diff --git a/board/gateworks/gw_ventana/gw_ventana.c b/board/gateworks/gw_ventana/gw_ventana.c index 930cec8c5a..588ea85b9d 100644 --- a/board/gateworks/gw_ventana/gw_ventana.c +++ b/board/gateworks/gw_ventana/gw_ventana.c @@ -700,13 +700,14 @@ static const struct boot_mode board_boot_modes[] = { int misc_init_r(void) { struct ventana_board_info *info = &ventana_info; + char buf[256]; + int i; /* set env vars based on EEPROM data */ if (ventana_info.model[0]) { char str[16], fdt[36]; char *p; const char *cputype = ""; - int i; /* * FDT name will be prefixed with CPU type. Three versions @@ -769,6 +770,19 @@ int misc_init_r(void) setenv("mem_mb", str); } + /* Set a non-initialized hwconfig based on board configuration */ + if (!strcmp(getenv("hwconfig"), "_UNKNOWN_")) { + sprintf(buf, "hwconfig="); + if (gpio_cfg[board_type].rs232_en) + strcat(buf, "rs232;"); + for (i = 0; i < gpio_cfg[board_type].dio_num; i++) { + char buf1[32]; + sprintf(buf1, "dio%d:mode=gpio;", i); + if (strlen(buf) + strlen(buf1) < sizeof(buf)) + strcat(buf, buf1); + } + setenv("hwconfig", buf); + } /* setup baseboard specific GPIO based on board and env */ setup_board_gpio(board_type, info); -- cgit From 966fe02ee64106721c7301641e86e5784a5f47b2 Mon Sep 17 00:00:00 2001 From: Tim Harvey Date: Fri, 15 Jul 2016 07:16:28 -0700 Subject: imx: ventana: refactor board-specific dt fixups (no functional change) Re-factor the board-specific dt fixups so that they are easier to follow and extend in the future: - use defines for DT paths - use switch/case per board - order models numerically There is no functional change in the code Signed-off-by: Tim Harvey --- board/gateworks/gw_ventana/gw_ventana.c | 166 ++++++++++++++++++-------------- 1 file changed, 93 insertions(+), 73 deletions(-) (limited to 'board') diff --git a/board/gateworks/gw_ventana/gw_ventana.c b/board/gateworks/gw_ventana/gw_ventana.c index 588ea85b9d..bb792c2028 100644 --- a/board/gateworks/gw_ventana/gw_ventana.c +++ b/board/gateworks/gw_ventana/gw_ventana.c @@ -1083,6 +1083,9 @@ void ft_board_pci_fixup(void *blob, bd_t *bd) * - board (full model from EEPROM) * - peripherals removed from DTB if not loaded on board (per EEPROM config) */ +#define UART1_PATH "/soc/aips-bus@02100000/serial@021ec000" +#define WDOG1_PATH "/soc/aips-bus@02000000/wdog@020bc000" +#define GPIO3_PATH "/soc/aips-bus@02000000/gpio@020a4000" int ft_board_setup(void *blob, bd_t *bd) { struct ventana_board_info *info = &ventana_info; @@ -1136,90 +1139,107 @@ int ft_board_setup(void *blob, bd_t *bd) ft_sethdmiinfmt(blob, getenv("hdmiinfmt")); /* - * disable serial2 node for GW54xx for compatibility with older - * 3.10.x kernel that improperly had this node enabled in the DT + * Board model specific fixups */ - if (board_type == GW54xx) { - i = fdt_path_offset(blob, - "/soc/aips-bus@02100000/serial@021ec000"); - if (i) - fdt_del_node(blob, i); - } - - /* - * disable wdog1/wdog2 nodes for GW51xx below revC to work around - * errata causing wdog timer to be unreliable. - */ - if (board_type == GW51xx && rev >= 'A' && rev < 'C') { - i = fdt_path_offset(blob, - "/soc/aips-bus@02000000/wdog@020bc000"); - if (i) - fdt_status_disabled(blob, i); - } - - /* GW522x Uses GPIO3_IO23 instead of GPIO1_IO29 */ - else if (board_type == GW52xx && info->model[4] == '2') { - u32 handle = 0; - u32 *range = NULL; + switch (board_type) { + case GW51xx: + /* + * disable wdog node for GW51xx-A/B to work around + * errata causing wdog timer to be unreliable. + */ + if (rev >= 'A' && rev < 'C') { + i = fdt_path_offset(blob, WDOG1_PATH); + if (i) + fdt_status_disabled(blob, i); + } + break; - i = fdt_node_offset_by_compatible(blob, -1, "fsl,imx6q-pcie"); - if (i) - range = (u32 *)fdt_getprop(blob, i, "reset-gpio", - NULL); + case GW52xx: + /* GW522x Uses GPIO3_IO23 instead of GPIO1_IO29 */ + if (info->model[4] == '2') { + u32 handle = 0; + u32 *range = NULL; - if (range) { - i = fdt_path_offset(blob, - "/soc/aips-bus@02000000/gpio@020a4000"); + i = fdt_node_offset_by_compatible(blob, -1, + "fsl,imx6q-pcie"); if (i) - handle = fdt_get_phandle(blob, i); - if (handle) { - range[0] = cpu_to_fdt32(handle); - range[1] = cpu_to_fdt32(23); + range = (u32 *)fdt_getprop(blob, i, + "reset-gpio", NULL); + + if (range) { + i = fdt_path_offset(blob, GPIO3_PATH); + if (i) + handle = fdt_get_phandle(blob, i); + if (handle) { + range[0] = cpu_to_fdt32(handle); + range[1] = cpu_to_fdt32(23); + } } - } - /* these have broken usd_vsel */ - if (strstr((const char *)info->model, "SP318-B") || - strstr((const char *)info->model, "SP331-B")) - gpio_cfg[board_type].usd_vsel = 0; - } + /* these have broken usd_vsel */ + if (strstr((const char *)info->model, "SP318-B") || + strstr((const char *)info->model, "SP331-B")) + gpio_cfg[board_type].usd_vsel = 0; + } + break; - /* - * isolate CSI0_DATA_EN for GW551x below revB to work around - * errata causing non functional digital video in (it is not hooked up) - */ - else if (board_type == GW551x && rev == 'A') { - u32 *range = NULL; - int len; - const u32 *handle = NULL; + case GW53xx: + break; - i = fdt_node_offset_by_compatible(blob, -1, - "fsl,imx-tda1997x-video"); - if (i) - handle = fdt_getprop(blob, i, "pinctrl-0", NULL); - if (handle) - i = fdt_node_offset_by_phandle(blob, - fdt32_to_cpu(*handle)); + case GW54xx: + /* + * disable serial2 node for GW54xx for compatibility with older + * 3.10.x kernel that improperly had this node enabled in the DT + */ + i = fdt_path_offset(blob, UART1_PATH); if (i) - range = (u32 *)fdt_getprop(blob, i, "fsl,pins", &len); - if (range) { - len /= sizeof(u32); - for (i = 0; i < len; i += 6) { - u32 mux_reg = fdt32_to_cpu(range[i+0]); - u32 conf_reg = fdt32_to_cpu(range[i+1]); - /* mux PAD_CSI0_DATA_EN to GPIO */ - if (is_cpu_type(MXC_CPU_MX6Q) && - mux_reg == 0x260 && conf_reg == 0x630) - range[i+3] = cpu_to_fdt32(0x5); - else if (!is_cpu_type(MXC_CPU_MX6Q) && - mux_reg == 0x08c && conf_reg == 0x3a0) - range[i+3] = cpu_to_fdt32(0x5); + fdt_del_node(blob, i); + break; + + case GW551x: + /* + * isolate CSI0_DATA_EN for GW551x-A to work around errata + * causing non functional digital video in (it is not hooked up) + */ + if (rev == 'A') { + u32 *range = NULL; + int len; + const u32 *handle = NULL; + + i = fdt_node_offset_by_compatible(blob, -1, + "fsl,imx-tda1997x-video"); + if (i) + handle = fdt_getprop(blob, i, "pinctrl-0", + NULL); + if (handle) + i = fdt_node_offset_by_phandle(blob, + fdt32_to_cpu(*handle)); + if (i) + range = (u32 *)fdt_getprop(blob, i, "fsl,pins", + &len); + if (range) { + len /= sizeof(u32); + for (i = 0; i < len; i += 6) { + u32 mux_reg = fdt32_to_cpu(range[i+0]); + u32 conf_reg = fdt32_to_cpu(range[i+1]); + /* mux PAD_CSI0_DATA_EN to GPIO */ + if (is_cpu_type(MXC_CPU_MX6Q) && + mux_reg == 0x260 && + conf_reg == 0x630) + range[i+3] = cpu_to_fdt32(0x5); + else if (!is_cpu_type(MXC_CPU_MX6Q) && + mux_reg == 0x08c && + conf_reg == 0x3a0) + range[i+3] = cpu_to_fdt32(0x5); + } + fdt_setprop_inplace(blob, i, "fsl,pins", range, + len); } - fdt_setprop_inplace(blob, i, "fsl,pins", range, len); - } - /* set BT656 video format */ - ft_sethdmiinfmt(blob, "yuv422bt656"); + /* set BT656 video format */ + ft_sethdmiinfmt(blob, "yuv422bt656"); + } + break; } /* Configure DIO */ -- cgit From a5bfb4ff9ee5f97adf91af8fba148b3fae48acde Mon Sep 17 00:00:00 2001 From: Tim Harvey Date: Fri, 15 Jul 2016 07:16:29 -0700 Subject: imx: ventana: add dt fixup for watchdog external reset Added removal of the fsl,ext-reset-output property in the wdog node for board revisions that pre-date the addition of the external watchdog reset signal. This property is a recent addition to mainline linux kernel in order to specify that the IMX watchdog external reset should be used instead of the internal chip-level reset. Signed-off-by: Tim Harvey --- board/gateworks/gw_ventana/gw_ventana.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) (limited to 'board') diff --git a/board/gateworks/gw_ventana/gw_ventana.c b/board/gateworks/gw_ventana/gw_ventana.c index bb792c2028..5d871ceed9 100644 --- a/board/gateworks/gw_ventana/gw_ventana.c +++ b/board/gateworks/gw_ventana/gw_ventana.c @@ -1085,6 +1085,7 @@ void ft_board_pci_fixup(void *blob, bd_t *bd) */ #define UART1_PATH "/soc/aips-bus@02100000/serial@021ec000" #define WDOG1_PATH "/soc/aips-bus@02000000/wdog@020bc000" +#define WDOG2_PATH "/soc/aips-bus@02000000/wdog@020c0000" #define GPIO3_PATH "/soc/aips-bus@02000000/gpio@020a4000" int ft_board_setup(void *blob, bd_t *bd) { @@ -1152,6 +1153,11 @@ int ft_board_setup(void *blob, bd_t *bd) if (i) fdt_status_disabled(blob, i); } + + /* GW51xx-E adds WDOG1_B external reset */ + if (rev < 'E') + ft_delprop_path(blob, WDOG1_PATH, + "fsl,ext-reset-output"); break; case GW52xx: @@ -1180,10 +1186,24 @@ int ft_board_setup(void *blob, bd_t *bd) if (strstr((const char *)info->model, "SP318-B") || strstr((const char *)info->model, "SP331-B")) gpio_cfg[board_type].usd_vsel = 0; + + /* GW520x-E adds WDOG1_B external reset */ + if (info->model[4] == '0' && rev < 'E') + ft_delprop_path(blob, WDOG1_PATH, + "fsl,ext-reset-output"); + + /* GW522x-B adds WDOG1_B external reset */ + if (info->model[4] == '2' && rev < 'B') + ft_delprop_path(blob, WDOG1_PATH, + "fsl,ext-reset-output"); } break; case GW53xx: + /* GW53xx-E adds WDOG1_B external reset */ + if (rev < 'E') + ft_delprop_path(blob, WDOG1_PATH, + "fsl,ext-reset-output"); break; case GW54xx: @@ -1194,6 +1214,11 @@ int ft_board_setup(void *blob, bd_t *bd) i = fdt_path_offset(blob, UART1_PATH); if (i) fdt_del_node(blob, i); + + /* GW54xx-E adds WDOG2_B external reset */ + if (rev < 'E') + ft_delprop_path(blob, WDOG2_PATH, + "fsl,ext-reset-output"); break; case GW551x: @@ -1239,6 +1264,11 @@ int ft_board_setup(void *blob, bd_t *bd) /* set BT656 video format */ ft_sethdmiinfmt(blob, "yuv422bt656"); } + + /* GW551x-C adds WDOG1_B external reset */ + if (rev < 'C') + ft_delprop_path(blob, WDOG1_PATH, + "fsl,ext-reset-output"); break; } -- cgit From 98b040c9889bc23a7a0007853d52ebb07e28de76 Mon Sep 17 00:00:00 2001 From: Breno Lima Date: Fri, 22 Jul 2016 09:11:02 -0300 Subject: wandboard: Replace is_cpu_type() for macro It's not necessary to use the is_cpu_type function, there is a macro in sys_proto.h already implemented. Signed-off-by: Breno Lima Reviewed-by: Fabio Estevam --- board/wandboard/wandboard.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'board') diff --git a/board/wandboard/wandboard.c b/board/wandboard/wandboard.c index 10cad3fd80..1de1e0b257 100644 --- a/board/wandboard/wandboard.c +++ b/board/wandboard/wandboard.c @@ -391,7 +391,7 @@ int board_late_init(void) #endif #ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG - if (is_cpu_type(MXC_CPU_MX6Q) || is_cpu_type(MXC_CPU_MX6D)) + if (is_mx6dq()) setenv("board_rev", "MX6Q"); else setenv("board_rev", "MX6DL"); @@ -410,7 +410,7 @@ int board_init(void) gd->bd->bi_boot_params = PHYS_SDRAM + 0x100; setup_i2c(1, CONFIG_SYS_I2C_SPEED, 0x7f, &mx6dl_i2c2_pad_info); - if (is_cpu_type(MXC_CPU_MX6Q) || is_cpu_type(MXC_CPU_MX6D)) + if (is_mx6dq()) setup_i2c(1, CONFIG_SYS_I2C_SPEED, 0x7f, &mx6q_i2c2_pad_info); else setup_i2c(1, CONFIG_SYS_I2C_SPEED, 0x7f, &mx6dl_i2c2_pad_info); -- cgit From 4a2f9014e82e73caeb09b39e4bf02f1460279882 Mon Sep 17 00:00:00 2001 From: Breno Lima Date: Fri, 22 Jul 2016 09:11:30 -0300 Subject: mx6cuboxi: Replace is_mx6q() for macro It's not necessary to implement the is_mx6q function, there is a macro in sys_proto.h already implemented. Signed-off-by: Breno Lima Reviewed-by: Fabio Estevam --- board/solidrun/mx6cuboxi/mx6cuboxi.c | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) (limited to 'board') diff --git a/board/solidrun/mx6cuboxi/mx6cuboxi.c b/board/solidrun/mx6cuboxi/mx6cuboxi.c index bcc9729129..cafa348150 100644 --- a/board/solidrun/mx6cuboxi/mx6cuboxi.c +++ b/board/solidrun/mx6cuboxi/mx6cuboxi.c @@ -367,14 +367,6 @@ int checkboard(void) return 0; } -static bool is_mx6q(void) -{ - if (is_cpu_type(MXC_CPU_MX6Q) || is_cpu_type(MXC_CPU_MX6D)) - return true; - else - return false; -} - int board_late_init(void) { #ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG @@ -383,7 +375,7 @@ int board_late_init(void) else setenv("board_name", "CUBOXI"); - if (is_mx6q()) + if (is_mx6dq()) setenv("board_rev", "MX6Q"); else setenv("board_rev", "MX6DL"); @@ -615,7 +607,7 @@ static void spl_dram_init(int width) .ddr_type = DDR_TYPE_DDR3, }; - if (is_cpu_type(MXC_CPU_MX6D) || is_cpu_type(MXC_CPU_MX6Q)) + if (is_mx6dq()) mx6dq_dram_iocfg(width, &mx6q_ddr_ioregs, &mx6q_grp_ioregs); else mx6sdl_dram_iocfg(width, &mx6dl_ddr_ioregs, &mx6sdl_grp_ioregs); -- cgit From 68c276019a6ede6dbb099af7e3e2756579e3b23e Mon Sep 17 00:00:00 2001 From: Breno Lima Date: Fri, 22 Jul 2016 09:12:12 -0300 Subject: cgtqmx6eval: Replace is_mx6q() for macro It's not necessary to implement the is_mx6q function, there is a macro in sys_proto.h already implemented. Signed-off-by: Breno Lima Reviewed-by: Fabio Estevam --- board/congatec/cgtqmx6eval/cgtqmx6eval.c | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) (limited to 'board') diff --git a/board/congatec/cgtqmx6eval/cgtqmx6eval.c b/board/congatec/cgtqmx6eval/cgtqmx6eval.c index 225de7c543..3fbd3d2aaa 100644 --- a/board/congatec/cgtqmx6eval/cgtqmx6eval.c +++ b/board/congatec/cgtqmx6eval/cgtqmx6eval.c @@ -678,14 +678,6 @@ int overwrite_console(void) return 1; } -static bool is_mx6q(void) -{ - if (is_cpu_type(MXC_CPU_MX6Q) || is_cpu_type(MXC_CPU_MX6D)) - return true; - else - return false; -} - int board_early_init_f(void) { setup_iomux_uart(); @@ -703,7 +695,7 @@ int board_init(void) gd->bd->bi_boot_params = PHYS_SDRAM + 0x100; - if (is_mx6q()) + if (is_mx6dq()) setup_i2c(1, CONFIG_SYS_I2C_SPEED, 0x7f, &mx6q_i2c_pad_info1); else setup_i2c(1, CONFIG_SYS_I2C_SPEED, 0x7f, &mx6dl_i2c_pad_info1); @@ -760,7 +752,7 @@ int misc_init_r(void) int board_late_init(void) { #ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG - if (is_mx6q()) + if (is_mx6dq()) setenv("board_rev", "MX6Q"); else setenv("board_rev", "MX6DL"); @@ -1053,7 +1045,7 @@ static void spl_dram_init(int width) return; } - if (is_mx6q()) { + if (is_mx6dq()) { mx6dq_dram_iocfg(width, &mx6q_ddr_ioregs, &mx6q_grp_ioregs); mx6_dram_cfg(&sysinfo, &mx6q_mmcd_calib, &mem_ddr_2g); } else if (is_cpu_type(MXC_CPU_MX6SOLO)) { -- cgit From ae440ab02d31179a5a4b23e7411fe1baf052e816 Mon Sep 17 00:00:00 2001 From: Stefan Agner Date: Wed, 20 Jul 2016 21:27:49 -0700 Subject: colibri_imx7: add Colibri iMX7S/iMX7D module support This commit adds support for the Toradex Computer on Modules Colibri iMX7S/iMX7D. The two modules/SoC's are very similar hence can be easily supported by one board. The board code detects RAM size at runtime which is one of the differences between the two boards. The board also uses the UART's in DTE mode, hence making use of the new DTE support via serial DM. Signed-off-by: Stefan Agner --- board/toradex/colibri_imx7/Kconfig | 20 ++ board/toradex/colibri_imx7/MAINTAINERS | 6 + board/toradex/colibri_imx7/Makefile | 6 + board/toradex/colibri_imx7/colibri_imx7.c | 420 ++++++++++++++++++++++++++++++ board/toradex/colibri_imx7/imximage.cfg | 150 +++++++++++ 5 files changed, 602 insertions(+) create mode 100644 board/toradex/colibri_imx7/Kconfig create mode 100644 board/toradex/colibri_imx7/MAINTAINERS create mode 100644 board/toradex/colibri_imx7/Makefile create mode 100644 board/toradex/colibri_imx7/colibri_imx7.c create mode 100644 board/toradex/colibri_imx7/imximage.cfg (limited to 'board') diff --git a/board/toradex/colibri_imx7/Kconfig b/board/toradex/colibri_imx7/Kconfig new file mode 100644 index 0000000000..7bba26b90d --- /dev/null +++ b/board/toradex/colibri_imx7/Kconfig @@ -0,0 +1,20 @@ +if TARGET_COLIBRI_IMX7 + +config SYS_BOARD + default "colibri_imx7" + +config SYS_VENDOR + default "toradex" + +config SYS_CONFIG_NAME + default "colibri_imx7" + +config COLIBRI_IMX7_EXT_PHYCLK + bool "External oscillator for Ethernet PHY clock provided" + help + Select this if your module provides a external Ethernet PHY + clock source. + default y + + +endif diff --git a/board/toradex/colibri_imx7/MAINTAINERS b/board/toradex/colibri_imx7/MAINTAINERS new file mode 100644 index 0000000000..5ffb2417aa --- /dev/null +++ b/board/toradex/colibri_imx7/MAINTAINERS @@ -0,0 +1,6 @@ +Colibri iMX7 +M: Stefan Agner +S: Maintained +F: board/toradex/colibri_imx7/ +F: include/configs/colibri_imx7.h +F: configs/colibri_imx7_defconfig diff --git a/board/toradex/colibri_imx7/Makefile b/board/toradex/colibri_imx7/Makefile new file mode 100644 index 0000000000..ea597dec28 --- /dev/null +++ b/board/toradex/colibri_imx7/Makefile @@ -0,0 +1,6 @@ +# Copyright (C) 2016 Toradex AG +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-y := colibri_imx7.o diff --git a/board/toradex/colibri_imx7/colibri_imx7.c b/board/toradex/colibri_imx7/colibri_imx7.c new file mode 100644 index 0000000000..8eedd65bf0 --- /dev/null +++ b/board/toradex/colibri_imx7/colibri_imx7.c @@ -0,0 +1,420 @@ +/* + * Copyright (C) 2016 Toradex AG + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +#define UART_PAD_CTRL (PAD_CTL_DSE_3P3V_49OHM | \ + PAD_CTL_PUS_PU100KOHM | PAD_CTL_HYS) + +#define USDHC_PAD_CTRL (PAD_CTL_DSE_3P3V_32OHM | PAD_CTL_SRE_SLOW | \ + PAD_CTL_HYS | PAD_CTL_PUE | PAD_CTL_PUS_PU47KOHM) + +#define ENET_PAD_CTRL (PAD_CTL_PUS_PU100KOHM | PAD_CTL_DSE_3P3V_49OHM) +#define ENET_PAD_CTRL_MII (PAD_CTL_DSE_3P3V_32OHM) + +#define ENET_RX_PAD_CTRL (PAD_CTL_PUS_PU100KOHM | PAD_CTL_DSE_3P3V_49OHM) + +#define I2C_PAD_CTRL (PAD_CTL_DSE_3P3V_32OHM | PAD_CTL_SRE_SLOW | \ + PAD_CTL_HYS | PAD_CTL_PUE | PAD_CTL_PUS_PU100KOHM) + +#define LCD_PAD_CTRL (PAD_CTL_HYS | PAD_CTL_PUS_PU100KOHM | \ + PAD_CTL_DSE_3P3V_49OHM) + +#define NAND_PAD_CTRL (PAD_CTL_DSE_3P3V_49OHM | PAD_CTL_SRE_SLOW | PAD_CTL_HYS) + +#define NAND_PAD_READY0_CTRL (PAD_CTL_DSE_3P3V_49OHM | PAD_CTL_PUS_PU5KOHM) + +#ifdef CONFIG_SYS_I2C_MXC +#define PC MUX_PAD_CTRL(I2C_PAD_CTRL) +/* I2C1 for PMIC */ +static struct i2c_pads_info i2c_pad_info1 = { + .scl = { + .i2c_mode = MX7D_PAD_GPIO1_IO04__I2C1_SCL | PC, + .gpio_mode = MX7D_PAD_GPIO1_IO04__GPIO1_IO4 | PC, + .gp = IMX_GPIO_NR(1, 4), + }, + .sda = { + .i2c_mode = MX7D_PAD_GPIO1_IO05__I2C1_SDA | PC, + .gpio_mode = MX7D_PAD_GPIO1_IO05__GPIO1_IO5 | PC, + .gp = IMX_GPIO_NR(1, 5), + }, +}; +/* I2C4 for Colibri I2C */ +static struct i2c_pads_info i2c_pad_info4 = { + .scl = { + .i2c_mode = MX7D_PAD_ENET1_RGMII_TD2__I2C4_SCL | PC, + .gpio_mode = MX7D_PAD_ENET1_RGMII_TD2__GPIO7_IO8 | PC, + .gp = IMX_GPIO_NR(7, 8), + }, + .sda = { + .i2c_mode = MX7D_PAD_ENET1_RGMII_TD3__I2C4_SDA | PC, + .gpio_mode = MX7D_PAD_ENET1_RGMII_TD3__GPIO7_IO9 | PC, + .gp = IMX_GPIO_NR(7, 9), + }, +}; +#endif + +int dram_init(void) +{ + gd->ram_size = get_ram_size((void *)PHYS_SDRAM, PHYS_SDRAM_SIZE); + + return 0; +} + +static iomux_v3_cfg_t const uart1_pads[] = { + MX7D_PAD_UART1_RX_DATA__UART1_DTE_TX | MUX_PAD_CTRL(UART_PAD_CTRL), + MX7D_PAD_UART1_TX_DATA__UART1_DTE_RX | MUX_PAD_CTRL(UART_PAD_CTRL), + MX7D_PAD_SAI2_TX_BCLK__UART1_DTE_CTS | MUX_PAD_CTRL(UART_PAD_CTRL), + MX7D_PAD_SAI2_TX_SYNC__UART1_DTE_RTS | MUX_PAD_CTRL(UART_PAD_CTRL), +}; + +static iomux_v3_cfg_t const usdhc1_pads[] = { + MX7D_PAD_SD1_CLK__SD1_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX7D_PAD_SD1_CMD__SD1_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX7D_PAD_SD1_DATA0__SD1_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX7D_PAD_SD1_DATA1__SD1_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX7D_PAD_SD1_DATA2__SD1_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX7D_PAD_SD1_DATA3__SD1_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + + MX7D_PAD_GPIO1_IO00__GPIO1_IO0 | MUX_PAD_CTRL(NO_PAD_CTRL), +}; + +#ifdef CONFIG_NAND_MXS +static iomux_v3_cfg_t const gpmi_pads[] = { + MX7D_PAD_SD3_DATA0__NAND_DATA00 | MUX_PAD_CTRL(NAND_PAD_CTRL), + MX7D_PAD_SD3_DATA1__NAND_DATA01 | MUX_PAD_CTRL(NAND_PAD_CTRL), + MX7D_PAD_SD3_DATA2__NAND_DATA02 | MUX_PAD_CTRL(NAND_PAD_CTRL), + MX7D_PAD_SD3_DATA3__NAND_DATA03 | MUX_PAD_CTRL(NAND_PAD_CTRL), + MX7D_PAD_SD3_DATA4__NAND_DATA04 | MUX_PAD_CTRL(NAND_PAD_CTRL), + MX7D_PAD_SD3_DATA5__NAND_DATA05 | MUX_PAD_CTRL(NAND_PAD_CTRL), + MX7D_PAD_SD3_DATA6__NAND_DATA06 | MUX_PAD_CTRL(NAND_PAD_CTRL), + MX7D_PAD_SD3_DATA7__NAND_DATA07 | MUX_PAD_CTRL(NAND_PAD_CTRL), + MX7D_PAD_SD3_CLK__NAND_CLE | MUX_PAD_CTRL(NAND_PAD_CTRL), + MX7D_PAD_SD3_CMD__NAND_ALE | MUX_PAD_CTRL(NAND_PAD_CTRL), + MX7D_PAD_SD3_STROBE__NAND_RE_B | MUX_PAD_CTRL(NAND_PAD_CTRL), + MX7D_PAD_SD3_RESET_B__NAND_WE_B | MUX_PAD_CTRL(NAND_PAD_CTRL), + MX7D_PAD_SAI1_RX_DATA__NAND_CE1_B | MUX_PAD_CTRL(NAND_PAD_CTRL), + MX7D_PAD_SAI1_TX_BCLK__NAND_CE0_B | MUX_PAD_CTRL(NAND_PAD_CTRL), + MX7D_PAD_SAI1_TX_DATA__NAND_READY_B | MUX_PAD_CTRL(NAND_PAD_READY0_CTRL), +}; + +static void setup_gpmi_nand(void) +{ + imx_iomux_v3_setup_multiple_pads(gpmi_pads, ARRAY_SIZE(gpmi_pads)); + + /* NAND_USDHC_BUS_CLK is set in rom */ + set_clk_nand(); +} +#endif + +static iomux_v3_cfg_t const usdhc3_emmc_pads[] = { + MX7D_PAD_SD3_CLK__SD3_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX7D_PAD_SD3_CMD__SD3_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX7D_PAD_SD3_DATA0__SD3_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX7D_PAD_SD3_DATA1__SD3_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX7D_PAD_SD3_DATA2__SD3_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX7D_PAD_SD3_DATA3__SD3_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX7D_PAD_SD3_DATA4__SD3_DATA4 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX7D_PAD_SD3_DATA5__SD3_DATA5 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX7D_PAD_SD3_DATA6__SD3_DATA6 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX7D_PAD_SD3_DATA7__SD3_DATA7 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX7D_PAD_SD3_STROBE__SD3_STROBE | MUX_PAD_CTRL(USDHC_PAD_CTRL), + + MX7D_PAD_SD3_RESET_B__GPIO6_IO11 | MUX_PAD_CTRL(USDHC_PAD_CTRL), +}; + +#ifdef CONFIG_VIDEO_MXS +static iomux_v3_cfg_t const lcd_pads[] = { + MX7D_PAD_LCD_CLK__LCD_CLK | MUX_PAD_CTRL(LCD_PAD_CTRL), + MX7D_PAD_LCD_ENABLE__LCD_ENABLE | MUX_PAD_CTRL(LCD_PAD_CTRL), + MX7D_PAD_LCD_HSYNC__LCD_HSYNC | MUX_PAD_CTRL(LCD_PAD_CTRL), + MX7D_PAD_LCD_VSYNC__LCD_VSYNC | MUX_PAD_CTRL(LCD_PAD_CTRL), + MX7D_PAD_LCD_DATA00__LCD_DATA0 | MUX_PAD_CTRL(LCD_PAD_CTRL), + MX7D_PAD_LCD_DATA01__LCD_DATA1 | MUX_PAD_CTRL(LCD_PAD_CTRL), + MX7D_PAD_LCD_DATA02__LCD_DATA2 | MUX_PAD_CTRL(LCD_PAD_CTRL), + MX7D_PAD_LCD_DATA03__LCD_DATA3 | MUX_PAD_CTRL(LCD_PAD_CTRL), + MX7D_PAD_LCD_DATA04__LCD_DATA4 | MUX_PAD_CTRL(LCD_PAD_CTRL), + MX7D_PAD_LCD_DATA05__LCD_DATA5 | MUX_PAD_CTRL(LCD_PAD_CTRL), + MX7D_PAD_LCD_DATA06__LCD_DATA6 | MUX_PAD_CTRL(LCD_PAD_CTRL), + MX7D_PAD_LCD_DATA07__LCD_DATA7 | MUX_PAD_CTRL(LCD_PAD_CTRL), + MX7D_PAD_LCD_DATA08__LCD_DATA8 | MUX_PAD_CTRL(LCD_PAD_CTRL), + MX7D_PAD_LCD_DATA09__LCD_DATA9 | MUX_PAD_CTRL(LCD_PAD_CTRL), + MX7D_PAD_LCD_DATA10__LCD_DATA10 | MUX_PAD_CTRL(LCD_PAD_CTRL), + MX7D_PAD_LCD_DATA11__LCD_DATA11 | MUX_PAD_CTRL(LCD_PAD_CTRL), + MX7D_PAD_LCD_DATA12__LCD_DATA12 | MUX_PAD_CTRL(LCD_PAD_CTRL), + MX7D_PAD_LCD_DATA13__LCD_DATA13 | MUX_PAD_CTRL(LCD_PAD_CTRL), + MX7D_PAD_LCD_DATA14__LCD_DATA14 | MUX_PAD_CTRL(LCD_PAD_CTRL), + MX7D_PAD_LCD_DATA15__LCD_DATA15 | MUX_PAD_CTRL(LCD_PAD_CTRL), + MX7D_PAD_LCD_DATA16__LCD_DATA16 | MUX_PAD_CTRL(LCD_PAD_CTRL), + MX7D_PAD_LCD_DATA17__LCD_DATA17 | MUX_PAD_CTRL(LCD_PAD_CTRL), +}; + +static iomux_v3_cfg_t const backlight_pads[] = { + /* Backlight On */ + MX7D_PAD_SD1_WP__GPIO5_IO1 | MUX_PAD_CTRL(NO_PAD_CTRL), + /* Backlight PWM (multiplexed pin) */ + MX7D_PAD_GPIO1_IO08__GPIO1_IO8 | MUX_PAD_CTRL(NO_PAD_CTRL), + MX7D_PAD_ECSPI2_MOSI__GPIO4_IO21 | MUX_PAD_CTRL(NO_PAD_CTRL), +}; + +#define GPIO_BL_ON IMX_GPIO_NR(5, 1) +#define GPIO_PWM_A IMX_GPIO_NR(1, 8) + +static int setup_lcd(void) +{ + imx_iomux_v3_setup_multiple_pads(lcd_pads, ARRAY_SIZE(lcd_pads)); + + imx_iomux_v3_setup_multiple_pads(backlight_pads, ARRAY_SIZE(backlight_pads)); + + /* Set BL_ON */ + gpio_request(GPIO_BL_ON, "BL_ON"); + gpio_direction_output(GPIO_BL_ON, 1); + + /* Set PWM to full brightness (assuming inversed polarity) */ + gpio_request(GPIO_PWM_A, "PWM"); + gpio_direction_output(GPIO_PWM_A, 0); + + return 0; +} +#endif + +#ifdef CONFIG_FEC_MXC +static iomux_v3_cfg_t const fec1_pads[] = { +#ifndef CONFIG_COLIBRI_IMX7_EXT_PHYCLK + MX7D_PAD_GPIO1_IO12__CCM_ENET_REF_CLK1 | MUX_PAD_CTRL(ENET_PAD_CTRL) | MUX_MODE_SION, +#else + MX7D_PAD_GPIO1_IO12__CCM_ENET_REF_CLK1 | MUX_PAD_CTRL(ENET_PAD_CTRL), +#endif + MX7D_PAD_SD2_CD_B__ENET1_MDIO | MUX_PAD_CTRL(ENET_PAD_CTRL_MII), + MX7D_PAD_SD2_WP__ENET1_MDC | MUX_PAD_CTRL(ENET_PAD_CTRL_MII), + MX7D_PAD_ENET1_RGMII_RD0__ENET1_RGMII_RD0 | MUX_PAD_CTRL(ENET_RX_PAD_CTRL), + MX7D_PAD_ENET1_RGMII_RD1__ENET1_RGMII_RD1 | MUX_PAD_CTRL(ENET_RX_PAD_CTRL), + MX7D_PAD_ENET1_RGMII_RXC__ENET1_RX_ER | MUX_PAD_CTRL(ENET_RX_PAD_CTRL), + MX7D_PAD_ENET1_RGMII_RX_CTL__ENET1_RGMII_RX_CTL | MUX_PAD_CTRL(ENET_RX_PAD_CTRL), + MX7D_PAD_ENET1_RGMII_TD0__ENET1_RGMII_TD0 | MUX_PAD_CTRL(ENET_PAD_CTRL), + MX7D_PAD_ENET1_RGMII_TD1__ENET1_RGMII_TD1 | MUX_PAD_CTRL(ENET_PAD_CTRL), + MX7D_PAD_ENET1_RGMII_TX_CTL__ENET1_RGMII_TX_CTL | MUX_PAD_CTRL(ENET_PAD_CTRL), +}; + +static void setup_iomux_fec(void) +{ + imx_iomux_v3_setup_multiple_pads(fec1_pads, ARRAY_SIZE(fec1_pads)); +} +#endif + +static void setup_iomux_uart(void) +{ + imx_iomux_v3_setup_multiple_pads(uart1_pads, ARRAY_SIZE(uart1_pads)); +} + +#ifdef CONFIG_FSL_ESDHC + +#define USDHC1_CD_GPIO IMX_GPIO_NR(1, 0) + +static struct fsl_esdhc_cfg usdhc_cfg[] = { + {USDHC1_BASE_ADDR, 0, 4}, +}; + +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 USDHC1_BASE_ADDR: + ret = !gpio_get_value(USDHC1_CD_GPIO); + break; + } + + return ret; +} + +int board_mmc_init(bd_t *bis) +{ + int i, ret; + /* USDHC1 is mmc0 */ + for (i = 0; i < CONFIG_SYS_FSL_USDHC_NUM; i++) { + switch (i) { + case 0: + imx_iomux_v3_setup_multiple_pads( + usdhc1_pads, ARRAY_SIZE(usdhc1_pads)); + gpio_request(USDHC1_CD_GPIO, "usdhc1_cd"); + gpio_direction_input(USDHC1_CD_GPIO); + usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC_CLK); + 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; +} +#endif + +#ifdef CONFIG_FEC_MXC +int board_eth_init(bd_t *bis) +{ + int ret; + + setup_iomux_fec(); + + ret = fecmxc_initialize_multi(bis, 0, + CONFIG_FEC_MXC_PHYADDR, IMX_FEC_BASE); + if (ret) + printf("FEC1 MXC: %s:failed\n", __func__); + + return ret; +} + +static int setup_fec(void) +{ + struct iomuxc_gpr_base_regs *const iomuxc_gpr_regs + = (struct iomuxc_gpr_base_regs *)IOMUXC_GPR_BASE_ADDR; + +#ifndef CONFIG_COLIBRI_IMX7_EXT_PHYCLK + /* + * Use 50M anatop REF_CLK1 for ENET1, clear gpr1[13], set gpr1[17] + * and output it on the pin + */ + clrsetbits_le32(&iomuxc_gpr_regs->gpr[1], + IOMUXC_GPR_GPR1_GPR_ENET1_TX_CLK_SEL_MASK, + IOMUXC_GPR_GPR1_GPR_ENET1_CLK_DIR_MASK); +#else + /* Use 50M external CLK for ENET1, set gpr1[13], clear gpr1[17] */ + clrsetbits_le32(&iomuxc_gpr_regs->gpr[1], + IOMUXC_GPR_GPR1_GPR_ENET1_CLK_DIR_MASK, + IOMUXC_GPR_GPR1_GPR_ENET1_TX_CLK_SEL_MASK); +#endif + + return set_clk_enet(ENET_50MHz); +} + +int board_phy_config(struct phy_device *phydev) +{ + if (phydev->drv->config) + phydev->drv->config(phydev); + return 0; +} +#endif + +int board_early_init_f(void) +{ + setup_iomux_uart(); + +#ifdef CONFIG_SYS_I2C_MXC + setup_i2c(0, CONFIG_SYS_I2C_SPEED, 0x7f, &i2c_pad_info1); + setup_i2c(3, CONFIG_SYS_I2C_SPEED, 0x7f, &i2c_pad_info4); +#endif + + return 0; +} + +int board_init(void) +{ + /* address of boot parameters */ + gd->bd->bi_boot_params = PHYS_SDRAM + 0x100; + +#ifdef CONFIG_FEC_MXC + setup_fec(); +#endif + +#ifdef CONFIG_NAND_MXS + setup_gpmi_nand(); +#endif + +#ifdef CONFIG_VIDEO_MXS + setup_lcd(); +#endif + + return 0; +} + +#ifdef CONFIG_CMD_BMODE +static const struct boot_mode board_boot_modes[] = { + /* 4 bit bus width */ + {"nand", MAKE_CFGVAL(0x40, 0x34, 0x00, 0x00)}, + {"sd1", MAKE_CFGVAL(0x10, 0x10, 0x00, 0x00)}, + {NULL, 0}, +}; +#endif + +int board_late_init(void) +{ +#ifdef CONFIG_CMD_BMODE + add_board_boot_modes(board_boot_modes); +#endif + + return 0; +} + +int checkboard(void) +{ + printf("Model: Toradex Colibri iMX7%c\n", + is_cpu_type(MXC_CPU_MX7D) ? 'D' : 'S'); + + return 0; +} + +#ifdef CONFIG_USB_EHCI_MX7 +static iomux_v3_cfg_t const usb_otg2_pads[] = { + MX7D_PAD_UART3_CTS_B__USB_OTG2_PWR | MUX_PAD_CTRL(NO_PAD_CTRL), +}; + +int board_ehci_hcd_init(int port) +{ + switch (port) { + case 0: + break; + case 1: + if (is_cpu_type(MXC_CPU_MX7S)) + return -ENODEV; + + imx_iomux_v3_setup_multiple_pads(usb_otg2_pads, + ARRAY_SIZE(usb_otg2_pads)); + break; + default: + return -EINVAL; + } + return 0; +} +#endif + +static struct mxc_serial_platdata mxc_serial_plat = { + .reg = (struct mxc_uart *)UART1_IPS_BASE_ADDR, + .use_dte = true, +}; + +U_BOOT_DEVICE(mxc_serial) = { + .name = "serial_mxc", + .platdata = &mxc_serial_plat, +}; diff --git a/board/toradex/colibri_imx7/imximage.cfg b/board/toradex/colibri_imx7/imximage.cfg new file mode 100644 index 0000000000..d891e82ae4 --- /dev/null +++ b/board/toradex/colibri_imx7/imximage.cfg @@ -0,0 +1,150 @@ +/* + * Copyright (C) 2015 Freescale Semiconductor, Inc. + * 2015 Toradex AG + * + * SPDX-License-Identifier: GPL-2.0+ + * + * Refer docs/README.imxmage for more details about how-to configure + * and create imximage boot image + * + * The syntax is taken as close as possible with the kwbimage + */ + +#define __ASSEMBLY__ +#include + +/* image version */ + +IMAGE_VERSION 2 + +/* + * Boot Device : sd + */ + +BOOT_FROM sd + +/* + * Secure boot support + */ +#ifdef CONFIG_SECURE_BOOT +CSF CONFIG_CSF_SIZE +#endif + +/* + * Device Configuration Data (DCD) + * + * Each entry must have the format: + * Addr-type Address Value + * + * where: + * Addr-type register length (1,2 or 4 bytes) + * Address absolute address of the register + * value value to be stored in the register + */ + +/* IOMUXC_GPR_GPR1 */ +DATA 4 0x30340004 0x4F400005 + +/* DDR3L */ +/* assuming MEMC_FREQ_RATIO = 2 */ +/* SRC_DDRC_RCR */ +DATA 4 0x30391000 0x00000002 +/* DDRC_MSTR */ +DATA 4 0x307a0000 0x01040001 +/* DDRC_DFIUPD0 */ +DATA 4 0x307a01a0 0x80400003 +/* DDRC_DFIUPD1 */ +DATA 4 0x307a01a4 0x00100020 +/* DDRC_DFIUPD2 */ +DATA 4 0x307a01a8 0x80100004 +/* DDRC_RFSHTMG */ +DATA 4 0x307a0064 0x00400045 +/* DDRC_MP_PCTRL_0 */ +DATA 4 0x307a0490 0x00000001 +/* DDRC_INIT0 */ +DATA 4 0x307a00d0 0x00020083 +/* DDRC_INIT1 */ +DATA 4 0x307a00d4 0x00690000 +/* DDRC_INIT3 MR0/MR1 */ +DATA 4 0x307a00dc 0x09300004 +/* DDRC_INIT4 MR2/MR3 */ +DATA 4 0x307a00e0 0x04480000 +/* DDRC_INIT5 */ +DATA 4 0x307a00e4 0x00100004 +/* DDRC_RANKCTL */ +DATA 4 0x307a00f4 0x0000033f +/* DDRC_DRAMTMG0 */ +DATA 4 0x307a0100 0x090b090a +/* DDRC_DRAMTMG1 */ +DATA 4 0x307a0104 0x000d020d +/* DDRC_DRAMTMG2 */ +DATA 4 0x307a0108 0x03040307 +/* DDRC_DRAMTMG3 */ +DATA 4 0x307a010c 0x00002006 +/* DDRC_DRAMTMG4 */ +DATA 4 0x307a0110 0x04020205 +/* DDRC_DRAMTMG5 */ +DATA 4 0x307a0114 0x03030202 +/* DDRC_DRAMTMG8 */ +DATA 4 0x307a0120 0x00000803 +/* DDRC_ZQCTL0 */ +DATA 4 0x307a0180 0x00800020 +/* DDRC_ZQCTL1 */ +DATA 4 0x307a0184 0x02001000 +/* DDRC_DFITMG0 */ +DATA 4 0x307a0190 0x02098204 +/* DDRC_DFITMG1 */ +DATA 4 0x307a0194 0x00030303 +/* DDRC_ADDRMAP0 */ +DATA 4 0x307a0200 0x0000001f +/* DDRC_ADDRMAP1 */ +DATA 4 0x307a0204 0x00080808 +/* DDRC_ADDRMAP5 */ +DATA 4 0x307a0214 0x07070707 +/* DDRC_ADDRMAP6 */ +DATA 4 0x307a0218 0x07070707 +/* DDRC_ODTCFG */ +DATA 4 0x307a0240 0x06000601 +/* DDRC_ODTMAP */ +DATA 4 0x307a0244 0x00000011 +/* SRC_DDRC_RCR */ +DATA 4 0x30391000 0x00000000 +/* DDR_PHY_PHY_CON0 */ +DATA 4 0x30790000 0x17420f40 +/* DDR_PHY_PHY_CON1 */ +DATA 4 0x30790004 0x10210100 +/* DDR_PHY_PHY_CON4 */ +DATA 4 0x30790010 0x00060807 +/* DDR_PHY_MDLL_CON0 */ +DATA 4 0x307900b0 0x1010007e +/* DDR_PHY_DRVDS_CON0 */ +DATA 4 0x3079009c 0x00000d6e +/* DDR_PHY_OFFSET_RD_CON0 */ +DATA 4 0x30790020 0x08080808 +/* DDR_PHY_OFFSET_WR_CON0 */ +DATA 4 0x30790030 0x08080808 +/* DDR_PHY_CMD_SDLL_CON0 */ +DATA 4 0x30790050 0x01000010 +DATA 4 0x30790050 0x00000010 + +/* DDR_PHY_ZQ_CON0 */ +DATA 4 0x307900c0 0x0e407304 +DATA 4 0x307900c0 0x0e447304 +DATA 4 0x307900c0 0x0e447306 +/* DDR_PHY_ZQ_CON1 */ +CHECK_BITS_SET 4 0x307900c4 0x1 +/* DDR_PHY_ZQ_CON0 */ +DATA 4 0x307900c0 0x0e447304 +DATA 4 0x307900c0 0x0e407304 + +/* CCM_CCGRn */ +DATA 4 0x30384130 0x00000000 +/* IOMUXC_GPR_GPR8 */ +DATA 4 0x30340020 0x00000178 +/* CCM_CCGRn */ +DATA 4 0x30384130 0x00000002 +/* DDR_PHY_LP_CON0 */ +DATA 4 0x30790018 0x0000000f + +/* DDRC_STAT */ +CHECK_BITS_SET 4 0x307a0004 0x1 -- cgit From a13d3757f7df25d0f017e85551b899d598ad1bdb Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Sat, 23 Jul 2016 13:23:38 -0300 Subject: warp: Use imx_ddr_size() for calculating the DDR size imx_ddr_size() can be used to calculate the DDR size in runtime. By using this function we no longer need to define PHYS_SDRAM_SIZE. Signed-off-by: Fabio Estevam --- board/warp/warp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'board') diff --git a/board/warp/warp.c b/board/warp/warp.c index 49dfdb6717..0bc0a6a92e 100644 --- a/board/warp/warp.c +++ b/board/warp/warp.c @@ -46,7 +46,7 @@ DECLARE_GLOBAL_DATA_PTR; int dram_init(void) { - gd->ram_size = get_ram_size((void *)PHYS_SDRAM, PHYS_SDRAM_SIZE); + gd->ram_size = imx_ddr_size(); return 0; } -- cgit From 84c51687a79c4bac514c43c0c3a0118015e6b13c Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Sat, 23 Jul 2016 13:23:39 -0300 Subject: aristainetos: Use imx_ddr_size() for calculating the DDR size imx_ddr_size() can be used to calculate the DDR size in runtime. By using this function we no longer need to define PHYS_SDRAM_SIZE. Cc: Heiko Schocher Signed-off-by: Fabio Estevam Acked-by: Heiko Schocher --- board/aristainetos/aristainetos.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'board') diff --git a/board/aristainetos/aristainetos.c b/board/aristainetos/aristainetos.c index e95ec81760..d1e6850636 100644 --- a/board/aristainetos/aristainetos.c +++ b/board/aristainetos/aristainetos.c @@ -102,7 +102,7 @@ iomux_v3_cfg_t const usdhc1_pads[] = { int dram_init(void) { - gd->ram_size = get_ram_size((void *)PHYS_SDRAM, PHYS_SDRAM_SIZE); + gd->ram_size = imx_ddr_size(); return 0; } -- cgit From c6a51bab174ecb4c6bebfada951ac556ffc13fcd Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Sat, 23 Jul 2016 13:23:40 -0300 Subject: bx50v3: Use imx_ddr_size() for calculating the DDR size imx_ddr_size() can be used to calculate the DDR size in runtime. By using this function we no longer need to define PHYS_SDRAM_SIZE. Cc: Martin Donnelly Signed-off-by: Fabio Estevam --- board/ge/bx50v3/bx50v3.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'board') diff --git a/board/ge/bx50v3/bx50v3.c b/board/ge/bx50v3/bx50v3.c index d45ed44c68..e9729f88e5 100644 --- a/board/ge/bx50v3/bx50v3.c +++ b/board/ge/bx50v3/bx50v3.c @@ -60,7 +60,7 @@ DECLARE_GLOBAL_DATA_PTR; int dram_init(void) { - gd->ram_size = get_ram_size((void *)PHYS_SDRAM, PHYS_SDRAM_SIZE); + gd->ram_size = imx_ddr_size(); return 0; } -- cgit From ec1935a243fcb4368fd8b537872d01d6b967b90f Mon Sep 17 00:00:00 2001 From: Diego Dorta Date: Mon, 25 Jul 2016 13:45:30 -0300 Subject: mx6ul_14x14_evk: Remove unused define Remove unused define constant. Signed-off-by: Diego Dorta Reviewed-by: Fabio Estevam --- board/freescale/mx6ul_14x14_evk/mx6ul_14x14_evk.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'board') diff --git a/board/freescale/mx6ul_14x14_evk/mx6ul_14x14_evk.c b/board/freescale/mx6ul_14x14_evk/mx6ul_14x14_evk.c index 92c92117cd..66d679556b 100644 --- a/board/freescale/mx6ul_14x14_evk/mx6ul_14x14_evk.c +++ b/board/freescale/mx6ul_14x14_evk/mx6ul_14x14_evk.c @@ -60,9 +60,6 @@ DECLARE_GLOBAL_DATA_PTR; #define ENET_CLK_PAD_CTRL (PAD_CTL_DSE_40ohm | PAD_CTL_SRE_FAST) -#define ENET_RX_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE | \ - PAD_CTL_SPEED_HIGH | PAD_CTL_SRE_FAST) - #define IOX_SDI IMX_GPIO_NR(5, 10) #define IOX_STCP IMX_GPIO_NR(5, 7) #define IOX_SHCP IMX_GPIO_NR(5, 11) -- cgit From 4c97077ce781d192ac20853d36d1df60dd271699 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Tue, 26 Jul 2016 21:08:58 -0300 Subject: mx7dsabresd: MAINTAINERS: Add mx7dsabresd_secure_defconfig Add an entry for the mx7dsabresd_secure_defconfig target. Signed-off-by: Fabio Estevam --- board/freescale/mx7dsabresd/MAINTAINERS | 1 + 1 file changed, 1 insertion(+) (limited to 'board') diff --git a/board/freescale/mx7dsabresd/MAINTAINERS b/board/freescale/mx7dsabresd/MAINTAINERS index b96642a568..c7a22fc0d3 100644 --- a/board/freescale/mx7dsabresd/MAINTAINERS +++ b/board/freescale/mx7dsabresd/MAINTAINERS @@ -4,3 +4,4 @@ S: Maintained F: board/freescale/mx7dsabresd F: include/configs/mx7dsabresd.h F: configs/mx7dsabresd_defconfig +F: configs/mx7dsabresd_secure_defconfig -- cgit