From b36bd6175bccc76102831d1110519c6e41a1d7c6 Mon Sep 17 00:00:00 2001 From: Wig C Date: Fri, 4 Dec 2015 17:46:23 +0800 Subject: MA-9190 Add pico-imx7d board support Ethnet is not supported in uboot. But ethnet on kernel relay the config in uboot. Once ethnet on kernel is indepedent, will remove ethnet code in uboot. Change-Id: If44705d2fbfc1c596cbce010ff7106fcd7556b9f --- board/technexion/pico-imx7d/Kconfig | 15 + board/technexion/pico-imx7d/MAINTAINERS | 6 + board/technexion/pico-imx7d/Makefile | 10 + board/technexion/pico-imx7d/imximage.cfg | 116 ++++++ board/technexion/pico-imx7d/pico-imx7d.c | 676 +++++++++++++++++++++++++++++++ board/technexion/pico-imx7d/plugin.S | 227 +++++++++++ 6 files changed, 1050 insertions(+) create mode 100644 board/technexion/pico-imx7d/Kconfig create mode 100644 board/technexion/pico-imx7d/MAINTAINERS create mode 100644 board/technexion/pico-imx7d/Makefile create mode 100644 board/technexion/pico-imx7d/imximage.cfg create mode 100755 board/technexion/pico-imx7d/pico-imx7d.c create mode 100755 board/technexion/pico-imx7d/plugin.S (limited to 'board/technexion/pico-imx7d') diff --git a/board/technexion/pico-imx7d/Kconfig b/board/technexion/pico-imx7d/Kconfig new file mode 100644 index 0000000..f4ae18c --- /dev/null +++ b/board/technexion/pico-imx7d/Kconfig @@ -0,0 +1,15 @@ +if TARGET_PICO_IMX7D + +config SYS_BOARD + default "pico-imx7d" + +config SYS_VENDOR + default "technexion" + +config SYS_SOC + default "mx7" + +config SYS_CONFIG_NAME + default "pico-imx7d" + +endif diff --git a/board/technexion/pico-imx7d/MAINTAINERS b/board/technexion/pico-imx7d/MAINTAINERS new file mode 100644 index 0000000..99c9982 --- /dev/null +++ b/board/technexion/pico-imx7d/MAINTAINERS @@ -0,0 +1,6 @@ +Technexion PICO-IMX7D board +M: Wig Cheng +S: Maintained +F: board/pico-imx7d/ +F: include/configs/pico-imx7d.h +F: configs/pico-imx7d_defconfig diff --git a/board/technexion/pico-imx7d/Makefile b/board/technexion/pico-imx7d/Makefile new file mode 100644 index 0000000..30bba14 --- /dev/null +++ b/board/technexion/pico-imx7d/Makefile @@ -0,0 +1,10 @@ +# (C) Copyright 2015 Freescale Semiconductor, Inc. +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-y := pico-imx7d.o + +extra-$(CONFIG_USE_PLUGIN) := plugin.bin +$(obj)/plugin.bin: $(obj)/plugin.o + $(OBJCOPY) -O binary --gap-fill 0xff $< $@ diff --git a/board/technexion/pico-imx7d/imximage.cfg b/board/technexion/pico-imx7d/imximage.cfg new file mode 100644 index 0000000..87088d2 --- /dev/null +++ b/board/technexion/pico-imx7d/imximage.cfg @@ -0,0 +1,116 @@ +/* + * Copyright (C) 2015-2016 Freescale Semiconductor, Inc. + * + * 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 : one of + * spi/sd/nand/onenand, qspi/nor + */ + +#ifdef CONFIG_SYS_BOOT_QSPI +BOOT_FROM qspi +#elif defined(CONFIG_SYS_BOOT_EIMNOR) +BOOT_FROM nor +#else +BOOT_FROM sd +#endif + +#ifdef CONFIG_USE_PLUGIN +/*PLUGIN plugin-binary-file IRAM_FREE_START_ADDR*/ +PLUGIN board/technexion/pico-imx7d/plugin.bin 0x00910000 +#else + +#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 + */ + +DATA 4 0x30340004 0x4F400005 +/* Clear then set bit30 to ensure exit from DDR retention */ +DATA 4 0x30360388 0x40000000 +DATA 4 0x30360384 0x40000000 + +DATA 4 0x30391000 0x00000002 +DATA 4 0x307a0000 0x01040001 +DATA 4 0x307a01a0 0x80400003 +DATA 4 0x307a01a4 0x00100020 +DATA 4 0x307a01a8 0x80100004 +DATA 4 0x307a0064 0x00400046 +DATA 4 0x307a0490 0x00000001 +DATA 4 0x307a00d0 0x00020083 +DATA 4 0x307a00d4 0x00690000 +DATA 4 0x307a00dc 0x09300004 +DATA 4 0x307a00e0 0x04080000 +DATA 4 0x307a00e4 0x00100004 +DATA 4 0x307a00f4 0x0000033f +DATA 4 0x307a0100 0x09081109 +DATA 4 0x307a0104 0x0007020d +DATA 4 0x307a0108 0x03040407 +DATA 4 0x307a010c 0x00002006 +DATA 4 0x307a0110 0x04020205 +DATA 4 0x307a0114 0x03030202 +DATA 4 0x307a0120 0x00000803 +DATA 4 0x307a0180 0x00800020 +DATA 4 0x307a0184 0x02000100 +DATA 4 0x307a0190 0x02098204 +DATA 4 0x307a0194 0x00030303 +DATA 4 0x307a0200 0x00000016 +DATA 4 0x307a0204 0x00080808 +DATA 4 0x307a0210 0x00000f0f +DATA 4 0x307a0214 0x07070707 +DATA 4 0x307a0218 0x0f070707 +DATA 4 0x307a0240 0x06000604 +DATA 4 0x307a0244 0x00000001 +DATA 4 0x30391000 0x00000000 +DATA 4 0x30790000 0x17420f40 +DATA 4 0x30790004 0x10210100 +DATA 4 0x30790010 0x00060807 +DATA 4 0x307900b0 0x1010007e +DATA 4 0x3079009c 0x00000b24 +DATA 4 0x30790020 0x08080808 +DATA 4 0x30790030 0x08080808 +DATA 4 0x30790050 0x01000010 +DATA 4 0x30790050 0x00000010 + +DATA 4 0x307900c0 0x0e407304 +DATA 4 0x307900c0 0x0e447304 +DATA 4 0x307900c0 0x0e447306 + +CHECK_BITS_SET 4 0x307900c4 0x1 + +DATA 4 0x307900c0 0x0e407304 + + +DATA 4 0x30384130 0x00000000 +DATA 4 0x30340020 0x00000178 +DATA 4 0x30384130 0x00000002 +DATA 4 0x30790018 0x0000000f + +CHECK_BITS_SET 4 0x307a0004 0x1 + +#endif diff --git a/board/technexion/pico-imx7d/pico-imx7d.c b/board/technexion/pico-imx7d/pico-imx7d.c new file mode 100755 index 0000000..245b2b8 --- /dev/null +++ b/board/technexion/pico-imx7d/pico-imx7d.c @@ -0,0 +1,676 @@ +/* + * Copyright (C) 2015 Freescale Semiconductor, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef CONFIG_SYS_I2C_MXC +#include +#include +#endif +#if defined(CONFIG_MXC_EPDC) +#include +#include +#endif +#include + +#ifdef CONFIG_VIDEO_MXS +#include +#include +#endif + + +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 QSPI_PAD_CTRL \ + (PAD_CTL_DSE_3P3V_49OHM | PAD_CTL_PUE | PAD_CTL_PUS_PU47KOHM) + +#define SPI_PAD_CTRL (PAD_CTL_DSE_3P3V_49OHM | PAD_CTL_SRE_SLOW | PAD_CTL_HYS) + +#define BUTTON_PAD_CTRL (PAD_CTL_PUS_PU5KOHM | PAD_CTL_DSE_3P3V_98OHM) + +#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) + +#define EPDC_PAD_CTRL 0x0 + +#ifdef CONFIG_SYS_I2C_MXC +#define PC MUX_PAD_CTRL(I2C_PAD_CTRL) +/* I2C1*/ +struct i2c_pads_info i2c_pad_info1 = { + .scl = { + .i2c_mode = MX7D_PAD_UART1_RX_DATA__I2C1_SCL | PC, + .gpio_mode = MX7D_PAD_UART1_RX_DATA__GPIO4_IO0 | PC, + .gp = IMX_GPIO_NR(4, 0), + }, + .sda = { + .i2c_mode = MX7D_PAD_UART1_TX_DATA__I2C1_SDA | PC, + .gpio_mode = MX7D_PAD_UART1_TX_DATA__GPIO4_IO1 | PC, + .gp = IMX_GPIO_NR(4, 1), + }, +}; + +/* I2C2 */ +struct i2c_pads_info i2c_pad_info2 = { + .scl = { + .i2c_mode = MX7D_PAD_UART2_RX_DATA__I2C2_SCL | PC, + .gpio_mode = MX7D_PAD_UART2_RX_DATA__GPIO4_IO2 | PC, + .gp = IMX_GPIO_NR(4, 2), + }, + .sda = { + .i2c_mode = MX7D_PAD_UART2_TX_DATA__I2C2_SDA | PC, + .gpio_mode = MX7D_PAD_UART2_TX_DATA__GPIO4_IO3 | PC, + .gp = IMX_GPIO_NR(4, 3), + }, +}; + +/* I2C4 for PMIC*/ +struct i2c_pads_info i2c_pad_info4 = { + .scl = { + .i2c_mode = MX7D_PAD_SAI1_RX_SYNC__I2C4_SCL | PC, + .gpio_mode = MX7D_PAD_SAI1_RX_SYNC__GPIO6_IO16 | PC, + .gp = IMX_GPIO_NR(6, 16), + }, + .sda = { + .i2c_mode = MX7D_PAD_SAI1_RX_BCLK__I2C4_SDA | PC, + .gpio_mode = MX7D_PAD_SAI1_RX_BCLK__GPIO6_IO17 | PC, + .gp = IMX_GPIO_NR(6, 17), + }, +}; +#endif + +int dram_init(void) +{ + gd->ram_size = PHYS_SDRAM_SIZE; + + return 0; +} + +static iomux_v3_cfg_t const wdog_pads[] = { + MX7D_PAD_GPIO1_IO00__WDOG1_WDOG_B | MUX_PAD_CTRL(NO_PAD_CTRL), +}; + +static iomux_v3_cfg_t const uart5_pads[] = { + MX7D_PAD_I2C4_SCL__UART5_DCE_RX | MUX_PAD_CTRL(UART_PAD_CTRL), + MX7D_PAD_I2C4_SDA__UART5_DCE_TX | 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_SD1_CD_B__GPIO5_IO0 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX7D_PAD_SD1_RESET_B__SD1_RESET_B | MUX_PAD_CTRL(USDHC_PAD_CTRL), +}; + +/* SD */ +#ifdef PICO_SD +#define USDHC3_CD_GPIO IMX_GPIO_NR(6, 9) +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_DATA7__GPIO6_IO9 | MUX_PAD_CTRL(USDHC_PAD_CTRL), +}; +#else +/* EMMC */ +#define USDHC3_CD_GPIO IMX_GPIO_NR(1, 14) +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_GPIO1_IO14__GPIO1_IO14 | MUX_PAD_CTRL(USDHC_PAD_CTRL), +}; +#endif + +#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), + MX7D_PAD_LCD_DATA18__LCD_DATA18 | MUX_PAD_CTRL(LCD_PAD_CTRL), + MX7D_PAD_LCD_DATA19__LCD_DATA19 | MUX_PAD_CTRL(LCD_PAD_CTRL), + MX7D_PAD_LCD_DATA20__LCD_DATA20 | MUX_PAD_CTRL(LCD_PAD_CTRL), + MX7D_PAD_LCD_DATA21__LCD_DATA21 | MUX_PAD_CTRL(LCD_PAD_CTRL), + MX7D_PAD_LCD_DATA22__LCD_DATA22 | MUX_PAD_CTRL(LCD_PAD_CTRL), + MX7D_PAD_LCD_DATA23__LCD_DATA23 | MUX_PAD_CTRL(LCD_PAD_CTRL), + MX7D_PAD_LCD_RESET__GPIO3_IO4 | MUX_PAD_CTRL(LCD_PAD_CTRL), + MX7D_PAD_GPIO1_IO06__GPIO1_IO6 | MUX_PAD_CTRL(LCD_PAD_CTRL), /* LCD_VDD_EN */ +}; + +static iomux_v3_cfg_t const pwm_pads[] = { + /* Use GPIO for Brightness adjustment, duty cycle = period */ + MX7D_PAD_GPIO1_IO11__GPIO1_IO11 | MUX_PAD_CTRL(NO_PAD_CTRL), /* LCD_BLT_CTRL */ +}; + +struct lcd_panel_info_t { + unsigned int lcdif_base_addr; + int depth; + void (*enable)(struct lcd_panel_info_t const *dev); + struct fb_videomode mode; +}; + +void do_enable_parallel_lcd(struct lcd_panel_info_t const *dev) +{ + imx_iomux_v3_setup_multiple_pads(lcd_pads, ARRAY_SIZE(lcd_pads)); + + imx_iomux_v3_setup_multiple_pads(pwm_pads, ARRAY_SIZE(pwm_pads)); + + /* Reset LCD */ + gpio_direction_output(IMX_GPIO_NR(3, 4) , 0); + udelay(500); + gpio_direction_output(IMX_GPIO_NR(3, 4) , 1); + + /* Set Brightness to high */ + gpio_direction_output(IMX_GPIO_NR(1, 11) , 1); + /* Set LCD enable to high */ + gpio_direction_output(IMX_GPIO_NR(1, 6) , 1); +} + +static struct lcd_panel_info_t const displays[] = {{ + .lcdif_base_addr = ELCDIF1_IPS_BASE_ADDR, + .depth = 24, + .enable = do_enable_parallel_lcd, + .mode = { + .name = "EJ050NA", + .xres = 800, + .yres = 480, + .pixclock = 29850, + .left_margin = 89, + .right_margin = 164, + .upper_margin = 23, + .lower_margin = 10, + .hsync_len = 10, + .vsync_len = 10, + .sync = 0, + .vmode = FB_VMODE_NONINTERLACED +} } }; + +int board_video_skip(void) +{ + int i; + int ret; + char const *panel = getenv("panel"); + if (!panel) { + panel = displays[0].mode.name; + printf("No panel detected: default to %s\n", panel); + i = 0; + } else { + for (i = 0; i < ARRAY_SIZE(displays); i++) { + if (!strcmp(panel, displays[i].mode.name)) + break; + } + } + if (i < ARRAY_SIZE(displays)) { + ret = mxs_lcd_panel_setup(displays[i].mode, displays[i].depth, + displays[i].lcdif_base_addr); + if (!ret) { + if (displays[i].enable) + displays[i].enable(displays+i); + printf("Display: %s (%ux%u)\n", + displays[i].mode.name, + displays[i].mode.xres, + displays[i].mode.yres); + } else + printf("LCD %s cannot be configured: %d\n", + displays[i].mode.name, ret); + } else { + printf("unsupported panel %s\n", panel); + return -EINVAL; + } + + return 0; +} +#endif + +#ifdef CONFIG_FEC_MXC +static iomux_v3_cfg_t const fec1_pads[] = { + MX7D_PAD_SD2_CD_B__ENET2_MDIO | MUX_PAD_CTRL(ENET_PAD_CTRL_MII), + MX7D_PAD_SD2_WP__ENET2_MDC | MUX_PAD_CTRL(ENET_PAD_CTRL_MII), + MX7D_PAD_ENET1_RGMII_TXC__ENET1_RGMII_TXC | MUX_PAD_CTRL(ENET_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_TD2__ENET1_RGMII_TD2 | MUX_PAD_CTRL(ENET_PAD_CTRL), + MX7D_PAD_ENET1_RGMII_TD3__ENET1_RGMII_TD3 | MUX_PAD_CTRL(ENET_PAD_CTRL), + MX7D_PAD_ENET1_RGMII_TX_CTL__ENET1_RGMII_TX_CTL | MUX_PAD_CTRL(ENET_PAD_CTRL), + MX7D_PAD_ENET1_RGMII_RXC__ENET1_RGMII_RXC | MUX_PAD_CTRL(ENET_RX_PAD_CTRL), + 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_RD2__ENET1_RGMII_RD2 | MUX_PAD_CTRL(ENET_RX_PAD_CTRL), + MX7D_PAD_ENET1_RGMII_RD3__ENET1_RGMII_RD3 | 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_SD3_STROBE__GPIO6_IO10 | MUX_PAD_CTRL(NO_PAD_CTRL), // Interrupt + MX7D_PAD_SD3_RESET_B__GPIO6_IO11 | MUX_PAD_CTRL(NO_PAD_CTRL), // Reset pin +}; + +#define FEC1_RST_GPIO IMX_GPIO_NR(6, 11) + + +static void setup_iomux_fec(void) +{ + imx_iomux_v3_setup_multiple_pads(fec1_pads, ARRAY_SIZE(fec1_pads)); +} +#endif + +static iomux_v3_cfg_t const bcm4339_pads[] = { + MX7D_PAD_ECSPI1_SCLK__GPIO4_IO16 | MUX_PAD_CTRL(NO_PAD_CTRL), //wifi reset + MX7D_PAD_ECSPI1_MISO__GPIO4_IO18 | MUX_PAD_CTRL(NO_PAD_CTRL), //bt reset +}; + +static iomux_v3_cfg_t const ccm_clko_pads[] = { + MX7D_PAD_GPIO1_IO03__CCM_CLKO2 | MUX_PAD_CTRL(NO_PAD_CTRL), + MX7D_PAD_GPIO1_IO02__CCM_CLKO1 | MUX_PAD_CTRL(NO_PAD_CTRL), +}; + +static void setup_iomux_uart(void) +{ + imx_iomux_v3_setup_multiple_pads(uart5_pads, ARRAY_SIZE(uart5_pads)); +} + +#ifdef CONFIG_FSL_ESDHC + +#define USDHC1_CD_GPIO IMX_GPIO_NR(5, 0) + +static struct fsl_esdhc_cfg usdhc_cfg[3] = { + {USDHC1_BASE_ADDR, 0, 4}, + {USDHC3_BASE_ADDR}, +}; + +int mmc_get_env_devno(void) +{ + struct bootrom_sw_info **p = + (struct bootrom_sw_info **)ROM_SW_INFO_ADDR; + + u8 boot_type = (*p)->boot_dev_type; + u8 dev_no = (*p)->boot_dev_instance; + + /* If not boot from sd/mmc, use default value */ + if ((boot_type != BOOT_TYPE_SD) && (boot_type != BOOT_TYPE_MMC)) + return CONFIG_SYS_MMC_ENV_DEV; + + if (2 == dev_no) + dev_no--; + + return dev_no; +} + +int mmc_map_to_kernel_blk(int dev_no) +{ + if (1 == dev_no) + dev_no++; + + return dev_no; +} + +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); /* Assume uSDHC1 sd is always present */ + break; + case USDHC3_BASE_ADDR: + ret = !gpio_get_value(USDHC3_CD_GPIO); /* Assume uSDHC3 emmc is always present */ + break; + } + + return ret; +} + +int board_mmc_init(bd_t *bis) +{ + int i, ret; + /* + * According to the board_mmc_init() the following map is done: + * (U-boot device node) (Physical Port) + * mmc0 USDHC1 + * mmc2 USDHC3 (eMMC) + */ + 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)); + usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC_CLK); + break; + case 1: + imx_iomux_v3_setup_multiple_pads( + usdhc3_emmc_pads, ARRAY_SIZE(usdhc3_emmc_pads)); + gpio_request(USDHC3_CD_GPIO, "usdhc3_cd"); + gpio_direction_input(USDHC3_CD_GPIO); + usdhc_cfg[1].sdhc_clk = mxc_get_clock(MXC_ESDHC3_CLK); + break; + default: + printf("Warning: you configured more USDHC controllers" + "(%d) than supported by the board\n", i + 1); + return 0; + } + + ret = fsl_esdhc_initialize(bis, &usdhc_cfg[i]); + if (ret) + return ret; + } + + return 0; +} + +int check_mmc_autodetect(void) +{ + char *autodetect_str = getenv("mmcautodetect"); + + if ((autodetect_str != NULL) && + (strcmp(autodetect_str, "yes") == 0)) { + return 1; + } + + return 0; +} + +void board_late_mmc_init(void) +{ + char cmd[32]; + char mmcblk[32]; + u32 dev_no = mmc_get_env_devno(); + + if (!check_mmc_autodetect()) + return; + + setenv_ulong("mmcdev", dev_no); + + /* Set mmcblk env */ + sprintf(mmcblk, "/dev/mmcblk%dp2 rootwait rw", + mmc_map_to_kernel_blk(dev_no)); + setenv("mmcroot", mmcblk); + + sprintf(cmd, "mmc dev %d", dev_no); + run_command(cmd, 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__); + + gpio_direction_output(FEC1_RST_GPIO, 0); + udelay(500); + gpio_set_value(FEC1_RST_GPIO, 1); + + 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; + int ret; + + /* Use 125M anatop REF_CLK1 for ENET1, clear gpr1[13], gpr1[17]*/ + clrsetbits_le32(&iomuxc_gpr_regs->gpr[1], + (IOMUXC_GPR_GPR1_GPR_ENET1_TX_CLK_SEL_MASK | + IOMUXC_GPR_GPR1_GPR_ENET1_CLK_DIR_MASK), 0); + + ret = set_clk_enet(ENET_125MHz); + if (ret) + return ret; + + return 0; +} + + +int board_phy_config(struct phy_device *phydev) +{ + /* enable rgmii rxc skew and phy mode select to RGMII copper */ + /*phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, 0x21); + phy_write(phydev, MDIO_DEVAD_NONE, 0x1f, 0x7ea8); + phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, 0x2f); + phy_write(phydev, MDIO_DEVAD_NONE, 0x1f, 0x71b7);*/ + + unsigned short val; + + /* To enable AR8035 ouput a 125MHz clk from CLK_25M */ +/* phy_write(phydev, MDIO_DEVAD_NONE, 0xd, 0x7); + phy_write(phydev, MDIO_DEVAD_NONE, 0xe, 0x8016); + phy_write(phydev, MDIO_DEVAD_NONE, 0xd, 0x4007); + + val = phy_read(phydev, MDIO_DEVAD_NONE, 0xe); + val &= 0xffe7; + val |= 0x18; + phy_write(phydev, MDIO_DEVAD_NONE, 0xe, val); +*/ + /* introduce tx clock delay */ + phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x5); + val = phy_read(phydev, MDIO_DEVAD_NONE, 0x1e); + val |= 0x0100; + phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, val); + + 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(1, CONFIG_SYS_I2C_SPEED, 0x7f, &i2c_pad_info2); + setup_i2c(3, CONFIG_SYS_I2C_SPEED, 0x7f, &i2c_pad_info4); +#endif + + return 0; +} + +#define BT_RST_GPIO IMX_GPIO_NR(6, 16) +#define WIFI_RST_GPIO IMX_GPIO_NR(6, 17) + +int board_init(void) +{ + /* address of boot parameters */ + gd->bd->bi_boot_params = PHYS_SDRAM + 0x100; + +#ifdef CONFIG_FEC_MXC + setup_fec(); +#endif + + //pico-imx7 custom initialize + imx_iomux_v3_setup_multiple_pads(bcm4339_pads, ARRAY_SIZE(bcm4339_pads)); + imx_iomux_v3_setup_multiple_pads(ccm_clko_pads, ARRAY_SIZE(ccm_clko_pads)); + + gpio_direction_output(BT_RST_GPIO, 1); + udelay(500); + gpio_direction_output(WIFI_RST_GPIO, 1); + udelay(500); + clock_set_src(IPP_DO_CLKO2,OSC_32K_CLK); + udelay(500); + clock_set_src(IPP_DO_CLKO1,OSC_24M_CLK); + + return 0; +} + +#ifdef CONFIG_CMD_BMODE +static const struct boot_mode board_boot_modes[] = { + /* 4 bit bus width */ + {"sd1", MAKE_CFGVAL(0x10, 0x10, 0x00, 0x00)}, + {"emmc", MAKE_CFGVAL(0x10, 0x2a, 0x00, 0x00)}, + /* TODO: Nand */ + /*{"qspi", MAKE_CFGVAL(0x00, 0x40, 0x00, 0x00)},*/ + {NULL, 0}, +}; +#endif + +#ifdef CONFIG_POWER +#define I2C_PMIC 3 +int power_init_board(void) +{ + struct pmic *p; + int ret; + unsigned int reg, rev_id; + + ret = power_pfuze300_init(I2C_PMIC); + if (ret) + return ret; + + p = pmic_get("PFUZE300"); + ret = pmic_probe(p); + if (ret) + return ret; + + pmic_reg_read(p, PFUZE300_DEVICEID, ®); + pmic_reg_read(p, PFUZE300_REVID, &rev_id); + printf("PMIC: PFUZE300 DEV_ID=0x%x REV_ID=0x%x\n", reg, rev_id); + + /* disable Low Power Mode during standby mode */ + pmic_reg_read(p, PFUZE300_LDOGCTL, ®); + reg |= 0x1; + pmic_reg_write(p, PFUZE300_LDOGCTL, reg); + + /* SW1A/1B mode set to APS/APS */ + reg = 0x8; + pmic_reg_write(p, PFUZE300_SW1AMODE, reg); + pmic_reg_write(p, PFUZE300_SW1BMODE, reg); + + /* SW1A/1B standby voltage set to 1.025V */ + reg = 0xd; + pmic_reg_write(p, PFUZE300_SW1ASTBY, reg); + pmic_reg_write(p, PFUZE300_SW1BSTBY, reg); + + /* decrease SW1B normal voltage to 0.975V */ + pmic_reg_read(p, PFUZE300_SW1BVOLT, ®); + reg &= ~0x1f; + reg |= PFUZE300_SW1AB_SETP(975); + pmic_reg_write(p, PFUZE300_SW1BVOLT, reg); + + return 0; +} +#endif + +int board_late_init(void) +{ +#ifdef CONFIG_CMD_BMODE + add_board_boot_modes(board_boot_modes); +#endif + +#ifdef CONFIG_ENV_IS_IN_MMC + board_late_mmc_init(); +#endif + + imx_iomux_v3_setup_multiple_pads(wdog_pads, ARRAY_SIZE(wdog_pads)); + + set_wdog_reset((struct wdog_regs *)WDOG1_BASE_ADDR); + + return 0; +} + +u32 get_board_rev(void) +{ + return get_cpu_rev(); +} + +int checkboard(void) +{ + puts("Board: i.MX7D PICOSOM\n"); + + return 0; +} + +#ifdef CONFIG_USB_EHCI_MX7 +iomux_v3_cfg_t const usb_otg1_pads[] = { + MX7D_PAD_UART3_TX_DATA__USB_OTG1_PWR | MUX_PAD_CTRL(NO_PAD_CTRL), +}; + +int board_ehci_hcd_init(int port) +{ + switch (port) { + case 0: + imx_iomux_v3_setup_multiple_pads(usb_otg1_pads, + ARRAY_SIZE(usb_otg1_pads)); + break; + + default: + printf("MXC USB port %d not yet supported\n", port); + return 1; + } + return 0; +} +#endif + diff --git a/board/technexion/pico-imx7d/plugin.S b/board/technexion/pico-imx7d/plugin.S new file mode 100755 index 0000000..75033f7 --- /dev/null +++ b/board/technexion/pico-imx7d/plugin.S @@ -0,0 +1,227 @@ +/* + * Copyright (C) 2014-2016 Freescale Semiconductor, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include + +/* DDR script */ +.macro imx7d_ddrphy_latency_setting + ldr r2, =ANATOP_BASE_ADDR + ldr r3, [r2, #0x800] + and r3, r3, #0xFF + cmp r3, #0x11 + bne NO_DELAY + + /*TO 1.1*/ + ldr r1, =0x00000dee + str r1, [r0, #0x9c] + ldr r1, =0x18181818 + str r1, [r0, #0x7c] + ldr r1, =0x18181818 + str r1, [r0, #0x80] + ldr r1, =0x40401818 + str r1, [r0, #0x84] + ldr r1, =0x00000040 + str r1, [r0, #0x88] + ldr r1, =0x40404040 + str r1, [r0, #0x6c] + b TUNE_END + +NO_DELAY: + /*TO 1.0*/ + ldr r1, =0x00000b24 + str r1, [r0, #0x9c] + +TUNE_END: +.endm + +.macro imx7d_ddr_freq_setting + ldr r2, =ANATOP_BASE_ADDR + ldr r3, [r2, #0x800] + and r3, r3, #0xFF + cmp r3, #0x11 + bne FREQ_DEFAULT_533 + + /* Change to 400Mhz for TO1.1 */ + ldr r0, =ANATOP_BASE_ADDR + ldr r1, =0x70 + ldr r2, =0x00703021 + str r2, [r0, r1] + ldr r1, =0x90 + ldr r2, =0x0 + str r2, [r0, r1] + ldr r1, =0x70 + ldr r2, =0x00603021 + str r2, [r0, r1] + + ldr r3, =0x80000000 +wait_lock: + ldr r2, [r0, r1] + and r2, r3 + cmp r2, r3 + bne wait_lock + + ldr r0, =CCM_BASE_ADDR + ldr r1, =0x9880 + ldr r2, =0x1 + str r2, [r0, r1] + +FREQ_DEFAULT_533: +.endm + +.macro imx7d_sabresd_ddr_setting + imx7d_ddr_freq_setting + + /* Configure ocram_epdc */ + ldr r0, =IOMUXC_GPR_BASE_ADDR + ldr r1, =0x4f400005 + str r1, [r0, #0x4] + + /* clear/set bit30 of SNVS_MISC_CTRL to ensure exit from ddr retention */ + ldr r0, =ANATOP_BASE_ADDR + ldr r1, =(0x1 << 30) + str r1, [r0, #0x388] + str r1, [r0, #0x384] + + ldr r0, =SRC_BASE_ADDR + ldr r1, =0x2 + ldr r2, =0x1000 + str r1, [r0, r2] + + ldr r0, =DDRC_IPS_BASE_ADDR + ldr r1, =0x01040001 + str r1, [r0] + ldr r1, =0x80400003 + str r1, [r0, #0x1a0] + ldr r1, =0x00100020 + str r1, [r0, #0x1a4] + ldr r1, =0x80100004 + str r1, [r0, #0x1a8] + ldr r1, =0x00400046 + str r1, [r0, #0x64] + ldr r1, =0x1 + str r1, [r0, #0x490] + ldr r1, =0x00020001 + str r1, [r0, #0xd0] + ldr r1, =0x00690000 + str r1, [r0, #0xd4] + ldr r1, =0x09300004 + str r1, [r0, #0xdc] + ldr r1, =0x04080000 + str r1, [r0, #0xe0] + ldr r1, =0x00100004 + str r1, [r0, #0xe4] + ldr r1, =0x33f + str r1, [r0, #0xf4] + ldr r1, =0x09081109 + str r1, [r0, #0x100] + ldr r1, =0x0007020d + str r1, [r0, #0x104] + ldr r1, =0x03040407 + str r1, [r0, #0x108] + ldr r1, =0x00002006 + str r1, [r0, #0x10c] + ldr r1, =0x04020205 + str r1, [r0, #0x110] + ldr r1, =0x03030202 + str r1, [r0, #0x114] + ldr r1, =0x00000803 + str r1, [r0, #0x120] + ldr r1, =0x00800020 + str r1, [r0, #0x180] + ldr r1, =0x02000100 + str r1, [r0, #0x184] + ldr r1, =0x02098204 + str r1, [r0, #0x190] + ldr r1, =0x00030303 + str r1, [r0, #0x194] + + ldr r1, =0x00000016 + str r1, [r0, #0x200] + ldr r1, =0x00080808 + str r1, [r0, #0x204] + ldr r1, =0x00000f0f + str r1, [r0, #0x210] + ldr r1, =0x07070707 + str r1, [r0, #0x214] + ldr r1, =0x0f070707 + str r1, [r0, #0x218] + + ldr r1, =0x06000604 + str r1, [r0, #0x240] + ldr r1, =0x00000001 + str r1, [r0, #0x244] + + ldr r0, =SRC_BASE_ADDR + mov r1, #0x0 + ldr r2, =0x1000 + str r1, [r0, r2] + + ldr r0, =DDRPHY_IPS_BASE_ADDR + ldr r1, =0x17420f40 + str r1, [r0] + ldr r1, =0x10210100 + str r1, [r0, #0x4] + ldr r1, =0x00060807 + str r1, [r0, #0x10] + ldr r1, =0x1010007e + str r1, [r0, #0xb0] + imx7d_ddrphy_latency_setting + ldr r1, =0x08080808 + str r1, [r0, #0x20] + ldr r1, =0x08080808 + str r1, [r0, #0x30] + ldr r1, =0x01000010 + str r1, [r0, #0x50] + + ldr r1, =0x0e407304 + str r1, [r0, #0xc0] + ldr r1, =0x0e447304 + str r1, [r0, #0xc0] + ldr r1, =0x0e447306 + str r1, [r0, #0xc0] + +wait_zq: + ldr r1, [r0, #0xc4] + tst r1, #0x1 + beq wait_zq + + ldr r1, =0x0e407304 + str r1, [r0, #0xc0] + + ldr r0, =CCM_BASE_ADDR + mov r1, #0x0 + ldr r2, =0x4130 + str r1, [r0, r2] + ldr r0, =IOMUXC_GPR_BASE_ADDR + mov r1, #0x178 + str r1, [r0, #0x20] + ldr r0, =CCM_BASE_ADDR + mov r1, #0x2 + ldr r2, =0x4130 + str r1, [r0, r2] + ldr r0, =DDRPHY_IPS_BASE_ADDR + ldr r1, =0x0000000f + str r1, [r0, #0x18] + + ldr r0, =DDRC_IPS_BASE_ADDR +wait_stat: + ldr r1, [r0, #0x4] + tst r1, #0x1 + beq wait_stat +.endm + +.macro imx7_clock_gating +.endm + +.macro imx7_qos_setting +.endm + +.macro imx7_ddr_setting + imx7d_sabresd_ddr_setting +.endm + +/* include the common plugin code here */ +#include -- cgit v1.1