summaryrefslogtreecommitdiff
path: root/board/seeed
diff options
context:
space:
mode:
authorNavin Sankar Velliangiri <navin@linumiz.com>2021-05-18 06:33:20 +0300
committerStefano Babic <sbabic@denx.de>2021-06-09 14:34:18 +0300
commita3a0bc85c0501c2374966104b8daca6c69101625 (patch)
tree2e84f239a50fbcf9fa65c80b26399c4dd09d58f2 /board/seeed
parentfe133eb192a8a55813a4dc5ec72ecf45ba74f65e (diff)
downloadu-boot-a3a0bc85c0501c2374966104b8daca6c69101625.tar.xz
imx: Add SeeedStudio NPI-IMX6ULL Support
CPU: Freescale i.MX6ULL rev1.1 792 MHz (running at 396 MHz) CPU: Industrial temperature grade (-40C to 105C) at 49C Reset cause: POR Model: Seeed NPi iMX6ULL Dev Board with NAND Board: Seeed NPi i.MX6ULL Dev Board DRAM: 512 MiB NAND: 512 MiB MMC: FSL_SDHC: 0 In: serial@2020000 Out: serial@2020000 Err: serial@2020000 Net: FEC0 Working: - Eth0 - MMC/SD - NAND - UART 1 - USB host Signed-off-by: Navin Sankar Velliangiri <navin@linumiz.com> Note: Changes in v2: * removed unnecessary space in imx6ull-seeed-npi-imx6ull-dev-board.dts file. * Used SZ_2M for CONFIG_SYS_MALLOC_LEN size allocation.
Diffstat (limited to 'board/seeed')
-rw-r--r--board/seeed/npi_imx6ull/Kconfig12
-rw-r--r--board/seeed/npi_imx6ull/MAINTAINERS9
-rw-r--r--board/seeed/npi_imx6ull/Makefile4
-rw-r--r--board/seeed/npi_imx6ull/README61
-rw-r--r--board/seeed/npi_imx6ull/npi_imx6ull.c114
-rw-r--r--board/seeed/npi_imx6ull/spl.c205
6 files changed, 405 insertions, 0 deletions
diff --git a/board/seeed/npi_imx6ull/Kconfig b/board/seeed/npi_imx6ull/Kconfig
new file mode 100644
index 0000000000..5e298299a3
--- /dev/null
+++ b/board/seeed/npi_imx6ull/Kconfig
@@ -0,0 +1,12 @@
+if TARGET_NPI_IMX6ULL
+
+config SYS_BOARD
+ default "npi_imx6ull"
+
+config SYS_VENDOR
+ default "seeed"
+
+config SYS_CONFIG_NAME
+ default "npi_imx6ull"
+
+endif
diff --git a/board/seeed/npi_imx6ull/MAINTAINERS b/board/seeed/npi_imx6ull/MAINTAINERS
new file mode 100644
index 0000000000..c6a915c79b
--- /dev/null
+++ b/board/seeed/npi_imx6ull/MAINTAINERS
@@ -0,0 +1,9 @@
+NPI_IMX6ULL BOARD
+M: Navin Sankar Velliangiri <navin@linumiz.com>
+S: Maintained
+F: arch/arm/dts/imx6ull-seeed-npi-imx6ull-dev-board.dts
+F: arch/arm/dts/imx6ull-seeed-npi-imx6ull-u-boot.dtsi
+F: arch/arm/dts/imx6ull-seeed-npi-imx6ull.dtsi
+F: board/seeed/npi-imx6ull/
+F: configs/seeed_npi_imx6ull_defconfig
+F: include/configs/npi_imx6ull.h
diff --git a/board/seeed/npi_imx6ull/Makefile b/board/seeed/npi_imx6ull/Makefile
new file mode 100644
index 0000000000..93ea413517
--- /dev/null
+++ b/board/seeed/npi_imx6ull/Makefile
@@ -0,0 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0+
+
+obj-y := npi_imx6ull.o
+obj-$(CONFIG_SPL_BUILD) += spl.o
diff --git a/board/seeed/npi_imx6ull/README b/board/seeed/npi_imx6ull/README
new file mode 100644
index 0000000000..01d218a9bc
--- /dev/null
+++ b/board/seeed/npi_imx6ull/README
@@ -0,0 +1,61 @@
+How to use U-BOOT on SeeedStudio NPI-IMX6ULL Single Board Computer
+------------------------------------------------------------------
+
+- Configure and build U-Boot for NPI-IMX6ULL:
+
+ $ export ARCH=arm
+ $ export CROSS_COMPILE=arm-none-linux-gnueabihf-
+ $ make seeed_npi_imx6ull_defconfig
+ $ make
+
+This will generate SPL and u-boot-dtb.img images.
+
+Boot from MMC/SD:
+- The SPL and u-boot-dtb.img images need to be flashed into the micro SD card:
+
+ $ sudo dd if=SPL of=/dev/mmcblk0 bs=1k seek=1; sync
+ $ sudo dd if=u-boot-dtb.img of=/dev/mmcblk0 bs=1k seek=69; sync
+
+- Boot mode settings:
+
+ Boot switch position: SW1 -> 0
+ SW2 -> 1
+ SW3 -> 0
+ SW4 -> 0
+ SW5 -> 1
+ SW6 -> 0
+ SW7 -> 0
+ SW8 -> 1
+
+Boot from NAND:
+- Boot the board using SD/MMC or Serial download and load the SPL into memory
+either from SD/MMC or TFTP.
+
+Default MTD layout is 512k(spl),1m(uboot),1m(uboot-dup),-(ubi)
+
+Flash SPL to NAND from SD/MMC,
+
+ $ ext4load mmc 0:2 $loadaddr SPL
+ $ nand erase.part spl
+ $ nandbcb init $loadaddr 0x0 $filesize
+
+Flash u-boot image to NAND from SD/MMC,
+
+ $ ext4load mmc 0:2 $loadaddr u-boot-dtb.img
+ $ nand erase.part uboot
+ $ nand write $loadaddr uboot $filesize
+
+- Boot mode settings:
+
+ Boot switch position: SW1 -> 0
+ SW2 -> 1
+ SW3 -> 1
+ SW4 -> 0
+ SW5 -> 0
+ SW6 -> 1
+ SW7 -> 0
+ SW8 -> 0
+
+- Connect the Serial cable to UART0 and the PC for the console.
+
+- Reset the board using reset button and U-Boot should boot from NAND.
diff --git a/board/seeed/npi_imx6ull/npi_imx6ull.c b/board/seeed/npi_imx6ull/npi_imx6ull.c
new file mode 100644
index 0000000000..eb9ee555c8
--- /dev/null
+++ b/board/seeed/npi_imx6ull/npi_imx6ull.c
@@ -0,0 +1,114 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2021 Linumiz
+ * Author: Navin Sankar Velliangiri <navin@linumiz.com>
+ */
+
+#include <init.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/crm_regs.h>
+#include <asm/arch/iomux.h>
+#include <asm/arch/mx6-pins.h>
+#include <asm/arch/sys_proto.h>
+#include <asm/mach-imx/iomux-v3.h>
+#include <asm/mach-imx/mxc_i2c.h>
+#include <fsl_esdhc_imx.h>
+#include <linux/bitops.h>
+#include <miiphy.h>
+#include <net.h>
+#include <netdev.h>
+#include <usb.h>
+#include <usb/ehci-ci.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+int dram_init(void)
+{
+ gd->ram_size = imx_ddr_size();
+
+ return 0;
+}
+
+#define UART_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE | \
+ PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED | \
+ PAD_CTL_DSE_40ohm | PAD_CTL_SRE_FAST | \
+ PAD_CTL_HYS)
+
+static iomux_v3_cfg_t const uart1_pads[] = {
+ MX6_PAD_UART1_TX_DATA__UART1_DCE_TX | MUX_PAD_CTRL(UART_PAD_CTRL),
+ MX6_PAD_UART1_RX_DATA__UART1_DCE_RX | MUX_PAD_CTRL(UART_PAD_CTRL),
+};
+
+static void setup_iomux_uart(void)
+{
+ imx_iomux_v3_setup_multiple_pads(uart1_pads, ARRAY_SIZE(uart1_pads));
+}
+
+int board_early_init_f(void)
+{
+ setup_iomux_uart();
+
+ return 0;
+}
+
+#ifdef CONFIG_FEC_MXC
+
+static int setup_fec(int fec_id)
+{
+ struct iomuxc *const iomuxc_regs = (struct iomuxc *)IOMUXC_BASE_ADDR;
+ int ret;
+
+ if (fec_id == 0) {
+ /*
+ * Use 50MHz anatop loopback REF_CLK1 for ENET1,
+ * clear gpr1[13], set gpr1[17].
+ */
+ clrsetbits_le32(&iomuxc_regs->gpr[1], IOMUX_GPR1_FEC1_MASK,
+ IOMUX_GPR1_FEC1_CLOCK_MUX1_SEL_MASK);
+ } else {
+ /*
+ * Use 50MHz anatop loopbak REF_CLK2 for ENET2,
+ * clear gpr1[14], set gpr1[18].
+ */
+ clrsetbits_le32(&iomuxc_regs->gpr[1], IOMUX_GPR1_FEC2_MASK,
+ IOMUX_GPR1_FEC2_CLOCK_MUX1_SEL_MASK);
+ }
+
+ ret = enable_fec_anatop_clock(fec_id, 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;
+}
+#endif
+
+int board_init(void)
+{
+ /* Address of boot parameters */
+ gd->bd->bi_boot_params = PHYS_SDRAM + 0x100;
+
+#ifdef CONFIG_FEC_MXC
+ setup_fec(CONFIG_FEC_ENET_DEV);
+#endif
+
+ return 0;
+}
+
+int checkboard(void)
+{
+ printf("Board: Seeed NPi i.MX6ULL Dev Board\n");
+
+ return 0;
+}
diff --git a/board/seeed/npi_imx6ull/spl.c b/board/seeed/npi_imx6ull/spl.c
new file mode 100644
index 0000000000..4b56f52d98
--- /dev/null
+++ b/board/seeed/npi_imx6ull/spl.c
@@ -0,0 +1,205 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2021 Linumiz
+ * Author: Navin Sankar Velliangiri <navin@linumiz.com>
+ */
+
+#include <common.h>
+#include <init.h>
+#include <spl.h>
+#include <asm/arch/clock.h>
+#include <asm/io.h>
+#include <asm/arch/mx6-ddr.h>
+#include <asm/arch/mx6-pins.h>
+#include <asm/arch/crm_regs.h>
+#include <asm/arch/sys_proto.h>
+#include <fsl_esdhc_imx.h>
+
+/* Configuration for Micron MT41K256M16TW-107 32M x 16 x 8 -> 512MiB */
+
+static struct mx6ul_iomux_grp_regs mx6_grp_ioregs = {
+ .grp_addds = 0x00000030,
+ .grp_ddrmode_ctl = 0x00020000,
+ .grp_b0ds = 0x00000030,
+ .grp_ctlds = 0x00000030,
+ .grp_b1ds = 0x00000030,
+ .grp_ddrpke = 0x00000000,
+ .grp_ddrmode = 0x00020000,
+ .grp_ddr_type = 0x000c0000,
+};
+
+static struct mx6ul_iomux_ddr_regs mx6_ddr_ioregs = {
+ .dram_dqm0 = 0x00000030,
+ .dram_dqm1 = 0x00000030,
+ .dram_ras = 0x00000030,
+ .dram_cas = 0x00000030,
+ .dram_odt0 = 0x00000030,
+ .dram_odt1 = 0x00000030,
+ .dram_sdba2 = 0x00000000,
+ .dram_sdclk_0 = 0x00000030,
+ .dram_sdqs0 = 0x00000030,
+ .dram_sdqs1 = 0x00000030,
+ .dram_reset = 0x00000030,
+};
+
+static struct mx6_mmdc_calibration mx6_mmcd_calib = {
+ .p0_mpwldectrl0 = 0x00000000,
+ .p0_mpdgctrl0 = 0x41480148,
+ .p0_mprddlctl = 0x40403E42,
+ .p0_mpwrdlctl = 0x40405852,
+};
+
+struct mx6_ddr_sysinfo ddr_sysinfo = {
+ .dsize = 0, /* Bus size = 16bit */
+ .cs_density = 32,
+ .ncs = 1,
+ .cs1_mirror = 0,
+ .rtt_wr = 1,
+ .rtt_nom = 1,
+ .walat = 1, /* Write additional latency */
+ .ralat = 5, /* Read additional latency */
+ .mif3_mode = 3, /* Command prediction working mode */
+ .bi_on = 1, /* Bank interleaving enabled */
+ .pd_fast_exit = 1,
+ .sde_to_rst = 0x10,
+ .rst_to_cke = 0x23, /* 33 cycles, 500us (JEDEC default) */
+ .ddr_type = DDR_TYPE_DDR3,
+ .refsel = 1, /* Refresh cycles at 32KHz */
+ .refr = 7, /* 8 refresh commands per refresh cycle */
+};
+
+static struct mx6_ddr3_cfg mem_ddr = {
+ .mem_speed = 1600,
+ .density = 4,
+ .width = 16,
+ .banks = 8,
+ .rowaddr = 15,
+ .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(0xFFFFFFFF, &ccm->CCGR0);
+ writel(0xFFFFFFFF, &ccm->CCGR1);
+ writel(0xFFFFFFFF, &ccm->CCGR2);
+ writel(0xFFFFFFFF, &ccm->CCGR3);
+ writel(0xFFFFFFFF, &ccm->CCGR4);
+ writel(0xFFFFFFFF, &ccm->CCGR5);
+ writel(0xFFFFFFFF, &ccm->CCGR6);
+}
+
+static void spl_dram_init(void)
+{
+ mx6ul_dram_iocfg(mem_ddr.width, &mx6_ddr_ioregs, &mx6_grp_ioregs);
+ mx6_dram_cfg(&ddr_sysinfo, &mx6_mmcd_calib, &mem_ddr);
+}
+
+#ifdef CONFIG_FSL_ESDHC_IMX
+
+#define USDHC_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE | \
+ PAD_CTL_PUS_22K_UP | PAD_CTL_SPEED_LOW | \
+ PAD_CTL_DSE_80ohm | PAD_CTL_SRE_FAST | \
+ PAD_CTL_HYS)
+
+static iomux_v3_cfg_t const usdhc1_pads[] = {
+ MX6_PAD_SD1_CLK__USDHC1_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL),
+ MX6_PAD_SD1_CMD__USDHC1_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL),
+ MX6_PAD_SD1_DATA0__USDHC1_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
+ MX6_PAD_SD1_DATA1__USDHC1_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
+ MX6_PAD_SD1_DATA2__USDHC1_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
+ MX6_PAD_SD1_DATA3__USDHC1_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
+ MX6_PAD_UART1_RTS_B__USDHC1_CD_B | MUX_PAD_CTRL(USDHC_PAD_CTRL),
+};
+
+#ifndef CONFIG_NAND_MXS
+static iomux_v3_cfg_t const usdhc2_pads[] = {
+ MX6_PAD_NAND_RE_B__USDHC2_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL),
+ MX6_PAD_NAND_WE_B__USDHC2_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL),
+ MX6_PAD_NAND_DATA00__USDHC2_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
+ MX6_PAD_NAND_DATA01__USDHC2_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
+ MX6_PAD_NAND_DATA02__USDHC2_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
+ MX6_PAD_NAND_DATA03__USDHC2_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
+ MX6_PAD_NAND_DATA04__USDHC2_DATA4 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
+ MX6_PAD_NAND_DATA05__USDHC2_DATA5 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
+ MX6_PAD_NAND_DATA06__USDHC2_DATA6 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
+ MX6_PAD_NAND_DATA07__USDHC2_DATA7 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
+};
+#endif
+
+static struct fsl_esdhc_cfg usdhc_cfg[] = {
+ {
+ .esdhc_base = USDHC1_BASE_ADDR,
+ .max_bus_width = 4,
+ },
+#ifndef CONFIG_NAND_MXS
+ {
+ .esdhc_base = USDHC2_BASE_ADDR,
+ .max_bus_width = 8,
+ },
+#endif
+};
+
+int board_mmc_getcd(struct mmc *mmc)
+{
+ return 1;
+}
+
+int board_mmc_init(struct bd_info *bis)
+{
+ int i, ret;
+
+ for (i = 0; i < CONFIG_SYS_FSL_USDHC_NUM; i++) {
+ switch (i) {
+ case 0:
+ SETUP_IOMUX_PADS(usdhc1_pads);
+ usdhc_cfg[i].sdhc_clk = mxc_get_clock(MXC_ESDHC_CLK);
+ break;
+#ifndef CONFIG_NAND_MXS
+ case 1:
+ SETUP_IOMUX_PADS(usdhc2_pads);
+ usdhc_cfg[i].sdhc_clk = mxc_get_clock(MXC_ESDHC_CLK);
+ break;
+#endif
+ default:
+ printf("Warning - USDHC%d controller not supporting\n",
+ i + 1);
+ return 0;
+ }
+
+ ret = fsl_esdhc_initialize(bis, &usdhc_cfg[i]);
+ if (ret) {
+ printf("Warning: failed to initialize mmc dev %d\n", i);
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
+#endif /* CONFIG_FSL_ESDHC_IMX */
+
+void board_init_f(ulong dummy)
+{
+ ccgr_init();
+
+ /* Setup AIPS and disable watchdog */
+ arch_cpu_init();
+
+ /* Setup iomux and fec */
+ 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();
+}