Skip to contentSkip to conversation

MX6: SPL NAND support

PATCH Superseded Tim Harvey 11 participants 56 messages Apr 28, 2014 – May 15, 2014

Subsystems (6)

v1 of 4 Superseded Latest is v4 →

lore
Share & tools
lore

Tim Harvey

author
#0 lore raw

cover MX6: SPL NAND support

This series adds some necessary framework for IMX6 SPL support. The series includes support for NAND SPL and has been tested with MMC as well. I have tested this on five differing Ventana baseboards with a variety of memory (32bit 512MB, 32bit 1024MB, 64bit 1024MB) and CPU configurations (IMX6Q, IMX6DL, IMX6S).

v2:
- use compatible linker script instead of creating new one
- remove structure passing data from SPL to u-boot
- remove dependence on mtdpart, mtdcore, nand_util, nand_ecc, nand_base and nand_bbt to bring SPL down in size. This reduced codesize by about 32k where now mxs_spl_nand is about 12k total
- adjust CONFIG_SPL_TEXT_BASE, CONFIG_SPL_STACK and CONFIG_SPL_MAX_SIZE to accomodate the IMX6SOLO/DUALLITE which have half the iRAM of the IMX6DUAL/IMX6QUAD
- move boot dev detection into imx-common/spl.c
- move macros for using pinmux array into iomux-v3.h
- remove missing/unnecessary include
- revert mtdparts change
- use get_ram_size() to detect memory
- add support for MX6SOLO and MX6DUAL
- set CS0_END for 4GB so get_ram_size() works
- updated DDR3 calibration values for ventana boards
- fixed build issue - only compile spl if doing spl build
- fixed line length issue in README
- remove CONFIG_SPL* conditions and conditionally compile instead
- removed prints for CPU type and DRAM size/width - uboot will print these l
- removed unused gw_ventana_spl.cfg
- use common read_eeprom function
- added MMC support to SPL
- added Masahiro Yamada's boot mode consolidation patch
http://patchwork.ozlabs.org/patch/341817 and rebase on top of it

Masahiro Yamada (1):
spl: consolidate arch/arm/include/asm/arch-*/spl.h

Tim Harvey (11):
SPL: NAND: remove CONFIG_SYS_NAND_PAGE_SIZE
SPL: NAND: add support for mxs nand
MX6: add common SPL configuration
MX6: add boot device support for SPL
IMX: add comments and remove unused struct fields
MX6: add structs for mmdc and ddr iomux registers
MX6: add mmdc configuration for MX6Q/MX6DL
IMX: add additional function for pinmux using an array
imx: ventana: split read_eeprom into standalone file
imx: ventana: auto-configure for IMX6Q vs IMX6DL
imx: ventana: switch to SPL

 arch/arm/cpu/arm720t/tegra-common/spl.c     |   2 +-
 arch/arm/cpu/armv7/mx6/Makefile             |   1 +
 arch/arm/cpu/armv7/mx6/ddr.c                | 469 ++++++++++++++++++++++
 arch/arm/imx-common/Makefile                |   1 +
 arch/arm/imx-common/cpu.c                   |  16 +-
 arch/arm/imx-common/iomux-v3.c              |  19 +-
 arch/arm/imx-common/spl.c                   |  79 ++++
 arch/arm/include/asm/arch-at91/spl.h        |  24 --
 arch/arm/include/asm/arch-davinci/spl.h     |  16 -
 arch/arm/include/asm/arch-mx35/spl.h        |  22 --
 arch/arm/include/asm/arch-mx5/spl.h         |  13 -
 arch/arm/include/asm/arch-mx6/mx6-ddr.h     | 231 +++++++++++
 arch/arm/include/asm/arch-tegra114/spl.h    |  22 --
 arch/arm/include/asm/arch-tegra124/spl.h    |  13 -
 arch/arm/include/asm/arch-tegra20/spl.h     |  12 -
 arch/arm/include/asm/arch-tegra30/spl.h     |  12 -
 arch/arm/include/asm/imx-common/iomux-v3.h  |  15 +
 arch/arm/include/asm/spl.h                  |  20 +
 board/denx/m53evk/m53evk.c                  |   2 +-
 board/gateworks/gw_ventana/Makefile         |   3 +-
 board/gateworks/gw_ventana/README           |  92 +++--
 board/gateworks/gw_ventana/eeprom.c         |  89 +++++
 board/gateworks/gw_ventana/gw_ventana.c     | 591 +++++++++++++++-------------
 board/gateworks/gw_ventana/gw_ventana.cfg   |  15 -
 board/gateworks/gw_ventana/gw_ventana_spl.c | 407 +++++++++++++++++++
 board/gateworks/gw_ventana/ventana_eeprom.h |  11 +
 boards.cfg                                  |   6 +-
 common/spl/spl_nand.c                       |   2 +-
 drivers/mtd/nand/Makefile                   |   1 +
 drivers/mtd/nand/mxs_nand_spl.c             | 239 +++++++++++
 include/configs/gw_ventana.h                |  11 +
 include/configs/imx6_spl.h                  |  71 ++++
 32 files changed, 2050 insertions(+), 477 deletions(-)
 create mode 100644 arch/arm/cpu/armv7/mx6/ddr.c
 create mode 100644 arch/arm/imx-common/spl.c
 delete mode 100644 arch/arm/include/asm/arch-at91/spl.h
 delete mode 100644 arch/arm/include/asm/arch-davinci/spl.h
 delete mode 100644 arch/arm/include/asm/arch-mx35/spl.h
 delete mode 100644 arch/arm/include/asm/arch-mx5/spl.h
 delete mode 100644 arch/arm/include/asm/arch-tegra114/spl.h
 delete mode 100644 arch/arm/include/asm/arch-tegra124/spl.h
 delete mode 100644 arch/arm/include/asm/arch-tegra20/spl.h
 delete mode 100644 arch/arm/include/asm/arch-tegra30/spl.h
 create mode 100644 board/gateworks/gw_ventana/eeprom.c
 create mode 100644 board/gateworks/gw_ventana/gw_ventana_spl.c
 create mode 100644 drivers/mtd/nand/mxs_nand_spl.c
 create mode 100644 include/configs/imx6_spl.h
Signature · 1 line
1.8.3.2
author
#1 lore raw

PATCH 1/12 SPL: NAND: remove CONFIG_SYS_NAND_PAGE_SIZE

We only need to read in the size of struct image_header and thus don't need to know the page size of the nand device.

---
v2:
- cc Scott Wood <[email protected]> on this
- Acked-by: Stefano Babic <[email protected]>
- Acked-by: Scott Wood <[email protected]>

---
 common/spl/spl_nand.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
common/spl/spl_nand.c +1 -1
index 9da0218..062461b 100644
@@ -76,7 +76,7 @@ void spl_nand_load_image(void)
 #endif
 	/* Load u-boot */
 	nand_spl_load_image(CONFIG_SYS_NAND_U_BOOT_OFFS,
-		CONFIG_SYS_NAND_PAGE_SIZE, (void *)header);
+		sizeof(*header), (void *)header);
 	spl_parse_image_header(header);
 	nand_spl_load_image(CONFIG_SYS_NAND_U_BOOT_OFFS,
 		spl_image.size, (void *)spl_image.load_addr);
Signature · 1 line
1.8.3.2
author
#2 lore raw

PATCH 2/12 SPL: NAND: add support for mxs nand

In reply to Tim Harvey

This utilizes existing mxs_nand support layer to provide a method to load an image off nand for SPL. The flash device will be detected in order to support multiple flash devices instead of having layout hard coded at build time.

---
v2:
- remove dependence on mtdpart, mtdcore, nand_util, nand_ecc, nand_base and nand_bbt to bring SPL down in size. This reduced codesize by about 32k where now mxs_spl_nand is about 12k total.

---
 drivers/mtd/nand/Makefile       |   1 +
 drivers/mtd/nand/mxs_nand_spl.c | 239 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 240 insertions(+)
 create mode 100644 drivers/mtd/nand/mxs_nand_spl.c
drivers/mtd/nand/Makefile +1 -0
index 02b149c..de5b461 100644
@@ -65,5 +65,6 @@ else  # minimal SPL drivers
 obj-$(CONFIG_NAND_FSL_ELBC) += fsl_elbc_spl.o
 obj-$(CONFIG_NAND_FSL_IFC) += fsl_ifc_spl.o
 obj-$(CONFIG_NAND_MXC) += mxc_nand_spl.o
+obj-$(CONFIG_NAND_MXS) += mxs_nand_spl.o mxs_nand.o
 
 endif # drivers
drivers/mtd/nand/mxs_nand_spl.c new file +239 -0

239 lines not on this page · raw message

Signature · 1 line
1.8.3.2
#3 lore raw

PATCH 2/12 SPL: NAND: add support for mxs nand

Quoted 5 lines · Tim Harvey
drivers/mtd/nand/mxs_nand_spl.c new file +5 -0
+static void mxs_nand_command(struct mtd_info *mtd, unsigned int command,
+			     int column, int page_addr)
+{
+	register struct nand_chip *chip = mtd->priv;
+	int ctrl = NAND_NCE | NAND_CTRL_CLE | NAND_CTRL_CHANGE;

drivers/mtd/nand/mxs_nand_spl.c line 28

Quoted 10 lines
drivers/mtd/nand/mxs_nand_spl.c new file +10 -0
+	u32 timeo, time_start;
+
+	/* write out the command to the device */
+	chip->cmd_ctrl(mtd, command, ctrl);
+
+	/* Address cycle, when necessary */
+	ctrl = NAND_NCE | NAND_CTRL_ALE | NAND_CTRL_CHANGE;
+	/* Serially input address */
+	if (column != -1) {
+		ctrl = NAND_CTRL_ALE | NAND_CTRL_CHANGE;

What happened to NAND_NCE?

It looks like the cmd_ctrl in nand_mxs.c doesn't care about NAND_MCE at all, so there's no functional impact, but either use it consistently or don't use it at all.

drivers/mtd/nand/mxs_nand_spl.c line 32

Quoted 4 lines
drivers/mtd/nand/mxs_nand_spl.c new file +4 -0
+		chip->cmd_ctrl(mtd, column, ctrl);
+		ctrl &= ~NAND_CTRL_CHANGE;
+		chip->cmd_ctrl(mtd, column >> 8, ctrl);
+	}

Why not pass the ctrl flags directly to cmd_ctrl as you do in most of the rest of the function? nand_mxs.c doesn't even look at NAND_CTRL_CHANGE.

drivers/mtd/nand/mxs_nand_spl.c line 184

Quoted 3 lines
drivers/mtd/nand/mxs_nand_spl.c new file +3 -0
+int nand_spl_load_image(uint32_t offs, unsigned int size, void *buf)
+{
+	register struct nand_chip *chip;

Why "register"?

drivers/mtd/nand/mxs_nand_spl.c line 219

Quoted 10 lines
drivers/mtd/nand/mxs_nand_spl.c new file +10 -0
+		if (!(page % nand_page_per_block)) {
+			/*
+			 * Yes, new block. See if this block is good. If not,
+			 * loop until we find a good block.
+			 */
+			while (is_badblock(&mtd, offs, 1)) {
+				page = page + nand_page_per_block;
+				/* Check i we've reached the end of flash. */
+				if (page >= mtd.size >> chip->page_shift)
+					return -1;

Why -1 rather than a real error value?

-Scott

author
#4 lore raw

PATCH 2/12 SPL: NAND: add support for mxs nand

On Fri, May 2, 2014 at 1:56 PM, Scott Wood <[email protected]> wrote:

Hi Scott,

Quoted 23 lines · Tim Harvey
Quoted 5 lines
drivers/mtd/nand/mxs_nand_spl.c new file +5 -0
+static void mxs_nand_command(struct mtd_info *mtd, unsigned int command,
+                          int column, int page_addr)
+{
+     register struct nand_chip *chip = mtd->priv;
+     int ctrl = NAND_NCE | NAND_CTRL_CLE | NAND_CTRL_CHANGE;

drivers/mtd/nand/mxs_nand_spl.c line 28

Quoted 10 lines
drivers/mtd/nand/mxs_nand_spl.c new file +10 -0
+     u32 timeo, time_start;
+
+     /* write out the command to the device */
+     chip->cmd_ctrl(mtd, command, ctrl);
+
+     /* Address cycle, when necessary */
+     ctrl = NAND_NCE | NAND_CTRL_ALE | NAND_CTRL_CHANGE;
+     /* Serially input address */
+     if (column != -1) {
+             ctrl = NAND_CTRL_ALE | NAND_CTRL_CHANGE;

What happened to NAND_NCE?

It looks like the cmd_ctrl in nand_mxs.c doesn't care about NAND_MCE at all, so there's no functional impact, but either use it consistently or don't use it at all.

Quoted 7 lines

drivers/mtd/nand/mxs_nand_spl.c line 32

Quoted 4 lines
drivers/mtd/nand/mxs_nand_spl.c new file +4 -0
+             chip->cmd_ctrl(mtd, column, ctrl);
+             ctrl &= ~NAND_CTRL_CHANGE;
+             chip->cmd_ctrl(mtd, column >> 8, ctrl);
+     }

Why not pass the ctrl flags directly to cmd_ctrl as you do in most of the rest of the function? nand_mxs.c doesn't even look at NAND_CTRL_CHANGE.

I'll simplify using only what nand_mxs.c pays attention to (NAND_ALE, NAND_CLE), remove the ctrl var and repost

Quoted 6 lines

drivers/mtd/nand/mxs_nand_spl.c line 184

Quoted 4 lines
drivers/mtd/nand/mxs_nand_spl.c new file +3 -0
+int nand_spl_load_image(uint32_t offs, unsigned int size, void *buf)
+{
+     register struct nand_chip *chip;

Why "register"?

cut-n-paste code from nand_base.c - will remove

Quoted 12 lines

drivers/mtd/nand/mxs_nand_spl.c line 219

Quoted 11 lines
drivers/mtd/nand/mxs_nand_spl.c new file +10 -0
+             if (!(page % nand_page_per_block)) {
+                     /*
+                      * Yes, new block. See if this block is good. If not,
+                      * loop until we find a good block.
+                      */
+                     while (is_badblock(&mtd, offs, 1)) {
+                             page = page + nand_page_per_block;
+                             /* Check i we've reached the end of flash. */
+                             if (page >= mtd.size >> chip->page_shift)
+                                     return -1;
Quoted 1 line

Why -1 rather than a real error value?

probably from the example I used from drivers/mtd/nand/mxc_nand_spl.c. The calling functions don't appear to do any error checking, but I'll replace it with -ENOMEM and -ENODEV if mxs_nand_init() fails.

Thanks for the review!

Tim

Quoted 4 lines

-Scott

author
#5 lore raw

PATCH 3/12 MX6: add common SPL configuration

In reply to Tim Harvey

Add a common header which can hopefully be shared amon imx6 SPL users

---
v2:
- adjust CONFIG_SPL_TEXT_BASE, CONFIG_SPL_STACK and CONFIG_SPL_MAX_SIZE to accomodate the IMX6SOLO/DUALLITE which have half the iRAM of the IMX6DUAL/IMX6QUAD

---
 include/configs/imx6_spl.h | 71 ++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 71 insertions(+)
 create mode 100644 include/configs/imx6_spl.h
include/configs/imx6_spl.h new file +71 -0
new file mode 100644
index 0000000..20078cc
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2014 Gateworks Corporation
+ * Author: Tim Harvey <[email protected]>
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+#ifndef __IMX6_SPL_CONFIG_H
+#define __IMX6_SPL_CONFIG_H
+
+#ifdef CONFIG_SPL
+
+#define CONFIG_SPL_FRAMEWORK
+
+/*
+ * see Figure 8-3 in IMX6DQ/IMX6SDL Reference manuals:
+ *  - IMX6 OCRAM (IRAM) is from 0x00907000 to 0x0091FFFF (IMX6SLD)
+ *  - IMX6DQ has 2x IRAM of IMX6SLD but we intend to support IMX6SLD as well
+ *  - BOOT ROM stack is at 0x0091FFB8
+ *  - if icache/dcache is enabled (eFuse/strapping controlled) then the
+ *    IMX BOOT ROM will setup MMU table at 0x00918000, therefore we need to
+ *    fit between 0x00907000 and 0x00918000.
+ *  - Additionally the BOOT ROM loads what they consider the firmware image
+ *    which consists of a 4K header in front of us that contains the IVT, DCD
+ *    and some padding thus 'our' max size is really 0x00908000 - 0x00918000
+ *    or 64KB
+ */
+#define CONFIG_SPL_LDSCRIPT	"arch/arm/cpu/armv7/omap-common/u-boot-spl.lds"
+#define CONFIG_SPL_TEXT_BASE		0x00908000
+#define CONFIG_SPL_MAX_SIZE		(64 * 1024)
+#define CONFIG_SPL_START_S_PATH		"arch/arm/cpu/armv7"
+#define CONFIG_SPL_STACK		0x0091FFB8
+#define CONFIG_SPL_LIBCOMMON_SUPPORT
+#define CONFIG_SPL_LIBGENERIC_SUPPORT
+#define CONFIG_SPL_SERIAL_SUPPORT
+#define CONFIG_SPL_I2C_SUPPORT
+#define CONFIG_SPL_GPIO_SUPPORT
+
+/* NAND support */
+#if defined(CONFIG_SPL_NAND_SUPPORT)
+#define CONFIG_SPL_NAND_MXS
+#define CONFIG_SPL_DMA_SUPPORT
+#endif
+
+/* MMC support */
+#if defined(CONFIG_SPL_MMC_SUPPORT)
+#define CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR	138 /* offset 69KB */
+#define CONFIG_SYS_U_BOOT_MAX_SIZE_SECTORS	800 /* 400 KB */
+#define CONFIG_SYS_MMC_SD_FAT_BOOT_PARTITION	1
+#define CONFIG_SYS_MONITOR_LEN  (CONFIG_SYS_U_BOOT_MAX_SIZE_SECTORS/2*1024)
+#endif
+
+/* SATA support */
+#if defined(CONFIG_SPL_SATA_SUPPORT)
+#define CONFIG_SPL_SATA_BOOT_DEVICE		0
+#define CONFIG_SYS_SATA_FAT_BOOT_PARTITION	1
+#endif
+
+/* Define the payload for FAT/EXT support */
+#if defined(CONFIG_SPL_FAT_SUPPORT) || defined(CONFIG_SPL_EXT_SUPPORT)
+#define CONFIG_SPL_FAT_LOAD_PAYLOAD_NAME  "u-boot.img"
+#define CONFIG_SPL_LIBDISK_SUPPORT
+#endif
+
+#define CONFIG_SPL_BSS_START_ADDR	0x18200000
+#define CONFIG_SPL_BSS_MAX_SIZE		0x100000	/* 1 MB */
+#define CONFIG_SYS_SPL_MALLOC_START	0x18300000
+#define CONFIG_SYS_SPL_MALLOC_SIZE	0x3200000	/* 50 MB */
+#define CONFIG_SYS_TEXT_BASE		0x17800000
+#endif
+
+#endif
Signature · 1 line
1.8.3.2
#6 lore raw

PATCH 3/12 MX6: add common SPL configuration

Hi Tim,

Quoted 24 lines · Tim Harvey

Add a common header which can hopefully be shared amon imx6 SPL users

---
v2:
- adjust CONFIG_SPL_TEXT_BASE, CONFIG_SPL_STACK and CONFIG_SPL_MAX_SIZE to accomodate the IMX6SOLO/DUALLITE which have half the iRAM of the IMX6DUAL/IMX6QUAD

---
  include/configs/imx6_spl.h | 71 ++++++++++++++++++++++++++++++++++++++++++++++
  1 file changed, 71 insertions(+)

create mode 100644 include/configs/imx6_spl.h

include/configs/imx6_spl.h new file +5 -0
new file mode 100644
index 0000000..20078cc
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2014 Gateworks Corporation
+ * Author: Tim Harvey <[email protected]>
+ *
+ * SPDX-License-Identifier:     GPL-2.0+

include/configs/imx6_spl.h line 15

Quoted 10 lines
include/configs/imx6_spl.h new file +10 -0
+ */
+#ifndef __IMX6_SPL_CONFIG_H
+#define __IMX6_SPL_CONFIG_H
+
+#ifdef CONFIG_SPL
+
+#define CONFIG_SPL_FRAMEWORK
+
+/*
+ * see Figure 8-3 in IMX6DQ/IMX6SDL Reference manuals:

s/IMX6SLD/IMX6SDL/g

include/configs/imx6_spl.h line 17

Quoted 2 lines
include/configs/imx6_spl.h new file +2 -0
+ *  - IMX6 OCRAM (IRAM) is from 0x00907000 to 0x0091FFFF (IMX6SLD)
+ *  - IMX6DQ has 2x IRAM of IMX6SLD but we intend to support IMX6SLD as well

... I was about to complain about the use of IMX6SLD (the nomenclature i.MX6DL/S seems more common), but the RM __is__ named SDL...

Regards,

Eric

#7 lore raw

PATCH 3/12 MX6: add common SPL configuration

Hi,

Quoted 40 lines · Eric Nelson

Hi Tim,

Quoted 24 lines · Tim Harvey

Add a common header which can hopefully be shared amon imx6 SPL users

---
v2:
- adjust CONFIG_SPL_TEXT_BASE, CONFIG_SPL_STACK and CONFIG_SPL_MAX_SIZE to accomodate the IMX6SOLO/DUALLITE which have half the iRAM of the IMX6DUAL/IMX6QUAD

---
  include/configs/imx6_spl.h | 71 ++++++++++++++++++++++++++++++++++++++++++++++
  1 file changed, 71 insertions(+)

create mode 100644 include/configs/imx6_spl.h

include/configs/imx6_spl.h new file +5 -0
new file mode 100644
index 0000000..20078cc
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2014 Gateworks Corporation
+ * Author: Tim Harvey <[email protected]>
+ *
+ * SPDX-License-Identifier:     GPL-2.0+

include/configs/imx6_spl.h line 15

Quoted 10 lines
include/configs/imx6_spl.h new file +10 -0
+ */
+#ifndef __IMX6_SPL_CONFIG_H
+#define __IMX6_SPL_CONFIG_H
+
+#ifdef CONFIG_SPL
+
+#define CONFIG_SPL_FRAMEWORK
+
+/*
+ * see Figure 8-3 in IMX6DQ/IMX6SDL Reference manuals:

s/IMX6SLD/IMX6SDL/g

Quoted 5 lines

include/configs/imx6_spl.h line 17

Quoted 2 lines
include/configs/imx6_spl.h new file +2 -0
+ *  - IMX6 OCRAM (IRAM) is from 0x00907000 to 0x0091FFFF (IMX6SLD)
+ *  - IMX6DQ has 2x IRAM of IMX6SLD but we intend to support IMX6SLD as well

... I was about to complain about the use of IMX6SLD (the nomenclature i.MX6DL/S seems more common), but the RM __is__ named SDL...

SDL stands for Solo/Dual Lite, so SLD is plain wrong... (Solo Lite and Dual are so different...)

Signature · 2 lines
Regards,
Igor.
author
#8 lore raw

PATCH 3/12 MX6: add common SPL configuration

Quoted 49 lines · Igor Grinberg

Hi,

Quoted 40 lines · Eric Nelson

Hi Tim,

Quoted 24 lines · Tim Harvey

Add a common header which can hopefully be shared amon imx6 SPL users

---
v2:
- adjust CONFIG_SPL_TEXT_BASE, CONFIG_SPL_STACK and CONFIG_SPL_MAX_SIZE to accomodate the IMX6SOLO/DUALLITE which have half the iRAM of the IMX6DUAL/IMX6QUAD

---
  include/configs/imx6_spl.h | 71 ++++++++++++++++++++++++++++++++++++++++++++++
  1 file changed, 71 insertions(+)

create mode 100644 include/configs/imx6_spl.h

include/configs/imx6_spl.h new file +5 -0
new file mode 100644
index 0000000..20078cc
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2014 Gateworks Corporation
+ * Author: Tim Harvey <[email protected]>
+ *
+ * SPDX-License-Identifier:     GPL-2.0+

include/configs/imx6_spl.h line 15

Quoted 10 lines
include/configs/imx6_spl.h new file +10 -0
+ */
+#ifndef __IMX6_SPL_CONFIG_H
+#define __IMX6_SPL_CONFIG_H
+
+#ifdef CONFIG_SPL
+
+#define CONFIG_SPL_FRAMEWORK
+
+/*
+ * see Figure 8-3 in IMX6DQ/IMX6SDL Reference manuals:

s/IMX6SLD/IMX6SDL/g

Quoted 5 lines

include/configs/imx6_spl.h line 17

Quoted 2 lines
include/configs/imx6_spl.h new file +2 -0
+ *  - IMX6 OCRAM (IRAM) is from 0x00907000 to 0x0091FFFF (IMX6SLD)
+ *  - IMX6DQ has 2x IRAM of IMX6SLD but we intend to support IMX6SLD as well

... I was about to complain about the use of IMX6SLD (the nomenclature i.MX6DL/S seems more common), but the RM __is__ named SDL...

Quoted 7 lines

SDL stands for Solo/Dual Lite, so SLD is plain wrong... (Solo Lite and Dual are so different...)

--
Regards,
Igor.

Igor / Eric,

Yes this was definitely a typo - no idea how I kept making the same typo over and over again... late nights!

I'll fix this for the next revision and refer to the CPU types as 'IMX6DQ' and 'IMX6SDL'.

Please let me know if there is anything else you see that needs to be discussed.

Tim

#9 lore raw

PATCH 3/12 MX6: add common SPL configuration

In reply to Tim Harvey

Hi Tim,

Quoted 81 lines · Tim Harvey

Add a common header which can hopefully be shared amon imx6 SPL users

---
v2:
- adjust CONFIG_SPL_TEXT_BASE, CONFIG_SPL_STACK and CONFIG_SPL_MAX_SIZE to accomodate the IMX6SOLO/DUALLITE which have half the iRAM of the IMX6DUAL/IMX6QUAD

---
 include/configs/imx6_spl.h | 71 ++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 71 insertions(+)
 create mode 100644 include/configs/imx6_spl.h
include/configs/imx6_spl.h new file +61 -0
new file mode 100644
index 0000000..20078cc
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2014 Gateworks Corporation
+ * Author: Tim Harvey <[email protected]>
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+#ifndef __IMX6_SPL_CONFIG_H
+#define __IMX6_SPL_CONFIG_H
+
+#ifdef CONFIG_SPL
+
+#define CONFIG_SPL_FRAMEWORK
+
+/*
+ * see Figure 8-3 in IMX6DQ/IMX6SDL Reference manuals:
+ *  - IMX6 OCRAM (IRAM) is from 0x00907000 to 0x0091FFFF (IMX6SLD)
+ *  - IMX6DQ has 2x IRAM of IMX6SLD but we intend to support IMX6SLD as well
+ *  - BOOT ROM stack is at 0x0091FFB8
+ *  - if icache/dcache is enabled (eFuse/strapping controlled) then the
+ *    IMX BOOT ROM will setup MMU table at 0x00918000, therefore we need to
+ *    fit between 0x00907000 and 0x00918000.
+ *  - Additionally the BOOT ROM loads what they consider the firmware image
+ *    which consists of a 4K header in front of us that contains the IVT, DCD
+ *    and some padding thus 'our' max size is really 0x00908000 - 0x00918000
+ *    or 64KB
+ */
+#define CONFIG_SPL_LDSCRIPT	"arch/arm/cpu/armv7/omap-common/u-boot-spl.lds"
+#define CONFIG_SPL_TEXT_BASE		0x00908000
+#define CONFIG_SPL_MAX_SIZE		(64 * 1024)
+#define CONFIG_SPL_START_S_PATH		"arch/arm/cpu/armv7"
+#define CONFIG_SPL_STACK		0x0091FFB8
+#define CONFIG_SPL_LIBCOMMON_SUPPORT
+#define CONFIG_SPL_LIBGENERIC_SUPPORT
+#define CONFIG_SPL_SERIAL_SUPPORT
+#define CONFIG_SPL_I2C_SUPPORT
+#define CONFIG_SPL_GPIO_SUPPORT
+
+/* NAND support */
+#if defined(CONFIG_SPL_NAND_SUPPORT)
+#define CONFIG_SPL_NAND_MXS
+#define CONFIG_SPL_DMA_SUPPORT
+#endif
+
+/* MMC support */
+#if defined(CONFIG_SPL_MMC_SUPPORT)
+#define CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR	138 /* offset 69KB */
+#define CONFIG_SYS_U_BOOT_MAX_SIZE_SECTORS	800 /* 400 KB */
+#define CONFIG_SYS_MMC_SD_FAT_BOOT_PARTITION	1
+#define CONFIG_SYS_MONITOR_LEN  (CONFIG_SYS_U_BOOT_MAX_SIZE_SECTORS/2*1024)
+#endif
+
+/* SATA support */
+#if defined(CONFIG_SPL_SATA_SUPPORT)
+#define CONFIG_SPL_SATA_BOOT_DEVICE		0
+#define CONFIG_SYS_SATA_FAT_BOOT_PARTITION	1
+#endif
+
+/* Define the payload for FAT/EXT support */
+#if defined(CONFIG_SPL_FAT_SUPPORT) || defined(CONFIG_SPL_EXT_SUPPORT)
+#define CONFIG_SPL_FAT_LOAD_PAYLOAD_NAME  "u-boot.img"
+#define CONFIG_SPL_LIBDISK_SUPPORT

include/configs/imx6_spl.h line 71

Quoted 10 lines
include/configs/imx6_spl.h new file +10 -0
+#endif
+
+#define CONFIG_SPL_BSS_START_ADDR	0x18200000
+#define CONFIG_SPL_BSS_MAX_SIZE		0x100000	/* 1 MB */
+#define CONFIG_SYS_SPL_MALLOC_START	0x18300000
+#define CONFIG_SYS_SPL_MALLOC_SIZE	0x3200000	/* 50 MB */
+#define CONFIG_SYS_TEXT_BASE		0x17800000
+#endif
+
+#endif

I generally agree with the idea having a common setup - this simplifies porting of new boards to SPL !

Apart the small typos found by Eric/Igor:

Best regards,
Stefano Babic

Signature · 5 lines
=====================================================================
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: +49-8142-66989-53 Fax: +49-8142-66989-80 Email: sbabic at denx.de
=====================================================================
#10 lore raw

PATCH 3/12 MX6: add common SPL configuration

In reply to Tim Harvey
Quoted 8 lines · Tim Harvey

Add a common header which can hopefully be shared amon imx6 SPL users

---
v2:
- adjust CONFIG_SPL_TEXT_BASE, CONFIG_SPL_STACK and CONFIG_SPL_MAX_SIZE to accomodate the IMX6SOLO/DUALLITE which have half the iRAM of the IMX6DUAL/IMX6QUAD

Aside from the typos,

--
Regards,
Nikita Kiryanov

author
#11 lore raw

PATCH 4/12 spl: consolidate arch/arm/include/asm/arch-*/spl.h

In reply to Tim Harvey

From: Masahiro Yamada <[email protected]>

arch/arm/include/asm/spl.h requires all SoCs to have arch/arm/include/asm/arch-*/spl.h.

But many of them just define BOOT_DEVICE_* macros.

Those macros are used in the "switch (boot_device) { ... }" statement in common/spl/spl.c.

So they should not be archtecture specific, but be described as a simpile enumeration.

This commit merges most of arch/arm/include/asm/arch-*/spl.h into arch/arm/include/asm/spl.h.

With a little more effort, arch-zynq/spl.h and arch-socfpga/spl.h will be merged, while I am not sure about OMAP and Exynos.

---
 arch/arm/cpu/arm720t/tegra-common/spl.c  |  2 +-
 arch/arm/include/asm/arch-at91/spl.h     | 24 ------------------------
 arch/arm/include/asm/arch-davinci/spl.h  | 16 ----------------
 arch/arm/include/asm/arch-mx35/spl.h     | 22 ----------------------
 arch/arm/include/asm/arch-mx5/spl.h      | 13 -------------
 arch/arm/include/asm/arch-tegra114/spl.h | 22 ----------------------
 arch/arm/include/asm/arch-tegra124/spl.h | 13 -------------
 arch/arm/include/asm/arch-tegra20/spl.h  | 12 ------------
 arch/arm/include/asm/arch-tegra30/spl.h  | 12 ------------
 arch/arm/include/asm/spl.h               | 20 ++++++++++++++++++++
 board/denx/m53evk/m53evk.c               |  2 +-
 11 files changed, 22 insertions(+), 136 deletions(-)
 delete mode 100644 arch/arm/include/asm/arch-at91/spl.h
 delete mode 100644 arch/arm/include/asm/arch-davinci/spl.h
 delete mode 100644 arch/arm/include/asm/arch-mx35/spl.h
 delete mode 100644 arch/arm/include/asm/arch-mx5/spl.h
 delete mode 100644 arch/arm/include/asm/arch-tegra114/spl.h
 delete mode 100644 arch/arm/include/asm/arch-tegra124/spl.h
 delete mode 100644 arch/arm/include/asm/arch-tegra20/spl.h
 delete mode 100644 arch/arm/include/asm/arch-tegra30/spl.h
arch/arm/cpu/arm720t/tegra-common/spl.c +1 -1
index 5171a8f..8147806 100644
@@ -14,7 +14,7 @@
 #include <asm/arch/pinmux.h>
 #include <asm/arch/tegra.h>
 #include <asm/arch-tegra/board.h>
-#include <asm/arch/spl.h>
+#include <asm/spl.h>
 #include "cpu.h"
 
 void spl_board_init(void)
arch/arm/include/asm/arch-at91/spl.h deleted +0 -24
deleted file mode 100644
index d8a87da..0000000
@@ -1,24 +0,0 @@
-/*
- * Copyright (C) 2013 Atmel Corporation
- *		      Bo Shen <[email protected]>
- *
- * SPDX-License-Identifier:	GPL-2.0+
- */
-
-#ifndef	_ASM_ARCH_SPL_H_
-#define	_ASM_ARCH_SPL_H_
-
-enum {
-	BOOT_DEVICE_NONE,
-#ifdef CONFIG_SYS_USE_MMC
-	BOOT_DEVICE_MMC1,
-	BOOT_DEVICE_MMC2,
-	BOOT_DEVICE_MMC2_2,
-#elif CONFIG_SYS_USE_NANDFLASH
-	BOOT_DEVICE_NAND,
-#elif CONFIG_SYS_USE_SERIALFLASH
-	BOOT_DEVICE_SPI,
-#endif
-};
-
-#endif
arch/arm/include/asm/arch-davinci/spl.h deleted +0 -16
deleted file mode 100644
index 5afe0d4..0000000
@@ -1,16 +0,0 @@
-/*
- * (C) Copyright 2012
- * Texas Instruments, <www.ti.com>
- *
- * SPDX-License-Identifier:	GPL-2.0+
- */
-#ifndef	_ASM_ARCH_SPL_H_
-#define	_ASM_ARCH_SPL_H_
-
-#define BOOT_DEVICE_NAND	1
-#define BOOT_DEVICE_SPI		2
-#define BOOT_DEVICE_MMC1	3
-#define BOOT_DEVICE_MMC2	4	/* dummy */
-#define BOOT_DEVICE_MMC2_2	5	/* dummy */
-
-#endif
arch/arm/include/asm/arch-mx35/spl.h deleted +0 -22
deleted file mode 100644
index d0efec2..0000000
@@ -1,22 +0,0 @@
-/*
- * (C) Copyright 2012
- * Texas Instruments, <www.ti.com>
- *
- * SPDX-License-Identifier:	GPL-2.0+
- */
-#ifndef	_ASM_ARCH_SPL_H_
-#define	_ASM_ARCH_SPL_H_
-
-#define BOOT_DEVICE_NONE	0
-#define BOOT_DEVICE_XIP		1
-#define BOOT_DEVICE_XIPWAIT	2
-#define BOOT_DEVICE_NAND	3
-#define BOOT_DEVICE_ONENAND	4
-#define BOOT_DEVICE_MMC1	5
-#define BOOT_DEVICE_MMC2	6
-#define BOOT_DEVICE_MMC2_2	7
-#define BOOT_DEVICE_NOR		8
-#define BOOT_DEVICE_I2C		9
-#define BOOT_DEVICE_SPI		10
-
-#endif
arch/arm/include/asm/arch-mx5/spl.h deleted +0 -13
deleted file mode 100644
index 20c6cae..0000000
@@ -1,13 +0,0 @@
-/*
- * Copyright (C) 2013 Marek Vasut <[email protected]>
- *
- * SPDX-License-Identifier:	GPL-2.0+
- */
-
-#ifndef __ASM_ARCH_SPL_H__
-#define __ASM_ARCH_SPL_H__
-
-#define BOOT_DEVICE_NONE	0
-#define BOOT_DEVICE_NAND	1
-
-#endif	/* __ASM_ARCH_SPL_H__ */
arch/arm/include/asm/arch-tegra114/spl.h deleted +0 -22
deleted file mode 100644
index ebb16fe..0000000
@@ -1,22 +0,0 @@
-/*
- * Copyright (c) 2010-2013, NVIDIA CORPORATION.  All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef	_ASM_ARCH_SPL_H_
-#define	_ASM_ARCH_SPL_H_
-
-#define BOOT_DEVICE_RAM         1
-
-#endif
arch/arm/include/asm/arch-tegra124/spl.h deleted +0 -13
deleted file mode 100644
index e266395..0000000
@@ -1,13 +0,0 @@
-/*
- * (C) Copyright 2010-2013
- * NVIDIA Corporation <www.nvidia.com>
- *
- * SPDX-License-Identifier:     GPL-2.0+
- */
-
-#ifndef _ASM_ARCH_SPL_H_
-#define _ASM_ARCH_SPL_H_
-
-#define BOOT_DEVICE_RAM 1
-
-#endif /* _ASM_ARCH_SPL_H_ */
arch/arm/include/asm/arch-tegra20/spl.h deleted +0 -12
deleted file mode 100644
index 8953b00..0000000
@@ -1,12 +0,0 @@
-/*
- * (C) Copyright 2012
- * NVIDIA Corporation <www.nvidia.com>
- *
- * SPDX-License-Identifier:	GPL-2.0+
- */
-#ifndef	_ASM_ARCH_SPL_H_
-#define	_ASM_ARCH_SPL_H_
-
-#define BOOT_DEVICE_RAM         1
-
-#endif
arch/arm/include/asm/arch-tegra30/spl.h deleted +0 -12
deleted file mode 100644
index 8953b00..0000000
@@ -1,12 +0,0 @@
-/*
- * (C) Copyright 2012
- * NVIDIA Corporation <www.nvidia.com>
- *
- * SPDX-License-Identifier:	GPL-2.0+
- */
-#ifndef	_ASM_ARCH_SPL_H_
-#define	_ASM_ARCH_SPL_H_
-
-#define BOOT_DEVICE_RAM         1
-
-#endif
arch/arm/include/asm/spl.h +20 -0
index 90e5a9d..18a319d 100644
@@ -7,9 +7,29 @@
 #ifndef	_ASM_SPL_H_
 #define	_ASM_SPL_H_
 
+#if defined(CONFIG_OMAP) || defined(CONFIG_SOCFPGA) || defined(CONFIG_ZYNQ) \
+	|| defined(CONFIG_EXYNOS4) || defined(CONFIG_EXYNOS5) \
+	|| defined(CONFIG_EXYNOS4210)
 /* Platform-specific defines */
 #include <asm/arch/spl.h>
 
+#else
+enum {
+	BOOT_DEVICE_RAM,
+	BOOT_DEVICE_MMC1,
+	BOOT_DEVICE_MMC2,
+	BOOT_DEVICE_MMC2_2,
+	BOOT_DEVICE_NAND,
+	BOOT_DEVICE_ONENAND,
+	BOOT_DEVICE_NOR,
+	BOOT_DEVICE_UART,
+	BOOT_DEVICE_SPI,
+	BOOT_DEVICE_SATA,
+	BOOT_DEVICE_I2C,
+	BOOT_DEVICE_NONE
+};
+#endif
+
 /* Linker symbols. */
 extern char __bss_start[], __bss_end[];
 
board/denx/m53evk/m53evk.c +1 -1
index 74f9501..5dd6cdd 100644
@@ -14,7 +14,7 @@
 #include <asm/arch/clock.h>
 #include <asm/arch/iomux-mx53.h>
 #include <asm/imx-common/mx5_video.h>
-#include <asm/arch/spl.h>
+#include <asm/spl.h>
 #include <asm/errno.h>
 #include <netdev.h>
 #include <i2c.h>
Signature · 1 line
1.8.3.2
#12 lore raw

PATCH 4/12 spl: consolidate arch/arm/include/asm/arch-*/spl.h

Hi Tim,
Cc : Stefano, Tom

Quoted 28 lines · On Mon, 28 Apr 2014 13:17:30 -0700 Tim Harvey <[email protected]> wrote:

From: Masahiro Yamada <[email protected]>

arch/arm/include/asm/spl.h requires all SoCs to have arch/arm/include/asm/arch-*/spl.h.

But many of them just define BOOT_DEVICE_* macros.

Those macros are used in the "switch (boot_device) { ... }" statement in common/spl/spl.c.

So they should not be archtecture specific, but be described as a simpile enumeration.

This commit merges most of arch/arm/include/asm/arch-*/spl.h into arch/arm/include/asm/spl.h.

With a little more effort, arch-zynq/spl.h and arch-socfpga/spl.h will be merged, while I am not sure about OMAP and Exynos.

Cc Tom Rini <[email protected]>
Cc Michal Simek <[email protected]>
Cc Andreas Biesmann <[email protected]>
Cc Stephen Warren <[email protected]>
Cc Tom Warren <[email protected]>
CC Stefano Babic <[email protected]>
CC Minkyu Kang <[email protected]>
Cc Dinh Nguyen <[email protected]>
Quoted 8 lines

I understand my patch is here because your series uses it as a prerequisite.

But, please make sure this patch should be reviewed and applied by Tom Rini because this patch is relevant to various SoCs.

Best Regards
Masahiro Yamada

#13 lore raw

PATCH 4/12 spl: consolidate arch/arm/include/asm/arch-*/spl.h

Hi Tim,

Quoted 43 lines · Masahiro Yamada

Hi Tim,
Cc : Stefano, Tom

Quoted 28 lines · On Mon, 28 Apr 2014 13:17:30 -0700 Tim Harvey <[email protected]> wrote:

From: Masahiro Yamada <[email protected]>

arch/arm/include/asm/spl.h requires all SoCs to have arch/arm/include/asm/arch-*/spl.h.

But many of them just define BOOT_DEVICE_* macros.

Those macros are used in the "switch (boot_device) { ... }" statement in common/spl/spl.c.

So they should not be archtecture specific, but be described as a simpile enumeration.

This commit merges most of arch/arm/include/asm/arch-*/spl.h into arch/arm/include/asm/spl.h.

With a little more effort, arch-zynq/spl.h and arch-socfpga/spl.h will be merged, while I am not sure about OMAP and Exynos.

Cc Tom Rini <[email protected]>
Cc Michal Simek <[email protected]>
Cc Andreas Biesmann <[email protected]>
Cc Stephen Warren <[email protected]>
Cc Tom Warren <[email protected]>
CC Stefano Babic <[email protected]>
CC Minkyu Kang <[email protected]>
Cc Dinh Nguyen <[email protected]>
Quoted 8 lines
Quoted 7 lines

I understand my patch is here because your series uses it as a prerequisite.

But, please make sure this patch should be reviewed and applied by Tom Rini because this patch is relevant to various SoCs.

Indeed. Tim, it is enough you add in the cover letter for the next version that your patchset depends on Masahiro's patch, without including it in your series. I will check by merging if all dependencies will be satisfied.

Best regards,
Stefano Babic

Signature · 5 lines
=====================================================================
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: +49-8142-66989-53 Fax: +49-8142-66989-80 Email: sbabic at denx.de
=====================================================================
author
#14 lore raw

PATCH 5/12 MX6: add boot device support for SPL

In reply to Tim Harvey

Add a common spl.c file to support boot device functions needed for SPL such as detecting the boot device.

---
v2:
- re-base on top of Masahiro Yamada's consolidation patch:
http://patchwork.ozlabs.org/patch/341817/
- moved spl_boot_device() and get_boot_mode() into own common imx spl.c file
- use mem-mapped structure for smbr reg access

---
 arch/arm/imx-common/Makefile |  1 +
 arch/arm/imx-common/spl.c    | 79 ++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 80 insertions(+)
 create mode 100644 arch/arm/imx-common/spl.c
arch/arm/imx-common/Makefile +1 -0
index b04dfbb..c97ea48 100644
@@ -16,6 +16,7 @@ obj-$(CONFIG_SYS_I2C_MXC) += i2c-mxv7.o
 endif
 ifeq ($(SOC),$(filter $(SOC),mx6 mxs))
 obj-y	+= misc.o
+obj-$(CONFIG_SPL_BUILD)	+= spl.o
 endif
 ifeq ($(SOC),$(filter $(SOC),mx6))
 obj-$(CONFIG_CMD_SATA) += sata.o
arch/arm/imx-common/spl.c new file +79 -0

79 lines not on this page · raw message

Signature · 1 line
1.8.3.2
#15 lore raw

PATCH 5/12 MX6: add boot device support for SPL

Hi Tim,

Quoted 17 lines · Tim Harvey

Add a common spl.c file to support boot device functions needed for SPL such as detecting the boot device.

<snip>

arch/arm/imx-common/spl.c new file +3 -0
new file mode 100644
index 0000000..5c1667c
@@ -0,0 +1,79 @@
 
<snip>
 
+u32 spl_boot_device(void)
+{
+	struct src *psrc = (struct src *)SRC_BASE_ADDR;

arch/arm/imx-common/spl.c line 37

Quoted 10 lines
arch/arm/imx-common/spl.c new file +7 -0
+	unsigned reg = readl(&psrc->sbmr1);
+
+	/* BOOT_CFG1[7:4] - see IMX6DQRM Table 8-8 */
+	switch ((reg & 0x000000FF) >> 4) {
 
<snip>
 
+	case 0x3:
+		/* BOOT_CFG4[2:0] */
+		switch ((reg & 0x07000000) >> 24) {

This made me want a language lawyer, although I do see case ranges used in arch/blackfin/cpu/traps.c

arch/arm/imx-common/spl.c line 42

Quoted 5 lines
arch/arm/imx-common/spl.c new file +5 -0
+		case 0x0 ... 0x4:
+			return BOOT_DEVICE_SPI;
+		case 0x5 ... 0x7:
+			return BOOT_DEVICE_I2C;
+		}

Regards,

Eric

#16 lore raw

PATCH 5/12 MX6: add boot device support for SPL

In reply to Tim Harvey

Hi Tim,

Quoted 34 lines · Tim Harvey

Add a common spl.c file to support boot device functions needed for SPL such as detecting the boot device.

---
v2:
- re-base on top of Masahiro Yamada's consolidation patch:
http://patchwork.ozlabs.org/patch/341817/
- moved spl_boot_device() and get_boot_mode() into own common imx spl.c file
- use mem-mapped structure for smbr reg access

---
 arch/arm/imx-common/Makefile |  1 +
 arch/arm/imx-common/spl.c    | 79 ++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 80 insertions(+)
 create mode 100644 arch/arm/imx-common/spl.c
arch/arm/imx-common/Makefile +1 -0
index b04dfbb..c97ea48 100644
@@ -16,6 +16,7 @@ obj-$(CONFIG_SYS_I2C_MXC) += i2c-mxv7.o
 endif
 ifeq ($(SOC),$(filter $(SOC),mx6 mxs))
 obj-y	+= misc.o
+obj-$(CONFIG_SPL_BUILD)	+= spl.o
 endif
 ifeq ($(SOC),$(filter $(SOC),mx6))
 obj-$(CONFIG_CMD_SATA) += sata.o
arch/arm/imx-common/spl.c new file +0 -0
new file mode 100644
index 0000000..5c1667c

arch/arm/imx-common/spl.c line 7

Quoted 7 lines
arch/arm/imx-common/spl.c new file +7 -0
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2014 Gateworks Corporation
+ * Author: Tim Harvey <[email protected]>
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+

Just a little remark. Do you have written the function on your own or have you ported it from Freescale's 2009.08 ? Apart names, it looks similar.

If this is the case, you should also add Freescale's Copyright to the header.

Quoted 63 lines
arch/arm/imx-common/spl.c new file +62 -0
+#include <common.h>
+#include <asm/io.h>
+#include <asm/arch/imx-regs.h>
+#include <asm/spl.h>
+#include <spl.h>
+
+#if defined(CONFIG_MX6)
+/* determine boot device from SRC_SBMR1 register (BOOT_CFG[4:1]) */
+u32 spl_boot_device(void)
+{
+	struct src *psrc = (struct src *)SRC_BASE_ADDR;
+	unsigned reg = readl(&psrc->sbmr1);
+
+	/* BOOT_CFG1[7:4] - see IMX6DQRM Table 8-8 */
+	switch ((reg & 0x000000FF) >> 4) {
+	 /* EIM: See 8.5.1, Table 8-9 */
+	case 0x0:
+		/* BOOT_CFG1[3]: NOR/OneNAND Selection */
+		if ((reg & 0x00000008) >> 3)
+			return BOOT_DEVICE_ONENAND;
+		else
+			return BOOT_DEVICE_NOR;
+		break;
+	/* SATA: See 8.5.4, Table 8-20 */
+	case 0x2:
+		return BOOT_DEVICE_SATA;
+	/* Serial ROM: See 8.5.5.1, Table 8-22 */
+	case 0x3:
+		/* BOOT_CFG4[2:0] */
+		switch ((reg & 0x07000000) >> 24) {
+		case 0x0 ... 0x4:
+			return BOOT_DEVICE_SPI;
+		case 0x5 ... 0x7:
+			return BOOT_DEVICE_I2C;
+		}
+		break;
+	/* SD/eSD: 8.5.3, Table 8-15  */
+	case 0x4:
+	case 0x5:
+		return BOOT_DEVICE_MMC1;
+	/* MMC/eMMC: 8.5.3 */
+	case 0x6:
+	case 0x7:
+		return BOOT_DEVICE_MMC1;
+	/* NAND Flash: 8.5.2 */
+	case 0x8 ... 0xf:
+		return BOOT_DEVICE_NAND;
+	}
+	return BOOT_DEVICE_NONE;
+}
+#endif
+
+#if defined(CONFIG_SPL_MMC_SUPPORT)
+/* called from spl_mmc to see type of boot mode for storage (RAW or FAT) */
+u32 spl_boot_mode(void)
+{
+	switch (spl_boot_device()) {
+	/* for MMC return either RAW or FAT mode */
+	case BOOT_DEVICE_MMC1:
+	case BOOT_DEVICE_MMC2:
+#ifdef CONFIG_SPL_FAT_SUPPORT
+		return MMCSD_MODE_FAT;

arch/arm/imx-common/spl.c line 79

Quoted 10 lines
arch/arm/imx-common/spl.c new file +10 -0
+#else
+		return MMCSD_MODE_RAW;
+#endif
+		break;
+	default:
+		puts("spl: ERROR:  unsupported device\n");
+		hang();
+	}
+}
+#endif

Best regards,
Stefano Babic

Signature · 5 lines
=====================================================================
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: +49-8142-66989-53 Fax: +49-8142-66989-80 Email: sbabic at denx.de
=====================================================================
author
#17 lore raw

PATCH 5/12 MX6: add boot device support for SPL

+cc Edward Lin

Quoted 48 lines · Stefano Babic

Hi Tim,

Quoted 34 lines · Tim Harvey

Add a common spl.c file to support boot device functions needed for SPL such as detecting the boot device.

---
v2:
- re-base on top of Masahiro Yamada's consolidation patch:
http://patchwork.ozlabs.org/patch/341817/
- moved spl_boot_device() and get_boot_mode() into own common imx spl.c file
- use mem-mapped structure for smbr reg access

---
 arch/arm/imx-common/Makefile |  1 +
 arch/arm/imx-common/spl.c    | 79 ++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 80 insertions(+)
 create mode 100644 arch/arm/imx-common/spl.c
arch/arm/imx-common/Makefile +1 -0
index b04dfbb..c97ea48 100644
@@ -16,6 +16,7 @@ obj-$(CONFIG_SYS_I2C_MXC) += i2c-mxv7.o
 endif
 ifeq ($(SOC),$(filter $(SOC),mx6 mxs))
 obj-y        += misc.o
+obj-$(CONFIG_SPL_BUILD)      += spl.o
 endif
 ifeq ($(SOC),$(filter $(SOC),mx6))
 obj-$(CONFIG_CMD_SATA) += sata.o
arch/arm/imx-common/spl.c new file +0 -0
new file mode 100644
index 0000000..5c1667c

arch/arm/imx-common/spl.c line 7

Quoted 7 lines
arch/arm/imx-common/spl.c new file +7 -0
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2014 Gateworks Corporation
+ * Author: Tim Harvey <[email protected]>
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+

Just a little remark. Do you have written the function on your own or have you ported it from Freescale's 2009.08 ? Apart names, it looks similar.

Quoted 2 lines

If this is the case, you should also add Freescale's Copyright to the header.

Hi Stefano,

I've never looked at Freescales 2009.08 code myself (I have an aversion to vendor specific forks of u-boot almost 5 years old heh), but its likely bits of the function came from there originally but my inspiration likely came from Edward Lin's patch a while back. A switch/case seems the logical approach given the bitfield from the IMX6 reference manual with several don't-cares spread around and I felt that was much easier to read than trying to convert it all the shifts and masks.

I can add additional copyright's if anyone feels its necessary - I've added Edward to the cc to see if he feels its necessary.

Tim

Quoted 84 lines
Quoted 64 lines
arch/arm/imx-common/spl.c new file +62 -0
+#include <common.h>
+#include <asm/io.h>
+#include <asm/arch/imx-regs.h>
+#include <asm/spl.h>
+#include <spl.h>
+
+#if defined(CONFIG_MX6)
+/* determine boot device from SRC_SBMR1 register (BOOT_CFG[4:1]) */
+u32 spl_boot_device(void)
+{
+     struct src *psrc = (struct src *)SRC_BASE_ADDR;
+     unsigned reg = readl(&psrc->sbmr1);
+
+     /* BOOT_CFG1[7:4] - see IMX6DQRM Table 8-8 */
+     switch ((reg & 0x000000FF) >> 4) {
+      /* EIM: See 8.5.1, Table 8-9 */
+     case 0x0:
+             /* BOOT_CFG1[3]: NOR/OneNAND Selection */
+             if ((reg & 0x00000008) >> 3)
+                     return BOOT_DEVICE_ONENAND;
+             else
+                     return BOOT_DEVICE_NOR;
+             break;
+     /* SATA: See 8.5.4, Table 8-20 */
+     case 0x2:
+             return BOOT_DEVICE_SATA;
+     /* Serial ROM: See 8.5.5.1, Table 8-22 */
+     case 0x3:
+             /* BOOT_CFG4[2:0] */
+             switch ((reg & 0x07000000) >> 24) {
+             case 0x0 ... 0x4:
+                     return BOOT_DEVICE_SPI;
+             case 0x5 ... 0x7:
+                     return BOOT_DEVICE_I2C;
+             }
+             break;
+     /* SD/eSD: 8.5.3, Table 8-15  */
+     case 0x4:
+     case 0x5:
+             return BOOT_DEVICE_MMC1;
+     /* MMC/eMMC: 8.5.3 */
+     case 0x6:
+     case 0x7:
+             return BOOT_DEVICE_MMC1;
+     /* NAND Flash: 8.5.2 */
+     case 0x8 ... 0xf:
+             return BOOT_DEVICE_NAND;
+     }
+     return BOOT_DEVICE_NONE;
+}
+#endif
+
+#if defined(CONFIG_SPL_MMC_SUPPORT)
+/* called from spl_mmc to see type of boot mode for storage (RAW or FAT) */
+u32 spl_boot_mode(void)
+{
+     switch (spl_boot_device()) {
+     /* for MMC return either RAW or FAT mode */
+     case BOOT_DEVICE_MMC1:
+     case BOOT_DEVICE_MMC2:
+#ifdef CONFIG_SPL_FAT_SUPPORT
+             return MMCSD_MODE_FAT;

arch/arm/imx-common/spl.c line 79

Quoted 10 lines
arch/arm/imx-common/spl.c new file +10 -0
+#else
+             return MMCSD_MODE_RAW;
+#endif
+             break;
+     default:
+             puts("spl: ERROR:  unsupported device\n");
+             hang();
+     }
+}
+#endif

Best regards,
Stefano Babic

--
=====================================================================
DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: +49-8142-66989-53 Fax: +49-8142-66989-80 Email: sbabic at denx.de
=====================================================================

#18 lore raw

PATCH 5/12 MX6: add boot device support for SPL

Hi Tim,

Quoted 8 lines · Tim Harvey
Quoted 5 lines

Just a little remark. Do you have written the function on your own or have you ported it from Freescale's 2009.08 ? Apart names, it looks similar.

If this is the case, you should also add Freescale's Copyright to the header.

Hi Stefano,

Quoted 8 lines

I've never looked at Freescales 2009.08 code myself (I have an aversion to vendor specific forks of u-boot almost 5 years old heh), but its likely bits of the function came from there originally but my inspiration likely came from Edward Lin's patch a while back. A switch/case seems the logical approach given the bitfield from the IMX6 reference manual with several don't-cares spread around and I felt that was much easier to read than trying to convert it all the shifts and masks.

This is ok - I want only to be sure that Copyright is maintained if code is taken from somewhere else.

Quoted 3 lines

I can add additional copyright's if anyone feels its necessary - I've added Edward to the cc to see if he feels its necessary.

Ok - if nobody complains, you can leave it as it is now.

Best regards,
Stefano

Signature · 5 lines
=====================================================================
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: +49-8142-66989-53 Fax: +49-8142-66989-80 Email: sbabic at denx.de
=====================================================================
#19 lore raw

PATCH 5/12 MX6: add boot device support for SPL

In reply to Tim Harvey
Quoted 5 lines · On Mon, 5 May 2014 08:46:24 -0700 Tim Harvey <[email protected]> wrote:

+cc Edward Lin

Quoted 2 lines · Stefano Babic

Hi Tim,

...

Quoted 99 lines
Quoted 14 lines

arch/arm/imx-common/spl.c line 7

Quoted 10 lines
arch/arm/imx-common/spl.c new file +7 -0
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2014 Gateworks Corporation
+ * Author: Tim Harvey <[email protected]>
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+

Just a little remark. Do you have written the function on your own or have you ported it from Freescale's 2009.08 ? Apart names, it looks similar.

Quoted 2 lines

If this is the case, you should also add Freescale's Copyright to the header.

Hi Stefano,

I've never looked at Freescales 2009.08 code myself (I have an aversion to vendor specific forks of u-boot almost 5 years old heh), but its likely bits of the function came from there originally but my inspiration likely came from Edward Lin's patch a while back. A switch/case seems the logical approach given the bitfield from the IMX6 reference manual with several don't-cares spread around and I felt that was much easier to read than trying to convert it all the shifts and masks.

I can add additional copyright's if anyone feels its necessary - I've added Edward to the cc to see if he feels its necessary.

Tim

Quoted 66 lines
Quoted 66 lines
arch/arm/imx-common/spl.c new file +65 -0
+#include <common.h>
+#include <asm/io.h>
+#include <asm/arch/imx-regs.h>
+#include <asm/spl.h>
+#include <spl.h>
+
+#if defined(CONFIG_MX6)
+/* determine boot device from SRC_SBMR1 register (BOOT_CFG[4:1]) */
+u32 spl_boot_device(void)
+{
+     struct src *psrc = (struct src *)SRC_BASE_ADDR;
+     unsigned reg = readl(&psrc->sbmr1);
+
+     /* BOOT_CFG1[7:4] - see IMX6DQRM Table 8-8 */
+     switch ((reg & 0x000000FF) >> 4) {
+      /* EIM: See 8.5.1, Table 8-9 */
+     case 0x0:
+             /* BOOT_CFG1[3]: NOR/OneNAND Selection */
+             if ((reg & 0x00000008) >> 3)
+                     return BOOT_DEVICE_ONENAND;
+             else
+                     return BOOT_DEVICE_NOR;
+             break;
+     /* SATA: See 8.5.4, Table 8-20 */
+     case 0x2:
+             return BOOT_DEVICE_SATA;
+     /* Serial ROM: See 8.5.5.1, Table 8-22 */
+     case 0x3:
+             /* BOOT_CFG4[2:0] */
+             switch ((reg & 0x07000000) >> 24) {
+             case 0x0 ... 0x4:
+                     return BOOT_DEVICE_SPI;
+             case 0x5 ... 0x7:
+                     return BOOT_DEVICE_I2C;
+             }
+             break;
+     /* SD/eSD: 8.5.3, Table 8-15  */
+     case 0x4:
+     case 0x5:
+             return BOOT_DEVICE_MMC1;
+     /* MMC/eMMC: 8.5.3 */
+     case 0x6:
+     case 0x7:
+             return BOOT_DEVICE_MMC1;
+     /* NAND Flash: 8.5.2 */
+     case 0x8 ... 0xf:
+             return BOOT_DEVICE_NAND;
+     }
+     return BOOT_DEVICE_NONE;
+}
+#endif
+
+#if defined(CONFIG_SPL_MMC_SUPPORT)
+/* called from spl_mmc to see type of boot mode for storage (RAW or FAT) */
+u32 spl_boot_mode(void)
+{
+     switch (spl_boot_device()) {
+     /* for MMC return either RAW or FAT mode */
+     case BOOT_DEVICE_MMC1:
+     case BOOT_DEVICE_MMC2:
+#ifdef CONFIG_SPL_FAT_SUPPORT
+             return MMCSD_MODE_FAT;
+#else
+             return MMCSD_MODE_RAW;
+#endif
Quoted 8 lines
Quoted 8 lines

arch/arm/imx-common/spl.c line 79

Quoted 8 lines
arch/arm/imx-common/spl.c new file +7 -0
+             break;
+     default:
+             puts("spl: ERROR:  unsupported device\n");
+             hang();
+     }
+}
+#endif

Tim, Stefano,

that piece of code indeed originates from Freescale's 2009.08 u-boot. (Edward has changed jobs, so the CC:d address is of no use.)

regards,

//Tapani

ps: Tim, thanks for getting the SPL framework mainlined!

#20 lore raw

PATCH 5/12 MX6: add boot device support for SPL

Hi Tim,

Quoted 5 lines · Tapani Utriainen

Tim, Stefano,

that piece of code indeed originates from Freescale's 2009.08 u-boot. (Edward has changed jobs, so the CC:d address is of no use.)

I supposed this. Tim, please add Freescale's Copyright, too.

Thanks,
Stefano Babic

Signature · 5 lines
=====================================================================
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: +49-8142-66989-53 Fax: +49-8142-66989-80 Email: sbabic at denx.de
=====================================================================
author
#21 lore raw

PATCH 5/12 MX6: add boot device support for SPL

Quoted 7 lines · Stefano Babic

Hi Tim,

Quoted 3 lines · Tapani Utriainen

Tim, Stefano,

Quoted 9 lines
Quoted 2 lines

that piece of code indeed originates from Freescale's 2009.08 u-boot. (Edward has changed jobs, so the CC:d address is of no use.)

I supposed this. Tim, please add Freescale's Copyright, too.

Thanks,
Stefano Babic

ok - will do. Thanks for the heads-up Tapani.

Tim

author
#22 lore raw

PATCH 6/12 IMX: add comments and remove unused struct fields

In reply to Tim Harvey

Add comment block for the imx_ddr_size function and remove the extra unused fields from struct esd_mmdc_regs which are also not common between IMX53 and IMX6. There are no functional changes here.

---
 arch/arm/imx-common/cpu.c | 16 +++++++---------
 1 file changed, 7 insertions(+), 9 deletions(-)
arch/arm/imx-common/cpu.c +7 -9
index a77c4de..392b8d4 100644
@@ -58,6 +58,7 @@ char *get_reset_cause(void)
 static const unsigned char col_lookup[] = {9, 10, 11, 8, 12, 9, 9, 9};
 static const unsigned char bank_lookup[] = {3, 2};
 
+/* these MMDC registers are common to the IMX53 and IMX6 */
 struct esd_mmdc_regs {
 	uint32_t	ctl;
 	uint32_t	pdc;
@@ -66,15 +67,6 @@ struct esd_mmdc_regs {
 	uint32_t	cfg1;
 	uint32_t	cfg2;
 	uint32_t	misc;
-	uint32_t	scr;
-	uint32_t	ref;
-	uint32_t	rsvd1;
-	uint32_t	rsvd2;
-	uint32_t	rwd;
-	uint32_t	or;
-	uint32_t	mrr;
-	uint32_t	cfg3lp;
-	uint32_t	mr4;
 };
 
 #define ESD_MMDC_CTL_GET_ROW(mdctl)	((ctl >> 24) & 7)
@@ -83,6 +75,12 @@ struct esd_mmdc_regs {
 #define ESD_MMDC_CTL_GET_CS1(mdctl)	((ctl >> 30) & 1)
 #define ESD_MMDC_MISC_GET_BANK(mdmisc)	((misc >> 5) & 1)
 
+/**
+ * imx_ddr_size - return size in bytes of DRAM according MMDC config
+ * The MMDC MDCTL register holds the number of bits for row, col, and data
+ * width and the MMDC MDMISC register holds the number of banks. Combine
+ * all these bits to determine the meme size the MMDC has been configured for
+ */
 unsigned imx_ddr_size(void)
 {
 	struct esd_mmdc_regs *mem = (struct esd_mmdc_regs *)MEMCTL_BASE;
Signature · 1 line
1.8.3.2
#23 lore raw

PATCH 6/12 IMX: add comments and remove unused struct fields

Hi Tim,

Quoted 38 lines · Tim Harvey

Add comment block for the imx_ddr_size function and remove the extra unused fields from struct esd_mmdc_regs which are also not common between IMX53 and IMX6. There are no functional changes here.

---
 arch/arm/imx-common/cpu.c | 16 +++++++---------
 1 file changed, 7 insertions(+), 9 deletions(-)
arch/arm/imx-common/cpu.c +1 -9
index a77c4de..392b8d4 100644
@@ -58,6 +58,7 @@ char *get_reset_cause(void)
 static const unsigned char col_lookup[] = {9, 10, 11, 8, 12, 9, 9, 9};
 static const unsigned char bank_lookup[] = {3, 2};
 
+/* these MMDC registers are common to the IMX53 and IMX6 */
 struct esd_mmdc_regs {
 	uint32_t	ctl;
 	uint32_t	pdc;
@@ -66,15 +67,6 @@ struct esd_mmdc_regs {
 	uint32_t	cfg1;
 	uint32_t	cfg2;
 	uint32_t	misc;
-	uint32_t	scr;
-	uint32_t	ref;
-	uint32_t	rsvd1;
-	uint32_t	rsvd2;
-	uint32_t	rwd;
-	uint32_t	or;
-	uint32_t	mrr;
-	uint32_t	cfg3lp;
-	uint32_t	mr4;
 };
 
 #define ESD_MMDC_CTL_GET_ROW(mdctl)	((ctl >> 24) & 7)

arch/arm/imx-common/cpu.c struct esd_mmdc_regs { · line 78

Quoted 4 lines
arch/arm/imx-common/cpu.c +1 -0
@@ -83,6 +75,12 @@ struct esd_mmdc_regs {
 #define ESD_MMDC_CTL_GET_CS1(mdctl)	((ctl >> 30) & 1)
 #define ESD_MMDC_MISC_GET_BANK(mdmisc)	((misc >> 5) & 1)
 
+/**

Just a *very* minor point: why do you introduce doxygen-like comment ? As U-Boot does not support it, this is uncommon and not useful.

arch/arm/imx-common/cpu.c struct esd_mmdc_regs { · line 86

Quoted 9 lines
arch/arm/imx-common/cpu.c +5 -0
+ * imx_ddr_size - return size in bytes of DRAM according MMDC config
+ * The MMDC MDCTL register holds the number of bits for row, col, and data
+ * width and the MMDC MDMISC register holds the number of banks. Combine
+ * all these bits to determine the meme size the MMDC has been configured for
+ */
 unsigned imx_ddr_size(void)
 {
 	struct esd_mmdc_regs *mem = (struct esd_mmdc_regs *)MEMCTL_BASE;

Apart of that:

Best regards,
Stefano Babic

Signature · 5 lines
=====================================================================
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: +49-8142-66989-53 Fax: +49-8142-66989-80 Email: sbabic at denx.de
=====================================================================
author
#24 lore raw

PATCH 7/12 MX6: add structs for mmdc and ddr iomux registers

In reply to Tim Harvey

Add memory-mapped structures for MMDC iomux and configuration. Note that while the MMDC configuration registers are common between the IMX6DQ (IMX6DUAL/IMX6QUAD) and IMX6SDL (IMX6SOLO/IMX6DUALLITE) types the iomux registers differ. This requires two sets of structures.

Add structures to describe DDR3 device information, system information (memory layout, etc), and MMDC calibration regitsers that can be used to configure the MMDC dynamically.

We define these structures for SPL builds instead of including mx6q-ddr.h and mx6dl-ddr.h which use the same namespace and are only useful for imximage cfg files.

---
v2:
- split out from original mmdc configuration patch
- only define for SPL build
- do not include mx6q-ddr.h and mx6dl-ddr.h for SPL build - these use the same namespace and are only useful for imximage cfg files

---
 arch/arm/include/asm/arch-mx6/mx6-ddr.h | 231 ++++++++++++++++++++++++++++++++
 1 file changed, 231 insertions(+)
arch/arm/include/asm/arch-mx6/mx6-ddr.h +231 -0
index 43d377a..d544d2e 100644
@@ -6,6 +6,7 @@
 #ifndef __ASM_ARCH_MX6_DDR_H__
 #define __ASM_ARCH_MX6_DDR_H__
 
+#ifndef CONFIG_SPL_BUILD
 #ifdef CONFIG_MX6Q
 #include "mx6q-ddr.h"
 #else
@@ -15,6 +16,236 @@
 #error "Please select cpu"
 #endif	/* CONFIG_MX6DL or CONFIG_MX6S */
 #endif	/* CONFIG_MX6Q */
+#else
+
+/* MMDC P0/P1 Registers */
+struct mmdc_p_regs {
+	u32 mdctl;
+	u32 mdpdc;
+	u32 mdotc;
+	u32 mdcfg0;
+	u32 mdcfg1;
+	u32 mdcfg2;
+	u32 mdmisc;
+	u32 mdscr;
+	u32 mdref;
+	u32 res1[2];
+	u32 mdrwd;
+	u32 mdor;
+	u32 res2[3];
+	u32 mdasp;
+	u32 res3[240];
+	u32 mapsr;
+	u32 res4[254];
+	u32 mpzqhwctrl;
+	u32 res5[2];
+	u32 mpwldectrl0;
+	u32 mpwldectrl1;
+	u32 res6;
+	u32 mpodtctrl;
+	u32 mprddqby0dl;
+	u32 mprddqby1dl;
+	u32 mprddqby2dl;
+	u32 mprddqby3dl;
+	u32 res7[4];
+	u32 mpdgctrl0;
+	u32 mpdgctrl1;
+	u32 res8;
+	u32 mprddlctl;
+	u32 res9;
+	u32 mpwrdlctl;
+	u32 res10[25];
+	u32 mpmur0;
+};
+
+/*
+ * MMDC iomux registers (pinctl/padctl) - (different for IMX6DQ vs IMX6SDL)
+ */
+#define MX6DQ_IOM_DDR_BASE      0x020e0500
+struct mx6dq_iomux_ddr_regs {
+	u32 res1[3];
+	u32 dram_sdqs5;
+	u32 dram_dqm5;
+	u32 dram_dqm4;
+	u32 dram_sdqs4;
+	u32 dram_sdqs3;
+	u32 dram_dqm3;
+	u32 dram_sdqs2;
+	u32 dram_dqm2;
+	u32 res2[16];
+	u32 dram_cas;
+	u32 res3[2];
+	u32 dram_ras;
+	u32 dram_reset;
+	u32 res4[2];
+	u32 dram_sdclk_0;
+	u32 dram_sdba2;
+	u32 dram_sdcke0;
+	u32 dram_sdclk_1;
+	u32 dram_sdcke1;
+	u32 dram_sdodt0;
+	u32 dram_sdodt1;
+	u32 res5;
+	u32 dram_sdqs0;
+	u32 dram_dqm0;
+	u32 dram_sdqs1;
+	u32 dram_dqm1;
+	u32 dram_sdqs6;
+	u32 dram_dqm6;
+	u32 dram_sdqs7;
+	u32 dram_dqm7;
+};
+
+#define MX6DQ_IOM_GRP_BASE      0x020e0700
+struct mx6dq_iomux_grp_regs {
+	u32 res1[18];
+	u32 grp_b7ds;
+	u32 grp_addds;
+	u32 grp_ddrmode_ctl;
+	u32 res2;
+	u32 grp_ddrpke;
+	u32 res3[6];
+	u32 grp_ddrmode;
+	u32 res4[3];
+	u32 grp_b0ds;
+	u32 grp_b1ds;
+	u32 grp_ctlds;
+	u32 res5;
+	u32 grp_b2ds;
+	u32 grp_ddr_type;
+	u32 grp_b3ds;
+	u32 grp_b4ds;
+	u32 grp_b5ds;
+	u32 grp_b6ds;
+};
+
+#define MX6SDL_IOM_DDR_BASE     0x020e0400
+struct mx6sdl_iomux_ddr_regs {
+	u32 res1[25];
+	u32 dram_cas;
+	u32 res2[2];
+	u32 dram_dqm0;
+	u32 dram_dqm1;
+	u32 dram_dqm2;
+	u32 dram_dqm3;
+	u32 dram_dqm4;
+	u32 dram_dqm5;
+	u32 dram_dqm6;
+	u32 dram_dqm7;
+	u32 dram_ras;
+	u32 dram_reset;
+	u32 res3[2];
+	u32 dram_sdba2;
+	u32 dram_sdcke0;
+	u32 dram_sdcke1;
+	u32 dram_sdclk_0;
+	u32 dram_sdclk_1;
+	u32 dram_sdodt0;
+	u32 dram_sdodt1;
+	u32 dram_sdqs0;
+	u32 dram_sdqs1;
+	u32 dram_sdqs2;
+	u32 dram_sdqs3;
+	u32 dram_sdqs4;
+	u32 dram_sdqs5;
+	u32 dram_sdqs6;
+	u32 dram_sdqs7;
+};
+
+#define MX6SDL_IOM_GRP_BASE     0x020e0700
+struct mx6sdl_iomux_grp_regs {
+	u32 res1[18];
+	u32 grp_b7ds;
+	u32 grp_addds;
+	u32 grp_ddrmode_ctl;
+	u32 grp_ddrpke;
+	u32 res2[2];
+	u32 grp_ddrmode;
+	u32 grp_b0ds;
+	u32 res3;
+	u32 grp_ctlds;
+	u32 grp_b1ds;
+	u32 grp_ddr_type;
+	u32 grp_b2ds;
+	u32 grp_b3ds;
+	u32 grp_b4ds;
+	u32 grp_b5ds;
+	u32 res4;
+	u32 grp_b6ds;
+};
+
+/* Device Information: Varies per DDR3 part number and speed grade */
+struct mx6_ddr3_cfg {
+	u16 mem_speed;	/* ie 1600 for DDR3-1600 (800,1066,1333,1600) */
+	u8 density;	/* chip density (Gb) (1,2,4,8) */
+	u8 width;	/* bus width (bits) (4,8,16) */
+	u8 banks;	/* number of banks */
+	u8 rowaddr;	/* row address bits (11-16)*/
+	u8 coladdr;	/* col address bits (9-12) */
+	u8 pagesz;	/* page size (K) (1-2) */
+	u16 trcd;	/* tRCD=tRP=CL (ns*100) */
+	u16 trcmin;	/* tRC min (ns*100) */
+	u16 trasmin;	/* tRAS min (ns*100) */
+	u8 SRT;		/* self-refresh temperature: 0=normal, 1=extended */
+};
+
+/* System Information: Varies per board design, layout, and term choices */
+struct mx6_ddr_sysinfo {
+	u8 dsize;	/* size of bus (in dwords: 0=16bit,1=32bit,2=64bit) */
+	u8 cs_density;	/* density per chip select (Gb) */
+	u8 ncs;		/* number chip selects used (1|2) */
+	char cs1_mirror;/* enable address mirror (0|1) */
+	char bi_on;	/* Bank interleaving enable */
+	u8 rtt_nom;	/* Rtt_Nom (DDR3_RTT_*) */
+	u8 rtt_wr;	/* Rtt_Wr (DDR3_RTT_*) */
+	u8 ralat;	/* Read Additional Latency (0-7) */
+	u8 walat;	/* Write Additional Latency (0-3) */
+	u8 mif3_mode;	/* Command prediction working mode */
+	u8 rst_to_cke;	/* Time from SDE enable to CKE rise */
+	u8 sde_to_rst;	/* Time from SDE enable until DDR reset# is high */
+};
+
+/*
+ * Board specific calibration:
+ *   This includes write leveling calibration values as well as DQS gating
+ *   and read/write delays. These values are board/layout/device specific.
+ *   Freescale recommends using the i.MX6 DDR Stress Test Tool V1.0.2
+ *   (DOC-96412) to determine these values over a range of boards and
+ *   temperatures.
+ */
+struct mx6_mmdc_calibration {
+	/* write leveling calibration */
+	u32 p0_mpwldectrl0;
+	u32 p0_mpwldectrl1;
+	u32 p1_mpwldectrl0;
+	u32 p1_mpwldectrl1;
+	/* read DQS gating */
+	u32 p0_mpdgctrl0;
+	u32 p0_mpdgctrl1;
+	u32 p1_mpdgctrl0;
+	u32 p1_mpdgctrl1;
+	/* read delay */
+	u32 p0_mprddlctl;
+	u32 p1_mprddlctl;
+	/* write delay */
+	u32 p0_mpwrdlctl;
+	u32 p1_mpwrdlctl;
+};
+
+/* configure iomux (pinctl/padctl) */
+void mx6dq_dram_iocfg(unsigned width,
+		      const struct mx6dq_iomux_ddr_regs *,
+		      const struct mx6dq_iomux_grp_regs *);
+void mx6sdl_dram_iocfg(unsigned width,
+		       const struct mx6sdl_iomux_ddr_regs *,
+		       const struct mx6sdl_iomux_grp_regs *);
+
+/* configure mx6 mmdc registers */
+void mx6_dram_cfg(const struct mx6_ddr_sysinfo *,
+		  const struct mx6_mmdc_calibration *,
+		  const struct mx6_ddr3_cfg *);
+
+#endif /* CONFIG_SPL_BUILD */
 
 #define MX6_MMDC_P0_MDCTL	0x021b0000
 #define MX6_MMDC_P0_MDPDC	0x021b0004
Signature · 1 line
1.8.3.2
#25 lore raw

PATCH 7/12 MX6: add structs for mmdc and ddr iomux registers

Hi Tim,

Quoted 37 lines · Tim Harvey

Add memory-mapped structures for MMDC iomux and configuration. Note that while the MMDC configuration registers are common between the IMX6DQ (IMX6DUAL/IMX6QUAD) and IMX6SDL (IMX6SOLO/IMX6DUALLITE) types the iomux registers differ. This requires two sets of structures.

Add structures to describe DDR3 device information, system information (memory layout, etc), and MMDC calibration regitsers that can be used to configure the MMDC dynamically.

We define these structures for SPL builds instead of including mx6q-ddr.h and mx6dl-ddr.h which use the same namespace and are only useful for imximage cfg files.

---
v2:
- split out from original mmdc configuration patch
- only define for SPL build
- do not include mx6q-ddr.h and mx6dl-ddr.h for SPL build - these use the same namespace and are only useful for imximage cfg files

---
  arch/arm/include/asm/arch-mx6/mx6-ddr.h | 231 ++++++++++++++++++++++++++++++++
  1 file changed, 231 insertions(+)
arch/arm/include/asm/arch-mx6/mx6-ddr.h +1 -0
index 43d377a..d544d2e 100644
@@ -6,6 +6,7 @@
  #ifndef __ASM_ARCH_MX6_DDR_H__
  #define __ASM_ARCH_MX6_DDR_H__
 
+#ifndef CONFIG_SPL_BUILD
  #ifdef CONFIG_MX6Q
  #include "mx6q-ddr.h"
  #else

arch/arm/include/asm/arch-mx6/mx6-ddr.h line 20

Quoted 5 lines
arch/arm/include/asm/arch-mx6/mx6-ddr.h +2 -0
@@ -15,6 +16,236 @@
  #error "Please select cpu"
  #endif	/* CONFIG_MX6DL or CONFIG_MX6S */
  #endif	/* CONFIG_MX6Q */
+#else
+

This part of the patch matches the commit message for patch 7.

arch/arm/include/asm/arch-mx6/mx6-ddr.h

Quoted 13 lines
arch/arm/include/asm/arch-mx6/mx6-ddr.h +10 -0
+/* MMDC P0/P1 Registers */
+struct mmdc_p_regs {
+	u32 mdctl;
+	u32 mdpdc;
+	u32 mdotc;
+	u32 mdcfg0;
+	u32 mdcfg1;
+	u32 mdcfg2;
+	u32 mdmisc;
+	u32 mdscr;
 
...

The following bits should probably be moved into patch 8 though:

Quoted 48 lines
arch/arm/include/asm/arch-mx6/mx6-ddr.h +48 -0
+
+/* Device Information: Varies per DDR3 part number and speed grade */
+struct mx6_ddr3_cfg {
+	u16 mem_speed;	/* ie 1600 for DDR3-1600 (800,1066,1333,1600) */
+	u8 density;	/* chip density (Gb) (1,2,4,8) */
+	u8 width;	/* bus width (bits) (4,8,16) */
+	u8 banks;	/* number of banks */
+	u8 rowaddr;	/* row address bits (11-16)*/
+	u8 coladdr;	/* col address bits (9-12) */
+	u8 pagesz;	/* page size (K) (1-2) */
+	u16 trcd;	/* tRCD=tRP=CL (ns*100) */
+	u16 trcmin;	/* tRC min (ns*100) */
+	u16 trasmin;	/* tRAS min (ns*100) */
+	u8 SRT;		/* self-refresh temperature: 0=normal, 1=extended */
+};
+
+/* System Information: Varies per board design, layout, and term choices */
+struct mx6_ddr_sysinfo {
+	u8 dsize;	/* size of bus (in dwords: 0=16bit,1=32bit,2=64bit) */
+	u8 cs_density;	/* density per chip select (Gb) */
+	u8 ncs;		/* number chip selects used (1|2) */
+	char cs1_mirror;/* enable address mirror (0|1) */
+	char bi_on;	/* Bank interleaving enable */
+	u8 rtt_nom;	/* Rtt_Nom (DDR3_RTT_*) */
+	u8 rtt_wr;	/* Rtt_Wr (DDR3_RTT_*) */
+	u8 ralat;	/* Read Additional Latency (0-7) */
+	u8 walat;	/* Write Additional Latency (0-3) */
+	u8 mif3_mode;	/* Command prediction working mode */
+	u8 rst_to_cke;	/* Time from SDE enable to CKE rise */
+	u8 sde_to_rst;	/* Time from SDE enable until DDR reset# is high */
+};
+
+/*
+ * Board specific calibration:
+ *   This includes write leveling calibration values as well as DQS gating
+ *   and read/write delays. These values are board/layout/device specific.
+ *   Freescale recommends using the i.MX6 DDR Stress Test Tool V1.0.2
+ *   (DOC-96412) to determine these values over a range of boards and
+ *   temperatures.
+ */
+struct mx6_mmdc_calibration {
+	/* write leveling calibration */
+	u32 p0_mpwldectrl0;
+	u32 p0_mpwldectrl1;
+	u32 p1_mpwldectrl0;
+	u32 p1_mpwldectrl1;
+	/* read DQS gating */
+	u32 p0_mpdgctrl0;

arch/arm/include/asm/arch-mx6/mx6-ddr.h line 233

Quoted 10 lines
arch/arm/include/asm/arch-mx6/mx6-ddr.h +10 -0
+	u32 p0_mpdgctrl1;
+	u32 p1_mpdgctrl0;
+	u32 p1_mpdgctrl1;
+	/* read delay */
+	u32 p0_mprddlctl;
+	u32 p1_mprddlctl;
+	/* write delay */
+	u32 p0_mpwrdlctl;
+	u32 p1_mpwrdlctl;
+};

Nicely done!

This partitioning of chip-level, design-level, and calibration data makes perfect sense.

Quoted 9 lines
arch/arm/include/asm/arch-mx6/mx6-ddr.h +8 -0
+
+/* configure iomux (pinctl/padctl) */
+void mx6dq_dram_iocfg(unsigned width,
+		      const struct mx6dq_iomux_ddr_regs *,
+		      const struct mx6dq_iomux_grp_regs *);
+void mx6sdl_dram_iocfg(unsigned width,
+		       const struct mx6sdl_iomux_ddr_regs *,
+		       const struct mx6sdl_iomux_grp_regs *);

arch/arm/include/asm/arch-mx6/mx6-ddr.h line 251

Quoted 10 lines
arch/arm/include/asm/arch-mx6/mx6-ddr.h +7 -0
+
+/* configure mx6 mmdc registers */
+void mx6_dram_cfg(const struct mx6_ddr_sysinfo *,
+		  const struct mx6_mmdc_calibration *,
+		  const struct mx6_ddr3_cfg *);
+
+#endif /* CONFIG_SPL_BUILD */
 
  #define MX6_MMDC_P0_MDCTL	0x021b0000
  #define MX6_MMDC_P0_MDPDC	0x021b0004

Regards,

Eric

#26 lore raw

PATCH 7/12 MX6: add structs for mmdc and ddr iomux registers

In reply to Tim Harvey

Hi Tim,

Quoted 76 lines · Tim Harvey

Add memory-mapped structures for MMDC iomux and configuration. Note that while the MMDC configuration registers are common between the IMX6DQ (IMX6DUAL/IMX6QUAD) and IMX6SDL (IMX6SOLO/IMX6DUALLITE) types the iomux registers differ. This requires two sets of structures.

Add structures to describe DDR3 device information, system information (memory layout, etc), and MMDC calibration regitsers that can be used to configure the MMDC dynamically.

We define these structures for SPL builds instead of including mx6q-ddr.h and mx6dl-ddr.h which use the same namespace and are only useful for imximage cfg files.

---
v2:
- split out from original mmdc configuration patch
- only define for SPL build
- do not include mx6q-ddr.h and mx6dl-ddr.h for SPL build - these use the same namespace and are only useful for imximage cfg files

---
 arch/arm/include/asm/arch-mx6/mx6-ddr.h | 231 ++++++++++++++++++++++++++++++++
 1 file changed, 231 insertions(+)
arch/arm/include/asm/arch-mx6/mx6-ddr.h +37 -0
index 43d377a..d544d2e 100644
@@ -6,6 +6,7 @@
 #ifndef __ASM_ARCH_MX6_DDR_H__
 #define __ASM_ARCH_MX6_DDR_H__
 
+#ifndef CONFIG_SPL_BUILD
 #ifdef CONFIG_MX6Q
 #include "mx6q-ddr.h"
 #else
@@ -15,6 +16,236 @@
 #error "Please select cpu"
 #endif	/* CONFIG_MX6DL or CONFIG_MX6S */
 #endif	/* CONFIG_MX6Q */
+#else
+
+/* MMDC P0/P1 Registers */
+struct mmdc_p_regs {
+	u32 mdctl;
+	u32 mdpdc;
+	u32 mdotc;
+	u32 mdcfg0;
+	u32 mdcfg1;
+	u32 mdcfg2;
+	u32 mdmisc;
+	u32 mdscr;
+	u32 mdref;
+	u32 res1[2];
+	u32 mdrwd;
+	u32 mdor;
+	u32 res2[3];
+	u32 mdasp;
+	u32 res3[240];
+	u32 mapsr;
+	u32 res4[254];
+	u32 mpzqhwctrl;
+	u32 res5[2];
+	u32 mpwldectrl0;
+	u32 mpwldectrl1;
+	u32 res6;
+	u32 mpodtctrl;
+	u32 mprddqby0dl;
+	u32 mprddqby1dl;
+	u32 mprddqby2dl;
+	u32 mprddqby3dl;
+	u32 res7[4];
+	u32 mpdgctrl0;
+	u32 mpdgctrl1;
+	u32 res8;
+	u32 mprddlctl;

arch/arm/include/asm/arch-mx6/mx6-ddr.h line 64

Quoted 10 lines
arch/arm/include/asm/arch-mx6/mx6-ddr.h +10 -0
+	u32 res9;
+	u32 mpwrdlctl;
+	u32 res10[25];
+	u32 mpmur0;
+};
+
+/*
+ * MMDC iomux registers (pinctl/padctl) - (different for IMX6DQ vs IMX6SDL)
+ */
+#define MX6DQ_IOM_DDR_BASE      0x020e0500

It is only a question - having the value here let us know where the registers are located. Anyway, registers' offsets are stored in the imx-regs.h file of the SOC. Which is the reason to set them here ?

Quoted 160 lines
arch/arm/include/asm/arch-mx6/mx6-ddr.h +160 -0
+struct mx6dq_iomux_ddr_regs {
+	u32 res1[3];
+	u32 dram_sdqs5;
+	u32 dram_dqm5;
+	u32 dram_dqm4;
+	u32 dram_sdqs4;
+	u32 dram_sdqs3;
+	u32 dram_dqm3;
+	u32 dram_sdqs2;
+	u32 dram_dqm2;
+	u32 res2[16];
+	u32 dram_cas;
+	u32 res3[2];
+	u32 dram_ras;
+	u32 dram_reset;
+	u32 res4[2];
+	u32 dram_sdclk_0;
+	u32 dram_sdba2;
+	u32 dram_sdcke0;
+	u32 dram_sdclk_1;
+	u32 dram_sdcke1;
+	u32 dram_sdodt0;
+	u32 dram_sdodt1;
+	u32 res5;
+	u32 dram_sdqs0;
+	u32 dram_dqm0;
+	u32 dram_sdqs1;
+	u32 dram_dqm1;
+	u32 dram_sdqs6;
+	u32 dram_dqm6;
+	u32 dram_sdqs7;
+	u32 dram_dqm7;
+};
+
+#define MX6DQ_IOM_GRP_BASE      0x020e0700
+struct mx6dq_iomux_grp_regs {
+	u32 res1[18];
+	u32 grp_b7ds;
+	u32 grp_addds;
+	u32 grp_ddrmode_ctl;
+	u32 res2;
+	u32 grp_ddrpke;
+	u32 res3[6];
+	u32 grp_ddrmode;
+	u32 res4[3];
+	u32 grp_b0ds;
+	u32 grp_b1ds;
+	u32 grp_ctlds;
+	u32 res5;
+	u32 grp_b2ds;
+	u32 grp_ddr_type;
+	u32 grp_b3ds;
+	u32 grp_b4ds;
+	u32 grp_b5ds;
+	u32 grp_b6ds;
+};
+
+#define MX6SDL_IOM_DDR_BASE     0x020e0400
+struct mx6sdl_iomux_ddr_regs {
+	u32 res1[25];
+	u32 dram_cas;
+	u32 res2[2];
+	u32 dram_dqm0;
+	u32 dram_dqm1;
+	u32 dram_dqm2;
+	u32 dram_dqm3;
+	u32 dram_dqm4;
+	u32 dram_dqm5;
+	u32 dram_dqm6;
+	u32 dram_dqm7;
+	u32 dram_ras;
+	u32 dram_reset;
+	u32 res3[2];
+	u32 dram_sdba2;
+	u32 dram_sdcke0;
+	u32 dram_sdcke1;
+	u32 dram_sdclk_0;
+	u32 dram_sdclk_1;
+	u32 dram_sdodt0;
+	u32 dram_sdodt1;
+	u32 dram_sdqs0;
+	u32 dram_sdqs1;
+	u32 dram_sdqs2;
+	u32 dram_sdqs3;
+	u32 dram_sdqs4;
+	u32 dram_sdqs5;
+	u32 dram_sdqs6;
+	u32 dram_sdqs7;
+};
+
+#define MX6SDL_IOM_GRP_BASE     0x020e0700
+struct mx6sdl_iomux_grp_regs {
+	u32 res1[18];
+	u32 grp_b7ds;
+	u32 grp_addds;
+	u32 grp_ddrmode_ctl;
+	u32 grp_ddrpke;
+	u32 res2[2];
+	u32 grp_ddrmode;
+	u32 grp_b0ds;
+	u32 res3;
+	u32 grp_ctlds;
+	u32 grp_b1ds;
+	u32 grp_ddr_type;
+	u32 grp_b2ds;
+	u32 grp_b3ds;
+	u32 grp_b4ds;
+	u32 grp_b5ds;
+	u32 res4;
+	u32 grp_b6ds;
+};
+
+/* Device Information: Varies per DDR3 part number and speed grade */
+struct mx6_ddr3_cfg {
+	u16 mem_speed;	/* ie 1600 for DDR3-1600 (800,1066,1333,1600) */
+	u8 density;	/* chip density (Gb) (1,2,4,8) */
+	u8 width;	/* bus width (bits) (4,8,16) */
+	u8 banks;	/* number of banks */
+	u8 rowaddr;	/* row address bits (11-16)*/
+	u8 coladdr;	/* col address bits (9-12) */
+	u8 pagesz;	/* page size (K) (1-2) */
+	u16 trcd;	/* tRCD=tRP=CL (ns*100) */
+	u16 trcmin;	/* tRC min (ns*100) */
+	u16 trasmin;	/* tRAS min (ns*100) */
+	u8 SRT;		/* self-refresh temperature: 0=normal, 1=extended */
+};
+
+/* System Information: Varies per board design, layout, and term choices */
+struct mx6_ddr_sysinfo {
+	u8 dsize;	/* size of bus (in dwords: 0=16bit,1=32bit,2=64bit) */
+	u8 cs_density;	/* density per chip select (Gb) */
+	u8 ncs;		/* number chip selects used (1|2) */
+	char cs1_mirror;/* enable address mirror (0|1) */
+	char bi_on;	/* Bank interleaving enable */
+	u8 rtt_nom;	/* Rtt_Nom (DDR3_RTT_*) */
+	u8 rtt_wr;	/* Rtt_Wr (DDR3_RTT_*) */
+	u8 ralat;	/* Read Additional Latency (0-7) */
+	u8 walat;	/* Write Additional Latency (0-3) */
+	u8 mif3_mode;	/* Command prediction working mode */
+	u8 rst_to_cke;	/* Time from SDE enable to CKE rise */
+	u8 sde_to_rst;	/* Time from SDE enable until DDR reset# is high */
+};
+
+/*
+ * Board specific calibration:
+ *   This includes write leveling calibration values as well as DQS gating
+ *   and read/write delays. These values are board/layout/device specific.
+ *   Freescale recommends using the i.MX6 DDR Stress Test Tool V1.0.2
+ *   (DOC-96412) to determine these values over a range of boards and
+ *   temperatures.
+ */
+struct mx6_mmdc_calibration {
+	/* write leveling calibration */
+	u32 p0_mpwldectrl0;
+	u32 p0_mpwldectrl1;
+	u32 p1_mpwldectrl0;
+	u32 p1_mpwldectrl1;
+	/* read DQS gating */
+	u32 p0_mpdgctrl0;
+	u32 p0_mpdgctrl1;

arch/arm/include/asm/arch-mx6/mx6-ddr.h line 234

Quoted 10 lines
arch/arm/include/asm/arch-mx6/mx6-ddr.h +10 -0
+	u32 p1_mpdgctrl0;
+	u32 p1_mpdgctrl1;
+	/* read delay */
+	u32 p0_mprddlctl;
+	u32 p1_mprddlctl;
+	/* write delay */
+	u32 p0_mpwrdlctl;
+	u32 p1_mpwrdlctl;
+};
+

I agree on theses structures. It is then simpler for a board maintainer to understand what is required to add SPL support for the own board.

Quoted 8 lines
arch/arm/include/asm/arch-mx6/mx6-ddr.h +7 -0
+/* configure iomux (pinctl/padctl) */
+void mx6dq_dram_iocfg(unsigned width,
+		      const struct mx6dq_iomux_ddr_regs *,
+		      const struct mx6dq_iomux_grp_regs *);
+void mx6sdl_dram_iocfg(unsigned width,
+		       const struct mx6sdl_iomux_ddr_regs *,
+		       const struct mx6sdl_iomux_grp_regs *);

arch/arm/include/asm/arch-mx6/mx6-ddr.h line 251

Quoted 10 lines
arch/arm/include/asm/arch-mx6/mx6-ddr.h +7 -0
+
+/* configure mx6 mmdc registers */
+void mx6_dram_cfg(const struct mx6_ddr_sysinfo *,
+		  const struct mx6_mmdc_calibration *,
+		  const struct mx6_ddr3_cfg *);
+
+#endif /* CONFIG_SPL_BUILD */
 
 #define MX6_MMDC_P0_MDCTL	0x021b0000
 #define MX6_MMDC_P0_MDPDC	0x021b0004

Best regards,
Stefano Babic

Signature · 5 lines
=====================================================================
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: +49-8142-66989-53 Fax: +49-8142-66989-80 Email: sbabic at denx.de
=====================================================================
author
#27 lore raw

PATCH 7/12 MX6: add structs for mmdc and ddr iomux registers

Quoted 85 lines · Stefano Babic

Hi Tim,

Quoted 82 lines · Tim Harvey

Add memory-mapped structures for MMDC iomux and configuration. Note that while the MMDC configuration registers are common between the IMX6DQ (IMX6DUAL/IMX6QUAD) and IMX6SDL (IMX6SOLO/IMX6DUALLITE) types the iomux registers differ. This requires two sets of structures.

Add structures to describe DDR3 device information, system information (memory layout, etc), and MMDC calibration regitsers that can be used to configure the MMDC dynamically.

We define these structures for SPL builds instead of including mx6q-ddr.h and mx6dl-ddr.h which use the same namespace and are only useful for imximage cfg files.

---
v2:
- split out from original mmdc configuration patch
- only define for SPL build
- do not include mx6q-ddr.h and mx6dl-ddr.h for SPL build - these use the same namespace and are only useful for imximage cfg files

---
 arch/arm/include/asm/arch-mx6/mx6-ddr.h | 231 ++++++++++++++++++++++++++++++++
 1 file changed, 231 insertions(+)
arch/arm/include/asm/arch-mx6/mx6-ddr.h +43 -0
index 43d377a..d544d2e 100644
@@ -6,6 +6,7 @@
 #ifndef __ASM_ARCH_MX6_DDR_H__
 #define __ASM_ARCH_MX6_DDR_H__
 
+#ifndef CONFIG_SPL_BUILD
 #ifdef CONFIG_MX6Q
 #include "mx6q-ddr.h"
 #else
@@ -15,6 +16,236 @@
 #error "Please select cpu"
 #endif       /* CONFIG_MX6DL or CONFIG_MX6S */
 #endif       /* CONFIG_MX6Q */
+#else
+
+/* MMDC P0/P1 Registers */
+struct mmdc_p_regs {
+     u32 mdctl;
+     u32 mdpdc;
+     u32 mdotc;
+     u32 mdcfg0;
+     u32 mdcfg1;
+     u32 mdcfg2;
+     u32 mdmisc;
+     u32 mdscr;
+     u32 mdref;
+     u32 res1[2];
+     u32 mdrwd;
+     u32 mdor;
+     u32 res2[3];
+     u32 mdasp;
+     u32 res3[240];
+     u32 mapsr;
+     u32 res4[254];
+     u32 mpzqhwctrl;
+     u32 res5[2];
+     u32 mpwldectrl0;
+     u32 mpwldectrl1;
+     u32 res6;
+     u32 mpodtctrl;
+     u32 mprddqby0dl;
+     u32 mprddqby1dl;
+     u32 mprddqby2dl;
+     u32 mprddqby3dl;
+     u32 res7[4];
+     u32 mpdgctrl0;
+     u32 mpdgctrl1;
+     u32 res8;
+     u32 mprddlctl;
+     u32 res9;
+     u32 mpwrdlctl;
+     u32 res10[25];
+     u32 mpmur0;
+};
+
Quoted 8 lines

arch/arm/include/asm/arch-mx6/mx6-ddr.h line 64

Quoted 4 lines
arch/arm/include/asm/arch-mx6/mx6-ddr.h +4 -0
+/*
+ * MMDC iomux registers (pinctl/padctl) - (different for IMX6DQ vs IMX6SDL)
+ */
+#define MX6DQ_IOM_DDR_BASE      0x020e0500

It is only a question - having the value here let us know where the registers are located. Anyway, registers' offsets are stored in the imx-regs.h file of the SOC. Which is the reason to set them here ?

I felt they belonged with the ddr structures themselves. I can move them but then will someone claim that the ddr structures should also be moved?

Tim

author
#28 lore raw

PATCH 8/12 MX6: add mmdc configuration for MX6Q/MX6DL

In reply to Tim Harvey

Add functions for configuring MMDC iomux and configuration based on board-specific configurations.

---
v2:
- split out mmdc and iomux structs into separate patch

---
 arch/arm/cpu/armv7/mx6/Makefile |   1 +
 arch/arm/cpu/armv7/mx6/ddr.c    | 469 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 470 insertions(+)
 create mode 100644 arch/arm/cpu/armv7/mx6/ddr.c
arch/arm/cpu/armv7/mx6/Makefile +1 -0
index d7285fc..6dc9f8e 100644
@@ -8,4 +8,5 @@
 #
 
 obj-y	:= soc.o clock.o
+obj-$(CONFIG_SPL_BUILD)	     += ddr.o
 obj-$(CONFIG_SECURE_BOOT)    += hab.o
arch/arm/cpu/armv7/mx6/ddr.c new file +469 -0

469 lines not on this page · raw message

Signature · 1 line
1.8.3.2
#29 lore raw

PATCH 8/12 MX6: add mmdc configuration for MX6Q/MX6DL

Hi Tim,

Quoted 33 lines · Tim Harvey

Add functions for configuring MMDC iomux and configuration based on board-specific configurations.

---
v2:
- split out mmdc and iomux structs into separate patch

---
  arch/arm/cpu/armv7/mx6/Makefile |   1 +
  arch/arm/cpu/armv7/mx6/ddr.c    | 469 ++++++++++++++++++++++++++++++++++++++++
  2 files changed, 470 insertions(+)

create mode 100644 arch/arm/cpu/armv7/mx6/ddr.c

arch/arm/cpu/armv7/mx6/Makefile +1 -0
index d7285fc..6dc9f8e 100644
@@ -8,4 +8,5 @@
  #
 
  obj-y	:= soc.o clock.o
+obj-$(CONFIG_SPL_BUILD)	     += ddr.o
  obj-$(CONFIG_SECURE_BOOT)    += hab.o
arch/arm/cpu/armv7/mx6/ddr.c new file +4 -0
new file mode 100644
index 0000000..1536418
@@ -0,0 +1,469 @@
+/*
+ * Copyright (C) 2014 Gateworks Corporation
+ * Author: Tim Harvey <[email protected]>
+ *

arch/arm/cpu/armv7/mx6/ddr.c line 14

Quoted 10 lines
arch/arm/cpu/armv7/mx6/ddr.c new file +10 -0
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#include <common.h>
+#include <linux/types.h>
+#include <asm/arch/mx6-ddr.h>
+#include <asm/arch/sys_proto.h>
+#include <asm/io.h>
+#include <asm/types.h>
+

Do you think that someone will want to use SPL on i.MX6 with support for only one of the variants?

It seems that this should be conditionally included if i.MX6DQ is supported by the board.

arch/arm/cpu/armv7/mx6/ddr.c line 20

Quoted 7 lines
arch/arm/cpu/armv7/mx6/ddr.c new file +6 -0
+/* Configure MX6DQ mmdc iomux */
+void mx6dq_dram_iocfg(unsigned width,
+		      const struct mx6dq_iomux_ddr_regs *ddr,
+		      const struct mx6dq_iomux_grp_regs *grp)
+{
+	volatile struct mx6dq_iomux_ddr_regs *mx6_ddr_iomux;

...

Ditto for i.MX6SDL:

arch/arm/cpu/armv7/mx6/ddr.c line 95

Quoted 5 lines
arch/arm/cpu/armv7/mx6/ddr.c new file +5 -0
+/* Configure MX6SDL mmdc iomux */
+void mx6sdl_dram_iocfg(unsigned width,
+		       const struct mx6sdl_iomux_ddr_regs *ddr,
+		       const struct mx6sdl_iomux_grp_regs *grp)
+{

Regards,

Eric

author
#30 lore raw

PATCH 8/12 MX6: add mmdc configuration for MX6Q/MX6DL

Quoted 55 lines · Eric Nelson

Hi Tim,

Quoted 36 lines · Tim Harvey

Add functions for configuring MMDC iomux and configuration based on board-specific configurations.

---
v2:
- split out mmdc and iomux structs into separate patch

---
  arch/arm/cpu/armv7/mx6/Makefile |   1 +
  arch/arm/cpu/armv7/mx6/ddr.c    | 469
++++++++++++++++++++++++++++++++++++++++
  2 files changed, 470 insertions(+)

create mode 100644 arch/arm/cpu/armv7/mx6/ddr.c

arch/arm/cpu/armv7/mx6/Makefile +1 -0
index d7285fc..6dc9f8e 100644
@@ -8,4 +8,5 @@
  #
 
  obj-y := soc.o clock.o
+obj-$(CONFIG_SPL_BUILD)             += ddr.o
  obj-$(CONFIG_SECURE_BOOT)    += hab.o
arch/arm/cpu/armv7/mx6/ddr.c new file +4 -0
new file mode 100644
index 0000000..1536418
@@ -0,0 +1,469 @@
+/*
+ * Copyright (C) 2014 Gateworks Corporation
+ * Author: Tim Harvey <[email protected]>
+ *

arch/arm/cpu/armv7/mx6/ddr.c line 14

Quoted 10 lines
arch/arm/cpu/armv7/mx6/ddr.c new file +10 -0
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#include <common.h>
+#include <linux/types.h>
+#include <asm/arch/mx6-ddr.h>
+#include <asm/arch/sys_proto.h>
+#include <asm/io.h>
+#include <asm/types.h>
+

Do you think that someone will want to use SPL on i.MX6 with support for only one of the variants?

Quoted 3 lines

It seems that this should be conditionally included if i.MX6DQ is supported by the board.

Eric,

Yes - that makes sense. Someone could have a single CPU but have several memory variants. I'm not sure how much codespace it will save but things are tight at 64KB max.

I can wrap the functions and their calls with an:

#if defined(MX6QDL) || defined(MX6Q) || defined(MX6D)

Quoted 9 lines

arch/arm/cpu/armv7/mx6/ddr.c line 20

Quoted 9 lines
arch/arm/cpu/armv7/mx6/ddr.c new file +6 -0
+/* Configure MX6DQ mmdc iomux */
+void mx6dq_dram_iocfg(unsigned width,
+                     const struct mx6dq_iomux_ddr_regs *ddr,
+                     const struct mx6dq_iomux_grp_regs *grp)
+{
+       volatile struct mx6dq_iomux_ddr_regs *mx6_ddr_iomux;
Quoted 4 lines

...

Ditto for i.MX6SDL:

and:

#if defined(MX6QDL) || defined(MX6DL) || defined(MX6S)

Tim

Quoted 12 lines

arch/arm/cpu/armv7/mx6/ddr.c line 95

Quoted 6 lines
arch/arm/cpu/armv7/mx6/ddr.c new file +5 -0
+/* Configure MX6SDL mmdc iomux */
+void mx6sdl_dram_iocfg(unsigned width,
+                    const struct mx6sdl_iomux_ddr_regs *ddr,
+                    const struct mx6sdl_iomux_grp_regs *grp)
+{

Regards,

Eric

#31 lore raw

PATCH 8/12 MX6: add mmdc configuration for MX6Q/MX6DL

Hi Tim,

Quoted 16 lines · Tim Harvey
Quoted 11 lines · Eric Nelson

Hi Tim,

<snip>

Do you think that someone will want to use SPL on i.MX6 with support for only one of the variants?

It seems that this should be conditionally included if i.MX6DQ is supported by the board.

Eric,

Quoted 8 lines

Yes - that makes sense. Someone could have a single CPU but have several memory variants. I'm not sure how much codespace it will save but things are tight at 64KB max.

I can wrap the functions and their calls with an:

#if defined(MX6QDL) || defined(MX6Q) || defined(MX6D)

Perfect.

Quoted 9 lines
Quoted 9 lines
Quoted 9 lines
arch/arm/cpu/armv7/mx6/ddr.c new file +6 -0
+/* Configure MX6DQ mmdc iomux */
+void mx6dq_dram_iocfg(unsigned width,
+                     const struct mx6dq_iomux_ddr_regs *ddr,
+                     const struct mx6dq_iomux_grp_regs *grp)
+{
+       volatile struct mx6dq_iomux_ddr_regs *mx6_ddr_iomux;
Quoted 9 lines
Quoted 4 lines

...

Ditto for i.MX6SDL:

and:

#if defined(MX6QDL) || defined(MX6DL) || defined(MX6S)

Cool.

#32 lore raw

PATCH 8/12 MX6: add mmdc configuration for MX6Q/MX6DL

In reply to Eric Nelson

Hello,

Quoted 43 lines · Eric Nelson
Quoted 42 lines · Tim Harvey

Add functions for configuring MMDC iomux and configuration based on board-specific configurations.

---
v2:
- split out mmdc and iomux structs into separate patch

---
  arch/arm/cpu/armv7/mx6/Makefile |   1 +
  arch/arm/cpu/armv7/mx6/ddr.c    | 469
++++++++++++++++++++++++++++++++++++++++
  2 files changed, 470 insertions(+)

create mode 100644 arch/arm/cpu/armv7/mx6/ddr.c

arch/arm/cpu/armv7/mx6/Makefile +1 -0
index d7285fc..6dc9f8e 100644
@@ -8,4 +8,5 @@
  #
 
  obj-y := soc.o clock.o
+obj-$(CONFIG_SPL_BUILD)             += ddr.o
  obj-$(CONFIG_SECURE_BOOT)    += hab.o
arch/arm/cpu/armv7/mx6/ddr.c new file +10 -0
new file mode 100644
index 0000000..1536418
@@ -0,0 +1,469 @@
+/*
+ * Copyright (C) 2014 Gateworks Corporation
+ * Author: Tim Harvey <[email protected]>
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#include <common.h>
+#include <linux/types.h>
+#include <asm/arch/mx6-ddr.h>
Quoted 8 lines

arch/arm/cpu/armv7/mx6/ddr.c line 14

Quoted 4 lines
arch/arm/cpu/armv7/mx6/ddr.c new file +4 -0
+#include <asm/arch/sys_proto.h>
+#include <asm/io.h>
+#include <asm/types.h>
+

Do you think that someone will want to use SPL on i.MX6 with support for only one of the variants?

Sure, Falcon mode comes to my mind...

Signature · 3 lines
Otavio Salvador                             O.S. Systems
http://www.ossystems.com.br        http://code.ossystems.com.br
Mobile: +55 (53) 9981-7854            Mobile: +1 (347) 903-9750
author
#33 lore raw

PATCH 9/12 IMX: add additional function for pinmux using an array

In reply to Tim Harvey

Add new function that can take an array of iomux configs, an index, and a stride to allow a multi-dimentional array of pinmux values to be used to define pinmux values per cpu-type.

This takes a different approach to previously proposed solutions which used multiple arrays of pad lists. The goal is to eliminate having these multiple arrays such as 'mx6q_uart1_pads' and 'mx6dl_uart1_pads' which are almost identical copies of each other except for the MX6Q/MX6DL prefix on the PAD.

---
v2:
- moved macros for declaring and using structs for array variant
- removed non-related whitespace cleanup

---
 arch/arm/imx-common/iomux-v3.c             | 19 +++++++++++++++----
 arch/arm/include/asm/imx-common/iomux-v3.h | 15 +++++++++++++++
 2 files changed, 30 insertions(+), 4 deletions(-)
arch/arm/imx-common/iomux-v3.c +15 -4
index b59b802..d3e1e30 100644
@@ -46,12 +46,23 @@ void imx_iomux_v3_setup_pad(iomux_v3_cfg_t pad)
 #endif
 }
 
-void imx_iomux_v3_setup_multiple_pads(iomux_v3_cfg_t const *pad_list,
-				      unsigned count)
+/* configures a list of pads within an array of lists */
+void imx_iomux_v3_setup_multiple_pads_array(iomux_v3_cfg_t const *pad_list,
+					    unsigned count, unsigned list,
+					    unsigned stride)
 {
 	iomux_v3_cfg_t const *p = pad_list;
 	int i;
 
-	for (i = 0; i < count; i++)
-		imx_iomux_v3_setup_pad(*p++);
+	p += list;
+	for (i = 0; i < count; i++) {
+		imx_iomux_v3_setup_pad(*p);
+		p += stride;
+	}
+}
+
+void imx_iomux_v3_setup_multiple_pads(iomux_v3_cfg_t const *pad_list,
+				      unsigned count)
+{
+	imx_iomux_v3_setup_multiple_pads_array(pad_list, count, 0, 1);
 }
arch/arm/include/asm/imx-common/iomux-v3.h +15 -0
index dec11a1..2f7a1cb 100644
@@ -167,7 +167,22 @@ typedef u64 iomux_v3_cfg_t;
 #define GPIO_PORTF		(5 << GPIO_PORT_SHIFT)
 
 void imx_iomux_v3_setup_pad(iomux_v3_cfg_t pad);
+void imx_iomux_v3_setup_multiple_pads_array(iomux_v3_cfg_t const *pad_list,
+					    unsigned count, unsigned list,
+					    unsigned stride);
 void imx_iomux_v3_setup_multiple_pads(iomux_v3_cfg_t const *pad_list,
 				     unsigned count);
 
+/* macros for declaring and using pinmux array */
+#define IOMUX_PADS(x) (MX6Q_##x), (MX6DL_##x)
+#define SETUP_IOMUX_PAD(def)					\
+if (is_cpu_type(MXC_CPU_MX6Q)) {				\
+	imx_iomux_v3_setup_pad(MX6Q_##def);			\
+} else {							\
+	imx_iomux_v3_setup_pad(MX6DL_##def);			\
+}
+#define SETUP_IOMUX_PADS(x)					\
+	imx_iomux_v3_setup_multiple_pads_array(x,		\
+	ARRAY_SIZE(x)/2, is_cpu_type(MXC_CPU_MX6Q) ? 0 : 1, 2)
+
 #endif	/* __MACH_IOMUX_V3_H__*/
Signature · 1 line
1.8.3.2
#34 lore raw

PATCH 9/12 IMX: add additional function for pinmux using an array

Hi Tim,

Quoted 10 lines · Tim Harvey

Add new function that can take an array of iomux configs, an index, and a stride to allow a multi-dimentional array of pinmux values to be used to define pinmux values per cpu-type.

This takes a different approach to previously proposed solutions which used multiple arrays of pad lists. The goal is to eliminate having these multiple arrays such as 'mx6q_uart1_pads' and 'mx6dl_uart1_pads' which are almost identical copies of each other except for the MX6Q/MX6DL prefix on the PAD.

I don't think a blind reference to the previously proposed solution helps in understanding this patch, and an example would be more helpful.

Quoted 15 lines

---
v2:
- moved macros for declaring and using structs for array variant
- removed non-related whitespace cleanup

---
  arch/arm/imx-common/iomux-v3.c             | 19 +++++++++++++++----
  arch/arm/include/asm/imx-common/iomux-v3.h | 15 +++++++++++++++
  2 files changed, 30 insertions(+), 4 deletions(-)
arch/arm/imx-common/iomux-v3.c +0 -0
index b59b802..d3e1e30 100644

arch/arm/imx-common/iomux-v3.c void imx_iomux_v3_setup_pad(iomux_v3_cfg_t pad) · line 48

Quoted 3 lines
arch/arm/imx-common/iomux-v3.c +0 -0
@@ -46,12 +46,23 @@ void imx_iomux_v3_setup_pad(iomux_v3_cfg_t pad)
  #endif
  }
 

It's odd that git generated removal and re-insertion of this bit:

arch/arm/imx-common/iomux-v3.c void imx_iomux_v3_setup_pad(iomux_v3_cfg_t pad) · line 50

Quoted 2 lines
arch/arm/imx-common/iomux-v3.c +0 -2
-void imx_iomux_v3_setup_multiple_pads(iomux_v3_cfg_t const *pad_list,
-				      unsigned count)

I think 'start_offs' would be clearer than 'list'.

The function name ..._array() also doesn't really capture what's going on here. Naming is hard though, and I'm not coming up with something else.

Perhaps 'sparse', 'skip', or alternate?

Quoted 27 lines
arch/arm/imx-common/iomux-v3.c +15 -2
+/* configures a list of pads within an array of lists */
+void imx_iomux_v3_setup_multiple_pads_array(iomux_v3_cfg_t const *pad_list,
+					    unsigned count, unsigned list,
+					    unsigned stride)
  {
  	iomux_v3_cfg_t const *p = pad_list;
  	int i;
 
-	for (i = 0; i < count; i++)
-		imx_iomux_v3_setup_pad(*p++);
+	p += list;
+	for (i = 0; i < count; i++) {
+		imx_iomux_v3_setup_pad(*p);
+		p += stride;
+	}
+}
+
+void imx_iomux_v3_setup_multiple_pads(iomux_v3_cfg_t const *pad_list,
+				      unsigned count)
+{
+	imx_iomux_v3_setup_multiple_pads_array(pad_list, count, 0, 1);
  }
arch/arm/include/asm/imx-common/iomux-v3.h +0 -0
index dec11a1..2f7a1cb 100644

arch/arm/include/asm/imx-common/iomux-v3.h typedef u64 iomux_v3_cfg_t; · line 172

Quoted 6 lines
arch/arm/include/asm/imx-common/iomux-v3.h +3 -0
@@ -167,7 +167,22 @@ typedef u64 iomux_v3_cfg_t;
  #define GPIO_PORTF		(5 << GPIO_PORT_SHIFT)
 
  void imx_iomux_v3_setup_pad(iomux_v3_cfg_t pad);
+void imx_iomux_v3_setup_multiple_pads_array(iomux_v3_cfg_t const *pad_list,
+					    unsigned count, unsigned list,
+					    unsigned stride);

Ditto about function and parameter naming.

arch/arm/include/asm/imx-common/iomux-v3.h typedef u64 iomux_v3_cfg_t; · line 175

Quoted 3 lines
arch/arm/include/asm/imx-common/iomux-v3.h +0 -0
  void imx_iomux_v3_setup_multiple_pads(iomux_v3_cfg_t const *pad_list,
  				     unsigned count);
 

It doesn't get any simpler than this:

arch/arm/include/asm/imx-common/iomux-v3.h typedef u64 iomux_v3_cfg_t; · line 177

Quoted 2 lines
arch/arm/include/asm/imx-common/iomux-v3.h +2 -0
+/* macros for declaring and using pinmux array */
+#define IOMUX_PADS(x) (MX6Q_##x), (MX6DL_##x)

In a similar vein to my comment about Patch 8, I do wonder if a minor extension of this will allow use with a single-variant board though.

We have some custom designs that really only function with one variant (usually i.MX6DQ) and it seems wrong to have the other variant included.

arch/arm/include/asm/imx-common/iomux-v3.h typedef u64 iomux_v3_cfg_t; · line 188

Quoted 12 lines
arch/arm/include/asm/imx-common/iomux-v3.h +10 -0
+#define SETUP_IOMUX_PAD(def)					\
+if (is_cpu_type(MXC_CPU_MX6Q)) {				\
+	imx_iomux_v3_setup_pad(MX6Q_##def);			\
+} else {							\
+	imx_iomux_v3_setup_pad(MX6DL_##def);			\
+}
+#define SETUP_IOMUX_PADS(x)					\
+	imx_iomux_v3_setup_multiple_pads_array(x,		\
+	ARRAY_SIZE(x)/2, is_cpu_type(MXC_CPU_MX6Q) ? 0 : 1, 2)
+
  #endif	/* __MACH_IOMUX_V3_H__*/

Please don't mis-interpret my comments as any form of Nack.

This patch moves the ball forward, and the approach of building two lists into one prevents duplication of tables quite nicely.

Regards,

Eric

author
#35 lore raw

PATCH 9/12 IMX: add additional function for pinmux using an array

Quoted 2 lines · Eric Nelson

Hi Tim,

Hi Eric,

Quoted 16 lines · Tim Harvey
Quoted 6 lines

Add new function that can take an array of iomux configs, an index, and a stride to allow a multi-dimentional array of pinmux values to be used to define pinmux values per cpu-type.

Quoted 8 lines

This takes a different approach to previously proposed solutions which used
multiple arrays of pad lists. The goal is to eliminate having these multiple
arrays such as 'mx6q_uart1_pads' and 'mx6dl_uart1_pads' which are almost identical copies of each other except for the MX6Q/MX6DL prefix on the PAD.

Quoted 2 lines

I don't think a blind reference to the previously proposed solution helps in understanding this patch, and an example would be more helpful.

agreed - will remove

Quoted 1 line

<snip>

Quoted 6 lines

arch/arm/imx-common/iomux-v3.c void imx_iomux_v3_setup_pad(iomux_v3_cfg_t pad) · line 50

Quoted 3 lines
arch/arm/imx-common/iomux-v3.c +0 -2
-void imx_iomux_v3_setup_multiple_pads(iomux_v3_cfg_t const *pad_list,
-                                     unsigned count)

I think 'start_offs' would be clearer than 'list'.

agreed - will change to 'start_offs'

Quoted 6 lines

The function name ..._array() also doesn't really capture what's going on here. Naming is hard though, and I'm not coming up with something else.

Perhaps 'sparse', 'skip', or alternate?

ya, I'm not sure anything else is more explanatory when we are doing something like this. Its bad enough that its likely difficult for someone to understand their first time through that we are doing this to eliminate multiple structs.

Quoted 1 line

<snip>

Quoted 8 lines

arch/arm/include/asm/imx-common/iomux-v3.h typedef u64 iomux_v3_cfg_t; · line 177

Quoted 3 lines
arch/arm/include/asm/imx-common/iomux-v3.h +2 -0
+/* macros for declaring and using pinmux array */
+#define IOMUX_PADS(x) (MX6Q_##x), (MX6DL_##x)

In a similar vein to my comment about Patch 8, I do wonder if a minor extension of this will allow use with a single-variant board though.

for a single-variant one would just use the original IOMUX_PAD/imx_iomux_v3_setup_pad/imx_iomux_v3_setup_pad right?

Quoted 21 lines

We have some custom designs that really only function with one variant (usually i.MX6DQ) and it seems wrong to have the other variant included.

arch/arm/include/asm/imx-common/iomux-v3.h typedef u64 iomux_v3_cfg_t; · line 188

Quoted 12 lines
arch/arm/include/asm/imx-common/iomux-v3.h +10 -0
+#define SETUP_IOMUX_PAD(def)                                   \
+if (is_cpu_type(MXC_CPU_MX6Q)) {                               \
+       imx_iomux_v3_setup_pad(MX6Q_##def);                     \
+} else {                                                       \
+       imx_iomux_v3_setup_pad(MX6DL_##def);                    \
+}
+#define SETUP_IOMUX_PADS(x)                                    \
+       imx_iomux_v3_setup_multiple_pads_array(x,               \
+       ARRAY_SIZE(x)/2, is_cpu_type(MXC_CPU_MX6Q) ? 0 : 1, 2)
+
  #endif        /* __MACH_IOMUX_V3_H__*/

Please don't mis-interpret my comments as any form of Nack.

Quoted 8 lines

This patch moves the ball forward, and the approach of building two lists into one prevents duplication of tables quite nicely.

Regards,

Eric

Thanks for the review!

Tim

#36 lore raw

PATCH 9/12 IMX: add additional function for pinmux using an array

Quoted 2 lines · Tim Harvey

On Tue, Apr 29, 2014 at 8:22 AM, Eric Nelson
<[email protected]> wrote:

<snip>

Quoted 9 lines
Quoted 5 lines

The function name ..._array() also doesn't really capture what's going on here. Naming is hard though, and I'm not coming up with something else.

Perhaps 'sparse', 'skip', or alternate?

ya, I'm not sure anything else is more explanatory when we are doing something like this. Its bad enough that its likely difficult for someone to understand their first time through that we are doing this to eliminate multiple structs.

Come to think of it, I don't think we need an _array() function at all. The list selection and
stride size are IOMUX_PADS implementation details. It's not something we should expose to
the function user. is_cpu_type() and ifdef(CONFIG_MX6QDL) can be used to decide the
list and stride values inside imx_iomux_v3_setup_multiple_pads(), and then this function
could be used for both single and multi cpu type situations.

Quoted 10 lines

<snip>

Quoted 6 lines

arch/arm/include/asm/imx-common/iomux-v3.h typedef u64 iomux_v3_cfg_t; · line 177

Quoted 2 lines
arch/arm/include/asm/imx-common/iomux-v3.h +2 -0
+/* macros for declaring and using pinmux array */
+#define IOMUX_PADS(x) (MX6Q_##x), (MX6DL_##x)

In a similar vein to my comment about Patch 8, I do wonder if a minor extension of this will allow use with a single-variant board though.

for a single-variant one would just use the original IOMUX_PAD/imx_iomux_v3_setup_pad/imx_iomux_v3_setup_pad right?

They can, but then we don't get to use the same code for both situations.
If we define two versions of IOMUX_PADS: one for multi cpu type, and one for single cpu type, then the pinmux arrays for both situations will be syntactically similar.
When combined with my other suggestion, it will be very easy to take a U-Boot configured for one CPU type, and reconfigure it to support both CPU types.

Quoted 28 lines
Quoted 20 lines

We have some custom designs that really only function with one variant (usually i.MX6DQ) and it seems wrong to have the other variant included.

arch/arm/include/asm/imx-common/iomux-v3.h typedef u64 iomux_v3_cfg_t; · line 188

Quoted 12 lines
arch/arm/include/asm/imx-common/iomux-v3.h +10 -0
+#define SETUP_IOMUX_PAD(def)                                   \
+if (is_cpu_type(MXC_CPU_MX6Q)) {                               \
+       imx_iomux_v3_setup_pad(MX6Q_##def);                     \
+} else {                                                       \
+       imx_iomux_v3_setup_pad(MX6DL_##def);                    \
+}
+#define SETUP_IOMUX_PADS(x)                                    \
+       imx_iomux_v3_setup_multiple_pads_array(x,               \
+       ARRAY_SIZE(x)/2, is_cpu_type(MXC_CPU_MX6Q) ? 0 : 1, 2)
+
   #endif        /* __MACH_IOMUX_V3_H__*/

Please don't mis-interpret my comments as any form of Nack.

Quoted 8 lines

This patch moves the ball forward, and the approach of building two lists into one prevents duplication of tables quite nicely.

Regards,

Eric

Quoted 7 lines

Thanks for the review!

Tim
_______________________________________________
U-Boot mailing list
U-Boot at lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot

--
Regards,
Nikita Kiryanov

author
#37 lore raw

PATCH 9/12 IMX: add additional function for pinmux using an array

Quoted 46 lines · Nikita Kiryanov
Quoted 3 lines · Tim Harvey

On Tue, Apr 29, 2014 at 8:22 AM, Eric Nelson
<[email protected]> wrote:

<snip>

Quoted 10 lines
Quoted 5 lines

The function name ..._array() also doesn't really capture what's going on here. Naming is hard though, and I'm not coming up with something else.

Perhaps 'sparse', 'skip', or alternate?

ya, I'm not sure anything else is more explanatory when we are doing something like this. Its bad enough that its likely difficult for someone to understand their first time through that we are doing this to eliminate multiple structs.

Come to think of it, I don't think we need an _array() function at all. The list selection and
stride size are IOMUX_PADS implementation details. It's not something we should expose to
the function user. is_cpu_type() and ifdef(CONFIG_MX6QDL) can be used to decide the
list and stride values inside imx_iomux_v3_setup_multiple_pads(), and then this function
could be used for both single and multi cpu type situations.

Quoted 11 lines

<snip>

Quoted 8 lines

arch/arm/include/asm/imx-common/iomux-v3.h typedef u64 iomux_v3_cfg_t; · line 177

Quoted 3 lines
arch/arm/include/asm/imx-common/iomux-v3.h +2 -0
+/* macros for declaring and using pinmux array */
+#define IOMUX_PADS(x) (MX6Q_##x), (MX6DL_##x)

In a similar vein to my comment about Patch 8, I do wonder if a minor extension of this will allow use with a single-variant board though.

Quoted 2 lines

for a single-variant one would just use the original IOMUX_PAD/imx_iomux_v3_setup_pad/imx_iomux_v3_setup_pad right?

Quoted 9 lines

They can, but then we don't get to use the same code for both situations.
If we define two versions of IOMUX_PADS: one for multi cpu type, and one for single cpu type, then the pinmux arrays for both situations will be syntactically similar.
When combined with my other suggestion, it will be very easy to take a U-Boot configured for one CPU type, and reconfigure it to support both CPU types.

Nikita,

Excellent idea - I've merged that idea into my new patchset that I will post shortly.

Tim

author
#38 lore raw

PATCH 10/12 imx: ventana: split read_eeprom into standalone file

In reply to Tim Harvey

Split the read_eeprom function out so that it can be shared (ie with SPL)

---
 board/gateworks/gw_ventana/Makefile         |  2 +-
 board/gateworks/gw_ventana/eeprom.c         | 89 +++++++++++++++++++++++++++++
 board/gateworks/gw_ventana/gw_ventana.c     | 89 +----------------------------
 board/gateworks/gw_ventana/ventana_eeprom.h | 11 ++++
 4 files changed, 102 insertions(+), 89 deletions(-)
 create mode 100644 board/gateworks/gw_ventana/eeprom.c
board/gateworks/gw_ventana/Makefile +1 -1
index e8dab89..03bd1fd 100644
@@ -6,5 +6,5 @@
 # SPDX-License-Identifier:  GPL-2.0+
 #
 
-obj-y  := gw_ventana.o gsc.o
+obj-y  := gw_ventana.o gsc.o eeprom.o
 
board/gateworks/gw_ventana/eeprom.c new file +89 -0

89 lines not on this page · raw message

board/gateworks/gw_ventana/gw_ventana.c +1 -88

107 lines not on this page · raw message

board/gateworks/gw_ventana/ventana_eeprom.h +11 -0
index 434b604..5b065be 100644
@@ -103,4 +103,15 @@ enum {
 	EECONFIG_RES15,
 };
 
+enum {
+	GW54proto, /* original GW5400-A prototype */
+	GW51xx,
+	GW52xx,
+	GW53xx,
+	GW54xx,
+	GW_UNKNOWN,
+};
+
+int read_eeprom(int bus, struct ventana_board_info *);
+
 #endif
Signature · 1 line
1.8.3.2
author
#39 lore raw

PATCH 11/12 imx: ventana: auto-configure for IMX6Q vs IMX6DL

In reply to Tim Harvey

use the new iomux function and a macros to create a multi-dimensional array of iomux values without duplicating the defintions.

---
v2:
- use macros that have been moved to iomux-v3.h

---
 board/gateworks/gw_ventana/gw_ventana.c | 493 ++++++++++++++++++++------------
 1 file changed, 311 insertions(+), 182 deletions(-)
board/gateworks/gw_ventana/gw_ventana.c +311 -182
index 3b6bc01..584762f 100644
@@ -85,109 +85,149 @@ int board_type;
 
 /* UART1: Function varies per baseboard */
 iomux_v3_cfg_t const uart1_pads[] = {
-	MX6_PAD_SD3_DAT6__UART1_RX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL),
-	MX6_PAD_SD3_DAT7__UART1_TX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL),
+	IOMUX_PADS(PAD_SD3_DAT6__UART1_RX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL)),
+	IOMUX_PADS(PAD_SD3_DAT7__UART1_TX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL)),
 };
 
 /* UART2: Serial Console */
 iomux_v3_cfg_t const uart2_pads[] = {
-	MX6_PAD_SD4_DAT7__UART2_TX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL),
-	MX6_PAD_SD4_DAT4__UART2_RX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL),
+	IOMUX_PADS(PAD_SD4_DAT7__UART2_TX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL)),
+	IOMUX_PADS(PAD_SD4_DAT4__UART2_RX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL)),
 };
 
 #define PC MUX_PAD_CTRL(I2C_PAD_CTRL)
 
 /* I2C1: GSC */
-struct i2c_pads_info i2c_pad_info0 = {
+struct i2c_pads_info mx6q_i2c_pad_info0 = {
 	.scl = {
-		.i2c_mode = MX6_PAD_EIM_D21__I2C1_SCL | PC,
-		.gpio_mode = MX6_PAD_EIM_D21__GPIO3_IO21 | PC,
+		.i2c_mode = MX6Q_PAD_EIM_D21__I2C1_SCL | PC,
+		.gpio_mode = MX6Q_PAD_EIM_D21__GPIO3_IO21 | PC,
 		.gp = IMX_GPIO_NR(3, 21)
 	},
 	.sda = {
-		.i2c_mode = MX6_PAD_EIM_D28__I2C1_SDA | PC,
-		.gpio_mode = MX6_PAD_EIM_D28__GPIO3_IO28 | PC,
+		.i2c_mode = MX6Q_PAD_EIM_D28__I2C1_SDA | PC,
+		.gpio_mode = MX6Q_PAD_EIM_D28__GPIO3_IO28 | PC,
+		.gp = IMX_GPIO_NR(3, 28)
+	}
+};
+struct i2c_pads_info mx6dl_i2c_pad_info0 = {
+	.scl = {
+		.i2c_mode = MX6DL_PAD_EIM_D21__I2C1_SCL | PC,
+		.gpio_mode = MX6DL_PAD_EIM_D21__GPIO3_IO21 | PC,
+		.gp = IMX_GPIO_NR(3, 21)
+	},
+	.sda = {
+		.i2c_mode = MX6DL_PAD_EIM_D28__I2C1_SDA | PC,
+		.gpio_mode = MX6DL_PAD_EIM_D28__GPIO3_IO28 | PC,
 		.gp = IMX_GPIO_NR(3, 28)
 	}
 };
 
 /* I2C2: PMIC/PCIe Switch/PCIe Clock/Mezz */
-struct i2c_pads_info i2c_pad_info1 = {
+struct i2c_pads_info mx6q_i2c_pad_info1 = {
 	.scl = {
-		.i2c_mode = MX6_PAD_KEY_COL3__I2C2_SCL | PC,
-		.gpio_mode = MX6_PAD_KEY_COL3__GPIO4_IO12 | PC,
+		.i2c_mode = MX6Q_PAD_KEY_COL3__I2C2_SCL | PC,
+		.gpio_mode = MX6Q_PAD_KEY_COL3__GPIO4_IO12 | PC,
 		.gp = IMX_GPIO_NR(4, 12)
 	},
 	.sda = {
-		.i2c_mode = MX6_PAD_KEY_ROW3__I2C2_SDA | PC,
-		.gpio_mode = MX6_PAD_KEY_ROW3__GPIO4_IO13 | PC,
+		.i2c_mode = MX6Q_PAD_KEY_ROW3__I2C2_SDA | PC,
+		.gpio_mode = MX6Q_PAD_KEY_ROW3__GPIO4_IO13 | PC,
+		.gp = IMX_GPIO_NR(4, 13)
+	}
+};
+struct i2c_pads_info mx6dl_i2c_pad_info1 = {
+	.scl = {
+		.i2c_mode = MX6DL_PAD_KEY_COL3__I2C2_SCL | PC,
+		.gpio_mode = MX6DL_PAD_KEY_COL3__GPIO4_IO12 | PC,
+		.gp = IMX_GPIO_NR(4, 12)
+	},
+	.sda = {
+		.i2c_mode = MX6DL_PAD_KEY_ROW3__I2C2_SDA | PC,
+		.gpio_mode = MX6DL_PAD_KEY_ROW3__GPIO4_IO13 | PC,
 		.gp = IMX_GPIO_NR(4, 13)
 	}
 };
 
 /* I2C3: Misc/Expansion */
-struct i2c_pads_info i2c_pad_info2 = {
+struct i2c_pads_info mx6q_i2c_pad_info2 = {
+	.scl = {
+		.i2c_mode = MX6Q_PAD_GPIO_3__I2C3_SCL | PC,
+		.gpio_mode = MX6Q_PAD_GPIO_3__GPIO1_IO03 | PC,
+		.gp = IMX_GPIO_NR(1, 3)
+	},
+	.sda = {
+		.i2c_mode = MX6Q_PAD_GPIO_6__I2C3_SDA | PC,
+		.gpio_mode = MX6Q_PAD_GPIO_6__GPIO1_IO06 | PC,
+		.gp = IMX_GPIO_NR(1, 6)
+	}
+};
+struct i2c_pads_info mx6dl_i2c_pad_info2 = {
 	.scl = {
-		.i2c_mode = MX6_PAD_GPIO_3__I2C3_SCL | PC,
-		.gpio_mode = MX6_PAD_GPIO_3__GPIO1_IO03 | PC,
+		.i2c_mode = MX6DL_PAD_GPIO_3__I2C3_SCL | PC,
+		.gpio_mode = MX6DL_PAD_GPIO_3__GPIO1_IO03 | PC,
 		.gp = IMX_GPIO_NR(1, 3)
 	},
 	.sda = {
-		.i2c_mode = MX6_PAD_GPIO_6__I2C3_SDA | PC,
-		.gpio_mode = MX6_PAD_GPIO_6__GPIO1_IO06 | PC,
+		.i2c_mode = MX6DL_PAD_GPIO_6__I2C3_SDA | PC,
+		.gpio_mode = MX6DL_PAD_GPIO_6__GPIO1_IO06 | PC,
 		.gp = IMX_GPIO_NR(1, 6)
 	}
 };
 
 /* MMC */
 iomux_v3_cfg_t const usdhc3_pads[] = {
-	MX6_PAD_SD3_CLK__SD3_CLK    | MUX_PAD_CTRL(USDHC_PAD_CTRL),
-	MX6_PAD_SD3_CMD__SD3_CMD    | MUX_PAD_CTRL(USDHC_PAD_CTRL),
-	MX6_PAD_SD3_DAT0__SD3_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
-	MX6_PAD_SD3_DAT1__SD3_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
-	MX6_PAD_SD3_DAT2__SD3_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
-	MX6_PAD_SD3_DAT3__SD3_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
-	MX6_PAD_SD3_DAT5__GPIO7_IO00  | MUX_PAD_CTRL(NO_PAD_CTRL), /* CD */
+	IOMUX_PADS(PAD_SD3_CLK__SD3_CLK    | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
+	IOMUX_PADS(PAD_SD3_CMD__SD3_CMD    | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
+	IOMUX_PADS(PAD_SD3_DAT0__SD3_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
+	IOMUX_PADS(PAD_SD3_DAT1__SD3_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
+	IOMUX_PADS(PAD_SD3_DAT2__SD3_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
+	IOMUX_PADS(PAD_SD3_DAT3__SD3_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
+	/* CD */
+	IOMUX_PADS(PAD_SD3_DAT5__GPIO7_IO00  | MUX_PAD_CTRL(NO_PAD_CTRL)),
 };
 
 /* ENET */
 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),
+	IOMUX_PADS(PAD_ENET_MDIO__ENET_MDIO  | MUX_PAD_CTRL(ENET_PAD_CTRL)),
+	IOMUX_PADS(PAD_ENET_MDC__ENET_MDC    | MUX_PAD_CTRL(ENET_PAD_CTRL)),
+	IOMUX_PADS(PAD_RGMII_TXC__RGMII_TXC  | MUX_PAD_CTRL(ENET_PAD_CTRL)),
+	IOMUX_PADS(PAD_RGMII_TD0__RGMII_TD0  | MUX_PAD_CTRL(ENET_PAD_CTRL)),
+	IOMUX_PADS(PAD_RGMII_TD1__RGMII_TD1  | MUX_PAD_CTRL(ENET_PAD_CTRL)),
+	IOMUX_PADS(PAD_RGMII_TD2__RGMII_TD2  | MUX_PAD_CTRL(ENET_PAD_CTRL)),
+	IOMUX_PADS(PAD_RGMII_TD3__RGMII_TD3  | MUX_PAD_CTRL(ENET_PAD_CTRL)),
+	IOMUX_PADS(PAD_RGMII_TX_CTL__RGMII_TX_CTL |
+		   MUX_PAD_CTRL(ENET_PAD_CTRL)),
+	IOMUX_PADS(PAD_ENET_REF_CLK__ENET_TX_CLK |
+		   MUX_PAD_CTRL(ENET_PAD_CTRL)),
+	IOMUX_PADS(PAD_RGMII_RXC__RGMII_RXC  | MUX_PAD_CTRL(ENET_PAD_CTRL)),
+	IOMUX_PADS(PAD_RGMII_RD0__RGMII_RD0  | MUX_PAD_CTRL(ENET_PAD_CTRL)),
+	IOMUX_PADS(PAD_RGMII_RD1__RGMII_RD1  | MUX_PAD_CTRL(ENET_PAD_CTRL)),
+	IOMUX_PADS(PAD_RGMII_RD2__RGMII_RD2  | MUX_PAD_CTRL(ENET_PAD_CTRL)),
+	IOMUX_PADS(PAD_RGMII_RD3__RGMII_RD3  | MUX_PAD_CTRL(ENET_PAD_CTRL)),
+	IOMUX_PADS(PAD_RGMII_RX_CTL__RGMII_RX_CTL |
+		   MUX_PAD_CTRL(ENET_PAD_CTRL)),
 	/* PHY nRST */
-	MX6_PAD_ENET_TXD0__GPIO1_IO30		| MUX_PAD_CTRL(NO_PAD_CTRL),
+	IOMUX_PADS(PAD_ENET_TXD0__GPIO1_IO30 | MUX_PAD_CTRL(NO_PAD_CTRL)),
 };
 
 /* NAND */
 iomux_v3_cfg_t const nfc_pads[] = {
-	MX6_PAD_NANDF_CLE__NAND_CLE     | MUX_PAD_CTRL(NO_PAD_CTRL),
-	MX6_PAD_NANDF_ALE__NAND_ALE     | MUX_PAD_CTRL(NO_PAD_CTRL),
-	MX6_PAD_NANDF_WP_B__NAND_WP_B   | MUX_PAD_CTRL(NO_PAD_CTRL),
-	MX6_PAD_NANDF_RB0__NAND_READY_B | MUX_PAD_CTRL(NO_PAD_CTRL),
-	MX6_PAD_NANDF_CS0__NAND_CE0_B   | MUX_PAD_CTRL(NO_PAD_CTRL),
-	MX6_PAD_SD4_CMD__NAND_RE_B      | MUX_PAD_CTRL(NO_PAD_CTRL),
-	MX6_PAD_SD4_CLK__NAND_WE_B      | MUX_PAD_CTRL(NO_PAD_CTRL),
-	MX6_PAD_NANDF_D0__NAND_DATA00   | MUX_PAD_CTRL(NO_PAD_CTRL),
-	MX6_PAD_NANDF_D1__NAND_DATA01   | MUX_PAD_CTRL(NO_PAD_CTRL),
-	MX6_PAD_NANDF_D2__NAND_DATA02   | MUX_PAD_CTRL(NO_PAD_CTRL),
-	MX6_PAD_NANDF_D3__NAND_DATA03   | MUX_PAD_CTRL(NO_PAD_CTRL),
-	MX6_PAD_NANDF_D4__NAND_DATA04   | MUX_PAD_CTRL(NO_PAD_CTRL),
-	MX6_PAD_NANDF_D5__NAND_DATA05   | MUX_PAD_CTRL(NO_PAD_CTRL),
-	MX6_PAD_NANDF_D6__NAND_DATA06   | MUX_PAD_CTRL(NO_PAD_CTRL),
-	MX6_PAD_NANDF_D7__NAND_DATA07   | MUX_PAD_CTRL(NO_PAD_CTRL),
+	IOMUX_PADS(PAD_NANDF_CLE__NAND_CLE     | MUX_PAD_CTRL(NO_PAD_CTRL)),
+	IOMUX_PADS(PAD_NANDF_ALE__NAND_ALE     | MUX_PAD_CTRL(NO_PAD_CTRL)),
+	IOMUX_PADS(PAD_NANDF_WP_B__NAND_WP_B   | MUX_PAD_CTRL(NO_PAD_CTRL)),
+	IOMUX_PADS(PAD_NANDF_RB0__NAND_READY_B | MUX_PAD_CTRL(NO_PAD_CTRL)),
+	IOMUX_PADS(PAD_NANDF_CS0__NAND_CE0_B   | MUX_PAD_CTRL(NO_PAD_CTRL)),
+	IOMUX_PADS(PAD_SD4_CMD__NAND_RE_B      | MUX_PAD_CTRL(NO_PAD_CTRL)),
+	IOMUX_PADS(PAD_SD4_CLK__NAND_WE_B      | MUX_PAD_CTRL(NO_PAD_CTRL)),
+	IOMUX_PADS(PAD_NANDF_D0__NAND_DATA00   | MUX_PAD_CTRL(NO_PAD_CTRL)),
+	IOMUX_PADS(PAD_NANDF_D1__NAND_DATA01   | MUX_PAD_CTRL(NO_PAD_CTRL)),
+	IOMUX_PADS(PAD_NANDF_D2__NAND_DATA02   | MUX_PAD_CTRL(NO_PAD_CTRL)),
+	IOMUX_PADS(PAD_NANDF_D3__NAND_DATA03   | MUX_PAD_CTRL(NO_PAD_CTRL)),
+	IOMUX_PADS(PAD_NANDF_D4__NAND_DATA04   | MUX_PAD_CTRL(NO_PAD_CTRL)),
+	IOMUX_PADS(PAD_NANDF_D5__NAND_DATA05   | MUX_PAD_CTRL(NO_PAD_CTRL)),
+	IOMUX_PADS(PAD_NANDF_D6__NAND_DATA06   | MUX_PAD_CTRL(NO_PAD_CTRL)),
+	IOMUX_PADS(PAD_NANDF_D7__NAND_DATA07   | MUX_PAD_CTRL(NO_PAD_CTRL)),
 };
 
 #ifdef CONFIG_CMD_NAND
@@ -196,7 +236,7 @@ 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));
+	SETUP_IOMUX_PADS(nfc_pads);
 
 	/* config gpmi and bch clock to 100 MHz */
 	clrsetbits_le32(&mxc_ccm->cs2cdr,
@@ -222,7 +262,7 @@ static void setup_gpmi_nand(void)
 
 static void setup_iomux_enet(void)
 {
-	imx_iomux_v3_setup_multiple_pads(enet_pads, ARRAY_SIZE(enet_pads));
+	SETUP_IOMUX_PADS(enet_pads);
 
 	/* toggle PHY_RST# */
 	gpio_direction_output(GP_PHY_RST, 0);
@@ -232,35 +272,36 @@ static void setup_iomux_enet(void)
 
 static void setup_iomux_uart(void)
 {
-	imx_iomux_v3_setup_multiple_pads(uart1_pads, ARRAY_SIZE(uart1_pads));
-	imx_iomux_v3_setup_multiple_pads(uart2_pads, ARRAY_SIZE(uart2_pads));
+	SETUP_IOMUX_PADS(uart1_pads);
+	SETUP_IOMUX_PADS(uart2_pads);
 }
 
 #ifdef CONFIG_USB_EHCI_MX6
 iomux_v3_cfg_t const usb_pads[] = {
-	MX6_PAD_GPIO_1__USB_OTG_ID   | MUX_PAD_CTRL(DIO_PAD_CTRL),
-	MX6_PAD_KEY_COL4__USB_OTG_OC | MUX_PAD_CTRL(DIO_PAD_CTRL),
-	MX6_PAD_EIM_D22__GPIO3_IO22  | MUX_PAD_CTRL(DIO_PAD_CTRL), /* OTG PWR */
+	IOMUX_PADS(PAD_GPIO_1__USB_OTG_ID   | MUX_PAD_CTRL(DIO_PAD_CTRL)),
+	IOMUX_PADS(PAD_KEY_COL4__USB_OTG_OC | MUX_PAD_CTRL(DIO_PAD_CTRL)),
+	/* OTG PWR */
+	IOMUX_PADS(PAD_EIM_D22__GPIO3_IO22  | MUX_PAD_CTRL(DIO_PAD_CTRL)),
 };
 
 int board_ehci_hcd_init(int port)
 {
 	struct ventana_board_info *info = &ventana_info;
 
-	imx_iomux_v3_setup_multiple_pads(usb_pads, ARRAY_SIZE(usb_pads));
+	SETUP_IOMUX_PADS(usb_pads);
 
 	/* Reset USB HUB (present on GW54xx/GW53xx) */
 	switch (info->model[3]) {
 	case '3': /* GW53xx */
-		imx_iomux_v3_setup_pad(MX6_PAD_GPIO_9__GPIO1_IO09|
-				       MUX_PAD_CTRL(NO_PAD_CTRL));
+		SETUP_IOMUX_PAD(PAD_GPIO_9__GPIO1_IO09 |
+				MUX_PAD_CTRL(NO_PAD_CTRL));
 		gpio_direction_output(IMX_GPIO_NR(1, 9), 0);
 		mdelay(2);
 		gpio_set_value(IMX_GPIO_NR(1, 9), 1);
 		break;
 	case '4': /* GW54xx */
-		imx_iomux_v3_setup_pad(MX6_PAD_SD1_DAT0__GPIO1_IO16 |
-				       MUX_PAD_CTRL(NO_PAD_CTRL));
+		SETUP_IOMUX_PAD(PAD_SD1_DAT0__GPIO1_IO16 |
+				MUX_PAD_CTRL(NO_PAD_CTRL));
 		gpio_direction_output(IMX_GPIO_NR(1, 16), 0);
 		mdelay(2);
 		gpio_set_value(IMX_GPIO_NR(1, 16), 1);
@@ -292,7 +333,7 @@ int board_mmc_getcd(struct mmc *mmc)
 int board_mmc_init(bd_t *bis)
 {
 	/* Only one USDHC controller on Ventana */
-	imx_iomux_v3_setup_multiple_pads(usdhc3_pads, ARRAY_SIZE(usdhc3_pads));
+	SETUP_IOMUX_PADS(usdhc3_pads);
 	usdhc_cfg.sdhc_clk = mxc_get_clock(MXC_ESDHC3_CLK);
 	usdhc_cfg.max_bus_width = 4;
 
@@ -303,17 +344,16 @@ int board_mmc_init(bd_t *bis)
 #ifdef CONFIG_MXC_SPI
 iomux_v3_cfg_t const ecspi1_pads[] = {
 	/* SS1 */
-	MX6_PAD_EIM_D19__GPIO3_IO19  | 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_D16__ECSPI1_SCLK | MUX_PAD_CTRL(SPI_PAD_CTRL),
+	IOMUX_PADS(PAD_EIM_D19__GPIO3_IO19  | MUX_PAD_CTRL(SPI_PAD_CTRL)),
+	IOMUX_PADS(PAD_EIM_D17__ECSPI1_MISO | MUX_PAD_CTRL(SPI_PAD_CTRL)),
+	IOMUX_PADS(PAD_EIM_D18__ECSPI1_MOSI | MUX_PAD_CTRL(SPI_PAD_CTRL)),
+	IOMUX_PADS(PAD_EIM_D16__ECSPI1_SCLK | MUX_PAD_CTRL(SPI_PAD_CTRL)),
 };
 
 static void setup_spi(void)
 {
 	gpio_direction_output(CONFIG_SF_DEFAULT_CS, 1);
-	imx_iomux_v3_setup_multiple_pads(ecspi1_pads,
-					 ARRAY_SIZE(ecspi1_pads));
+	SETUP_IOMUX_PADS(ecspi1_pads);
 }
 #endif
 
@@ -366,118 +406,118 @@ int board_eth_init(bd_t *bis)
 /* common to add baseboards */
 static iomux_v3_cfg_t const gw_gpio_pads[] = {
 	/* MSATA_EN */
-	MX6_PAD_SD4_DAT0__GPIO2_IO08 | MUX_PAD_CTRL(NO_PAD_CTRL),
+	IOMUX_PADS(PAD_SD4_DAT0__GPIO2_IO08 | MUX_PAD_CTRL(NO_PAD_CTRL)),
 	/* RS232_EN# */
-	MX6_PAD_SD4_DAT3__GPIO2_IO11 | MUX_PAD_CTRL(NO_PAD_CTRL),
+	IOMUX_PADS(PAD_SD4_DAT3__GPIO2_IO11 | MUX_PAD_CTRL(NO_PAD_CTRL)),
 };
 
 /* prototype */
 static iomux_v3_cfg_t const gwproto_gpio_pads[] = {
 	/* PANLEDG# */
-	MX6_PAD_KEY_COL0__GPIO4_IO06 | MUX_PAD_CTRL(NO_PAD_CTRL),
+	IOMUX_PADS(PAD_KEY_COL0__GPIO4_IO06 | MUX_PAD_CTRL(NO_PAD_CTRL)),
 	/* PANLEDR# */
-	MX6_PAD_KEY_ROW0__GPIO4_IO07 | MUX_PAD_CTRL(NO_PAD_CTRL),
+	IOMUX_PADS(PAD_KEY_ROW0__GPIO4_IO07 | MUX_PAD_CTRL(NO_PAD_CTRL)),
 	/* LOCLED# */
-	MX6_PAD_KEY_ROW4__GPIO4_IO15 | MUX_PAD_CTRL(NO_PAD_CTRL),
+	IOMUX_PADS(PAD_KEY_ROW4__GPIO4_IO15 | MUX_PAD_CTRL(NO_PAD_CTRL)),
 	/* RS485_EN */
-	MX6_PAD_SD3_DAT4__GPIO7_IO01 | MUX_PAD_CTRL(NO_PAD_CTRL),
+	IOMUX_PADS(PAD_SD3_DAT4__GPIO7_IO01 | MUX_PAD_CTRL(NO_PAD_CTRL)),
 	/* IOEXP_PWREN# */
-	MX6_PAD_EIM_A19__GPIO2_IO19 | MUX_PAD_CTRL(NO_PAD_CTRL),
+	IOMUX_PADS(PAD_EIM_A19__GPIO2_IO19 | MUX_PAD_CTRL(NO_PAD_CTRL)),
 	/* IOEXP_IRQ# */
-	MX6_PAD_EIM_A20__GPIO2_IO18 | MUX_PAD_CTRL(NO_PAD_CTRL),
+	IOMUX_PADS(PAD_EIM_A20__GPIO2_IO18 | MUX_PAD_CTRL(NO_PAD_CTRL)),
 	/* VID_EN */
-	MX6_PAD_EIM_D31__GPIO3_IO31 | MUX_PAD_CTRL(NO_PAD_CTRL),
+	IOMUX_PADS(PAD_EIM_D31__GPIO3_IO31 | MUX_PAD_CTRL(NO_PAD_CTRL)),
 	/* DIOI2C_DIS# */
-	MX6_PAD_GPIO_19__GPIO4_IO05 | MUX_PAD_CTRL(NO_PAD_CTRL),
+	IOMUX_PADS(PAD_GPIO_19__GPIO4_IO05 | MUX_PAD_CTRL(NO_PAD_CTRL)),
 	/* PCICK_SSON */
-	MX6_PAD_SD1_CLK__GPIO1_IO20 | MUX_PAD_CTRL(NO_PAD_CTRL),
+	IOMUX_PADS(PAD_SD1_CLK__GPIO1_IO20 | MUX_PAD_CTRL(NO_PAD_CTRL)),
 	/* PCI_RST# */
-	MX6_PAD_ENET_TXD1__GPIO1_IO29 | MUX_PAD_CTRL(NO_PAD_CTRL),
+	IOMUX_PADS(PAD_ENET_TXD1__GPIO1_IO29 | MUX_PAD_CTRL(NO_PAD_CTRL)),
 };
 
 static iomux_v3_cfg_t const gw51xx_gpio_pads[] = {
 	/* PANLEDG# */
-	MX6_PAD_KEY_COL0__GPIO4_IO06 | MUX_PAD_CTRL(NO_PAD_CTRL),
+	IOMUX_PADS(PAD_KEY_COL0__GPIO4_IO06 | MUX_PAD_CTRL(NO_PAD_CTRL)),
 	/* PANLEDR# */
-	MX6_PAD_KEY_ROW0__GPIO4_IO07 | MUX_PAD_CTRL(NO_PAD_CTRL),
+	IOMUX_PADS(PAD_KEY_ROW0__GPIO4_IO07 | MUX_PAD_CTRL(NO_PAD_CTRL)),
 	/* IOEXP_PWREN# */
-	MX6_PAD_EIM_A19__GPIO2_IO19 | MUX_PAD_CTRL(NO_PAD_CTRL),
+	IOMUX_PADS(PAD_EIM_A19__GPIO2_IO19 | MUX_PAD_CTRL(NO_PAD_CTRL)),
 	/* IOEXP_IRQ# */
-	MX6_PAD_EIM_A20__GPIO2_IO18 | MUX_PAD_CTRL(NO_PAD_CTRL),
+	IOMUX_PADS(PAD_EIM_A20__GPIO2_IO18 | MUX_PAD_CTRL(NO_PAD_CTRL)),
 
 	/* GPS_SHDN */
-	MX6_PAD_GPIO_2__GPIO1_IO02 | MUX_PAD_CTRL(NO_PAD_CTRL),
+	IOMUX_PADS(PAD_GPIO_2__GPIO1_IO02 | MUX_PAD_CTRL(NO_PAD_CTRL)),
 	/* VID_PWR */
-	MX6_PAD_CSI0_DATA_EN__GPIO5_IO20 | MUX_PAD_CTRL(NO_PAD_CTRL),
+	IOMUX_PADS(PAD_CSI0_DATA_EN__GPIO5_IO20 | MUX_PAD_CTRL(NO_PAD_CTRL)),
 	/* PCI_RST# */
-	MX6_PAD_GPIO_0__GPIO1_IO00 | MUX_PAD_CTRL(NO_PAD_CTRL),
+	IOMUX_PADS(PAD_GPIO_0__GPIO1_IO00 | MUX_PAD_CTRL(NO_PAD_CTRL)),
 };
 
 static iomux_v3_cfg_t const gw52xx_gpio_pads[] = {
 	/* PANLEDG# */
-	MX6_PAD_KEY_COL0__GPIO4_IO06 | MUX_PAD_CTRL(NO_PAD_CTRL),
+	IOMUX_PADS(PAD_KEY_COL0__GPIO4_IO06 | MUX_PAD_CTRL(NO_PAD_CTRL)),
 	/* PANLEDR# */
-	MX6_PAD_KEY_ROW0__GPIO4_IO07 | MUX_PAD_CTRL(NO_PAD_CTRL),
+	IOMUX_PADS(PAD_KEY_ROW0__GPIO4_IO07 | MUX_PAD_CTRL(NO_PAD_CTRL)),
 	/* IOEXP_PWREN# */
-	MX6_PAD_EIM_A19__GPIO2_IO19 | MUX_PAD_CTRL(NO_PAD_CTRL),
+	IOMUX_PADS(PAD_EIM_A19__GPIO2_IO19 | MUX_PAD_CTRL(NO_PAD_CTRL)),
 	/* IOEXP_IRQ# */
-	MX6_PAD_EIM_A20__GPIO2_IO18 | MUX_PAD_CTRL(NO_PAD_CTRL),
+	IOMUX_PADS(PAD_EIM_A20__GPIO2_IO18 | MUX_PAD_CTRL(NO_PAD_CTRL)),
 
 	/* MX6_LOCLED# */
-	MX6_PAD_KEY_ROW4__GPIO4_IO15 | MUX_PAD_CTRL(NO_PAD_CTRL),
+	IOMUX_PADS(PAD_KEY_ROW4__GPIO4_IO15 | MUX_PAD_CTRL(NO_PAD_CTRL)),
 	/* GPS_SHDN */
-	MX6_PAD_ENET_RXD0__GPIO1_IO27 | MUX_PAD_CTRL(NO_PAD_CTRL),
+	IOMUX_PADS(PAD_ENET_RXD0__GPIO1_IO27 | MUX_PAD_CTRL(NO_PAD_CTRL)),
 	/* USBOTG_SEL */
-	MX6_PAD_GPIO_2__GPIO1_IO02 | MUX_PAD_CTRL(NO_PAD_CTRL),
+	IOMUX_PADS(PAD_GPIO_2__GPIO1_IO02 | MUX_PAD_CTRL(NO_PAD_CTRL)),
 	/* VID_PWR */
-	MX6_PAD_EIM_D31__GPIO3_IO31 | MUX_PAD_CTRL(NO_PAD_CTRL),
+	IOMUX_PADS(PAD_EIM_D31__GPIO3_IO31 | MUX_PAD_CTRL(NO_PAD_CTRL)),
 	/* PCI_RST# */
-	MX6_PAD_ENET_TXD1__GPIO1_IO29 | MUX_PAD_CTRL(NO_PAD_CTRL),
+	IOMUX_PADS(PAD_ENET_TXD1__GPIO1_IO29 | MUX_PAD_CTRL(NO_PAD_CTRL)),
 };
 
 static iomux_v3_cfg_t const gw53xx_gpio_pads[] = {
 	/* PANLEDG# */
-	MX6_PAD_KEY_COL0__GPIO4_IO06 | MUX_PAD_CTRL(NO_PAD_CTRL),
+	IOMUX_PADS(PAD_KEY_COL0__GPIO4_IO06 | MUX_PAD_CTRL(NO_PAD_CTRL)),
 	/* PANLEDR# */
-	MX6_PAD_KEY_ROW0__GPIO4_IO07 | MUX_PAD_CTRL(NO_PAD_CTRL),
+	IOMUX_PADS(PAD_KEY_ROW0__GPIO4_IO07 | MUX_PAD_CTRL(NO_PAD_CTRL)),
 	/* IOEXP_PWREN# */
-	MX6_PAD_EIM_A19__GPIO2_IO19 | MUX_PAD_CTRL(NO_PAD_CTRL),
+	IOMUX_PADS(PAD_EIM_A19__GPIO2_IO19 | MUX_PAD_CTRL(NO_PAD_CTRL)),
 	/* IOEXP_IRQ# */
-	MX6_PAD_EIM_A20__GPIO2_IO18 | MUX_PAD_CTRL(NO_PAD_CTRL),
+	IOMUX_PADS(PAD_EIM_A20__GPIO2_IO18 | MUX_PAD_CTRL(NO_PAD_CTRL)),
 
 	/* MX6_LOCLED# */
-	MX6_PAD_KEY_ROW4__GPIO4_IO15 | MUX_PAD_CTRL(NO_PAD_CTRL),
+	IOMUX_PADS(PAD_KEY_ROW4__GPIO4_IO15 | MUX_PAD_CTRL(NO_PAD_CTRL)),
 	/* GPS_SHDN */
-	MX6_PAD_ENET_RXD0__GPIO1_IO27 | MUX_PAD_CTRL(NO_PAD_CTRL),
+	IOMUX_PADS(PAD_ENET_RXD0__GPIO1_IO27 | MUX_PAD_CTRL(NO_PAD_CTRL)),
 	/* VID_EN */
-	MX6_PAD_EIM_D31__GPIO3_IO31 | MUX_PAD_CTRL(NO_PAD_CTRL),
+	IOMUX_PADS(PAD_EIM_D31__GPIO3_IO31 | MUX_PAD_CTRL(NO_PAD_CTRL)),
 	/* PCI_RST# */
-	MX6_PAD_ENET_TXD1__GPIO1_IO29 | MUX_PAD_CTRL(NO_PAD_CTRL),
+	IOMUX_PADS(PAD_ENET_TXD1__GPIO1_IO29 | MUX_PAD_CTRL(NO_PAD_CTRL)),
 };
 
 static iomux_v3_cfg_t const gw54xx_gpio_pads[] = {
 	/* PANLEDG# */
-	MX6_PAD_KEY_COL0__GPIO4_IO06 | MUX_PAD_CTRL(NO_PAD_CTRL),
+	IOMUX_PADS(PAD_KEY_COL0__GPIO4_IO06 | MUX_PAD_CTRL(NO_PAD_CTRL)),
 	/* PANLEDR# */
-	MX6_PAD_KEY_COL2__GPIO4_IO10 | MUX_PAD_CTRL(NO_PAD_CTRL),
+	IOMUX_PADS(PAD_KEY_COL2__GPIO4_IO10 | MUX_PAD_CTRL(NO_PAD_CTRL)),
 	/* MX6_LOCLED# */
-	MX6_PAD_KEY_ROW4__GPIO4_IO15 | MUX_PAD_CTRL(NO_PAD_CTRL),
+	IOMUX_PADS(PAD_KEY_ROW4__GPIO4_IO15 | MUX_PAD_CTRL(NO_PAD_CTRL)),
 	/* MIPI_DIO */
-	MX6_PAD_SD1_DAT3__GPIO1_IO21 | MUX_PAD_CTRL(NO_PAD_CTRL),
+	IOMUX_PADS(PAD_SD1_DAT3__GPIO1_IO21 | MUX_PAD_CTRL(NO_PAD_CTRL)),
 	/* RS485_EN */
-	MX6_PAD_EIM_D24__GPIO3_IO24 | MUX_PAD_CTRL(NO_PAD_CTRL),
+	IOMUX_PADS(PAD_EIM_D24__GPIO3_IO24 | MUX_PAD_CTRL(NO_PAD_CTRL)),
 	/* IOEXP_PWREN# */
-	MX6_PAD_KEY_ROW0__GPIO4_IO07 | MUX_PAD_CTRL(NO_PAD_CTRL),
+	IOMUX_PADS(PAD_KEY_ROW0__GPIO4_IO07 | MUX_PAD_CTRL(NO_PAD_CTRL)),
 	/* IOEXP_IRQ# */
-	MX6_PAD_KEY_ROW1__GPIO4_IO09 | MUX_PAD_CTRL(NO_PAD_CTRL),
+	IOMUX_PADS(PAD_KEY_ROW1__GPIO4_IO09 | MUX_PAD_CTRL(NO_PAD_CTRL)),
 	/* DIOI2C_DIS# */
-	MX6_PAD_GPIO_19__GPIO4_IO05 | MUX_PAD_CTRL(NO_PAD_CTRL),
+	IOMUX_PADS(PAD_GPIO_19__GPIO4_IO05 | MUX_PAD_CTRL(NO_PAD_CTRL)),
 	/* DIOI2C_DIS# */
-	MX6_PAD_GPIO_19__GPIO4_IO05 | MUX_PAD_CTRL(NO_PAD_CTRL),
+	IOMUX_PADS(PAD_GPIO_19__GPIO4_IO05 | MUX_PAD_CTRL(NO_PAD_CTRL)),
 	/* PCICK_SSON */
-	MX6_PAD_SD1_CLK__GPIO1_IO20 | MUX_PAD_CTRL(NO_PAD_CTRL),
+	IOMUX_PADS(PAD_SD1_CLK__GPIO1_IO20 | MUX_PAD_CTRL(NO_PAD_CTRL)),
 	/* PCI_RST# */
-	MX6_PAD_ENET_TXD1__GPIO1_IO29 | MUX_PAD_CTRL(NO_PAD_CTRL),
+	IOMUX_PADS(PAD_ENET_TXD1__GPIO1_IO29 | MUX_PAD_CTRL(NO_PAD_CTRL)),
 };
 
 /*
@@ -485,9 +525,9 @@ static iomux_v3_cfg_t const gw54xx_gpio_pads[] = {
  * be pinmuxed as a GPIO or in some cases a PWM
  */
 struct dio_cfg {
-	iomux_v3_cfg_t gpio_padmux;
+	iomux_v3_cfg_t gpio_padmux[2];
 	unsigned gpio_param;
-	iomux_v3_cfg_t pwm_padmux;
+	iomux_v3_cfg_t pwm_padmux[2];
 	unsigned pwm_param;
 };
 
@@ -514,16 +554,32 @@ struct ventana gpio_cfg[] = {
 	/* GW5400proto */
 	{
 		.gpio_pads = gw54xx_gpio_pads,
-		.num_pads = ARRAY_SIZE(gw54xx_gpio_pads),
+		.num_pads = ARRAY_SIZE(gw54xx_gpio_pads)/2,
 		.dio_cfg = {
-			{ MX6_PAD_GPIO_9__GPIO1_IO09, IMX_GPIO_NR(1, 9),
-			  MX6_PAD_GPIO_9__PWM1_OUT, 1 },
-			{ MX6_PAD_SD1_DAT2__GPIO1_IO19, IMX_GPIO_NR(1, 19),
-			  MX6_PAD_SD1_DAT2__PWM2_OUT, 2 },
-			{ MX6_PAD_SD4_DAT1__GPIO2_IO09, IMX_GPIO_NR(2, 9),
-			  MX6_PAD_SD4_DAT1__PWM3_OUT, 3 },
-			{ MX6_PAD_SD4_DAT2__GPIO2_IO10, IMX_GPIO_NR(2, 10),
-			  MX6_PAD_SD4_DAT2__PWM4_OUT, 4 },
+			{
+				{ 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
+			},
 		},
 		.leds = {
 			IMX_GPIO_NR(4, 6),
@@ -541,16 +597,32 @@ struct ventana gpio_cfg[] = {
 	/* GW51xx */
 	{
 		.gpio_pads = gw51xx_gpio_pads,
-		.num_pads = ARRAY_SIZE(gw51xx_gpio_pads),
+		.num_pads = ARRAY_SIZE(gw51xx_gpio_pads)/2,
 		.dio_cfg = {
-			{ MX6_PAD_SD1_DAT0__GPIO1_IO16, IMX_GPIO_NR(1, 16),
-			  0, 0 },
-			{ MX6_PAD_SD1_DAT2__GPIO1_IO19, IMX_GPIO_NR(1, 19),
-			  MX6_PAD_SD1_DAT2__PWM2_OUT, 2 },
-			{ MX6_PAD_SD1_DAT1__GPIO1_IO17, IMX_GPIO_NR(1, 17),
-			  MX6_PAD_SD1_DAT1__PWM3_OUT, 3 },
-			{ MX6_PAD_SD1_CMD__GPIO1_IO18, IMX_GPIO_NR(1, 18),
-			  MX6_PAD_SD1_CMD__PWM4_OUT, 4 },
+			{
+				{ 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
+			},
 		},
 		.leds = {
 			IMX_GPIO_NR(4, 6),
@@ -566,16 +638,32 @@ struct ventana gpio_cfg[] = {
 	/* GW52xx */
 	{
 		.gpio_pads = gw52xx_gpio_pads,
-		.num_pads = ARRAY_SIZE(gw52xx_gpio_pads),
+		.num_pads = ARRAY_SIZE(gw52xx_gpio_pads)/2,
 		.dio_cfg = {
-			{ MX6_PAD_SD1_DAT0__GPIO1_IO16, IMX_GPIO_NR(1, 16),
-			  0, 0 },
-			{ MX6_PAD_SD1_DAT2__GPIO1_IO19, IMX_GPIO_NR(1, 19),
-			  MX6_PAD_SD1_DAT2__PWM2_OUT, 2 },
-			{ MX6_PAD_SD1_DAT1__GPIO1_IO17, IMX_GPIO_NR(1, 17),
-			  MX6_PAD_SD1_DAT1__PWM3_OUT, 3 },
-			{ MX6_PAD_SD1_CLK__GPIO1_IO20, IMX_GPIO_NR(1, 20),
-			  0, 0 },
+			{
+				{ 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
+			},
 		},
 		.leds = {
 			IMX_GPIO_NR(4, 6),
@@ -593,16 +681,32 @@ struct ventana gpio_cfg[] = {
 	/* GW53xx */
 	{
 		.gpio_pads = gw53xx_gpio_pads,
-		.num_pads = ARRAY_SIZE(gw53xx_gpio_pads),
+		.num_pads = ARRAY_SIZE(gw53xx_gpio_pads)/2,
 		.dio_cfg = {
-			{ MX6_PAD_SD1_DAT0__GPIO1_IO16, IMX_GPIO_NR(1, 16),
-			  0, 0 },
-			{ MX6_PAD_SD1_DAT2__GPIO1_IO19, IMX_GPIO_NR(1, 19),
-			  MX6_PAD_SD1_DAT2__PWM2_OUT, 2 },
-			{ MX6_PAD_SD1_DAT1__GPIO1_IO17, IMX_GPIO_NR(1, 17),
-			  MX6_PAD_SD1_DAT1__PWM3_OUT, 3 },
-			{ MX6_PAD_SD1_CLK__GPIO1_IO20, IMX_GPIO_NR(1, 20),
-			  0, 0 },
+			{
+				{ 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
+			},
 		},
 		.leds = {
 			IMX_GPIO_NR(4, 6),
@@ -619,16 +723,32 @@ struct ventana gpio_cfg[] = {
 	/* GW54xx */
 	{
 		.gpio_pads = gw54xx_gpio_pads,
-		.num_pads = ARRAY_SIZE(gw54xx_gpio_pads),
+		.num_pads = ARRAY_SIZE(gw54xx_gpio_pads)/2,
 		.dio_cfg = {
-			{ MX6_PAD_GPIO_9__GPIO1_IO09, IMX_GPIO_NR(1, 9),
-			  MX6_PAD_GPIO_9__PWM1_OUT, 1 },
-			{ MX6_PAD_SD1_DAT2__GPIO1_IO19, IMX_GPIO_NR(1, 19),
-			  MX6_PAD_SD1_DAT2__PWM2_OUT, 2 },
-			{ MX6_PAD_SD4_DAT1__GPIO2_IO09, IMX_GPIO_NR(2, 9),
-			  MX6_PAD_SD4_DAT1__PWM3_OUT, 3 },
-			{ MX6_PAD_SD4_DAT2__GPIO2_IO10, IMX_GPIO_NR(2, 10),
-			  MX6_PAD_SD4_DAT2__PWM4_OUT, 4 },
+			{
+				{ 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
+			},
 		},
 		.leds = {
 			IMX_GPIO_NR(4, 6),
@@ -718,6 +838,7 @@ static void setup_board_gpio(int board)
 	for (i = 0; i < 4; i++) {
 		struct dio_cfg *cfg = &gpio_cfg[board].dio_cfg[i];
 		unsigned ctrl = DIO_PAD_CTRL;
+		unsigned cputype = is_cpu_type(MXC_CPU_MX6Q) ? 0 : 1;
 
 		sprintf(arg, "dio%d", i);
 		if (!hwconfig(arg))
@@ -732,14 +853,14 @@ static void setup_board_gpio(int board)
 				       cfg->gpio_param%32,
 				       cfg->gpio_param);
 			}
-			imx_iomux_v3_setup_pad(cfg->gpio_padmux |
+			imx_iomux_v3_setup_pad(cfg->gpio_padmux[cputype] |
 					       MUX_PAD_CTRL(ctrl));
 			gpio_direction_input(cfg->gpio_param);
 		} else if (hwconfig_subarg_cmp("dio2", "mode", "pwm") &&
 			   cfg->pwm_padmux) {
 			if (!quiet)
 				printf("DIO%d:  pwm%d\n", i, cfg->pwm_param);
-			imx_iomux_v3_setup_pad(cfg->pwm_padmux |
+			imx_iomux_v3_setup_pad(cfg->pwm_padmux[cputype] |
 					       MUX_PAD_CTRL(ctrl));
 		}
 	}
@@ -759,9 +880,10 @@ static void setup_board_gpio(int board)
 int imx6_pcie_toggle_reset(void)
 {
 	if (board_type < GW_UNKNOWN) {
-		gpio_direction_output(gpio_cfg[board_type].pcie_rst, 0);
+		uint pin = gpio_cfg[board_type].pcie_rst;
+		gpio_direction_output(pin, 0);
 		mdelay(50);
-		gpio_direction_output(gpio_cfg[board_type].pcie_rst, 1);
+		gpio_direction_output(pin, 1);
 	}
 	return 0;
 }
@@ -807,7 +929,6 @@ int dram_init(void)
 {
 	gd->ram_size = get_ram_size((void *)PHYS_SDRAM,
 				    CONFIG_DDR_MB*1024*1024);
-
 	return 0;
 }
 
@@ -829,9 +950,15 @@ int board_init(void)
 #ifdef CONFIG_MXC_SPI
 	setup_spi();
 #endif
-	setup_i2c(0, CONFIG_SYS_I2C_SPEED, 0x7f, &i2c_pad_info0);
-	setup_i2c(1, CONFIG_SYS_I2C_SPEED, 0x7f, &i2c_pad_info1);
-	setup_i2c(2, CONFIG_SYS_I2C_SPEED, 0x7f, &i2c_pad_info2);
+	if (is_cpu_type(MXC_CPU_MX6Q)) {
+		setup_i2c(0, CONFIG_SYS_I2C_SPEED, 0x7f, &mx6q_i2c_pad_info0);
+		setup_i2c(1, CONFIG_SYS_I2C_SPEED, 0x7f, &mx6q_i2c_pad_info1);
+		setup_i2c(2, CONFIG_SYS_I2C_SPEED, 0x7f, &mx6q_i2c_pad_info2);
+	} else {
+		setup_i2c(0, CONFIG_SYS_I2C_SPEED, 0x7f, &mx6dl_i2c_pad_info0);
+		setup_i2c(1, CONFIG_SYS_I2C_SPEED, 0x7f, &mx6dl_i2c_pad_info1);
+		setup_i2c(2, CONFIG_SYS_I2C_SPEED, 0x7f, &mx6dl_i2c_pad_info2);
+	}
 
 #ifdef CONFIG_CMD_SATA
 	setup_sata();
@@ -840,11 +967,13 @@ int board_init(void)
 	board_type = read_eeprom(I2C_GSC, &ventana_info);
 
 	/* board-specifc GPIO iomux */
+	SETUP_IOMUX_PADS(gw_gpio_pads);
 	if (board_type < GW_UNKNOWN) {
-		imx_iomux_v3_setup_multiple_pads(gw_gpio_pads,
-						 ARRAY_SIZE(gw_gpio_pads));
-		imx_iomux_v3_setup_multiple_pads(gpio_cfg[board_type].gpio_pads,
-						 gpio_cfg[board_type].num_pads);
+		iomux_v3_cfg_t const *p = gpio_cfg[board_type].gpio_pads;
+		int count = gpio_cfg[board_type].num_pads;
+		unsigned cputype = is_cpu_type(MXC_CPU_MX6Q) ? 0 : 1;
+
+		imx_iomux_v3_setup_multiple_pads_array(p, count, cputype, 2);
 	}
 
 	return 0;
Signature · 1 line
1.8.3.2
author
#40 lore raw

PATCH 12/12 imx: ventana: switch to SPL

In reply to Tim Harvey

Switch to an SPL image. The SPL for Ventana does the following:
- setup i2c and read the factory programmed EEPROM to obtain DRAM config and model for board-specific calibration data
- configure DRAM per CPU/size/layout/devices/calibration
- load u-boot.img from NAND or MTD depending on boot device and jump to it

This allows for a single SPL+u-boot.img to replace the previous multiple board configurations.

---
v2:
- remove missing/unnecessary include
- revert mtdparts change
- use imx_ddr_size() which uses MMDC configuration to determine mem size explicitly
- add support for MX6SOLO and MX6DUAL
- set CS0_END for 4GB so get_ram_size() works
- updated DDR3 calibration values for ventana boards
- fixed build issue - only compile spl if doing spl build
- fixed line length issue in README
- remove CONFIG_SPL* conditions and conditionally compile instead
- removed prints for CPU type and DRAM size/width - uboot will print these later
- removed unused gw_ventana_spl.cfg
- use common read_eeprom function
- added MMC support to SPL

---
 board/gateworks/gw_ventana/Makefile         |   1 +
 board/gateworks/gw_ventana/README           |  92 ++++---
 board/gateworks/gw_ventana/gw_ventana.c     |   9 +-
 board/gateworks/gw_ventana/gw_ventana.cfg   |  15 -
 board/gateworks/gw_ventana/gw_ventana_spl.c | 407 ++++++++++++++++++++++++++++
 boards.cfg                                  |   6 +-
 include/configs/gw_ventana.h                |  11 +
 7 files changed, 485 insertions(+), 56 deletions(-)
 create mode 100644 board/gateworks/gw_ventana/gw_ventana_spl.c
board/gateworks/gw_ventana/Makefile +1 -0
index 03bd1fd..33a1788 100644
@@ -7,4 +7,5 @@
 #
 
 obj-y  := gw_ventana.o gsc.o eeprom.o
+obj-$(CONFIG_SPL_BUILD) += gw_ventana_spl.o
 
board/gateworks/gw_ventana/README +60 -32

113 lines not on this page · raw message

board/gateworks/gw_ventana/gw_ventana.c +5 -4
index 584762f..ee2b203 100644
@@ -927,8 +927,7 @@ int board_early_init_f(void)
 
 int dram_init(void)
 {
-	gd->ram_size = get_ram_size((void *)PHYS_SDRAM,
-				    CONFIG_DDR_MB*1024*1024);
+	gd->ram_size = imx_ddr_size();
 	return 0;
 }
 
@@ -1071,9 +1070,11 @@ int misc_init_r(void)
 		 * env scripts will try loading each from most specific to
 		 * least.
 		 */
-		if (is_cpu_type(MXC_CPU_MX6Q))
+		if (is_cpu_type(MXC_CPU_MX6Q) ||
+		    is_cpu_type(MXC_CPU_MX6D))
 			cputype = "imx6q";
-		else if (is_cpu_type(MXC_CPU_MX6DL))
+		else if (is_cpu_type(MXC_CPU_MX6DL) ||
+			 is_cpu_type(MXC_CPU_MX6SOLO))
 			cputype = "imx6dl";
 		memset(str, 0, sizeof(str));
 		for (i = 0; i < (sizeof(str)-1) && info->model[i]; i++)
board/gateworks/gw_ventana/gw_ventana.cfg +0 -15
index 27f0974..9ab95f5 100644
@@ -24,21 +24,6 @@ BOOT_FROM      nand
 
 #define __ASSEMBLY__
 #include <config.h>
-#include "asm/arch/mx6-ddr.h"
 #include "asm/arch/iomux.h"
 #include "asm/arch/crm_regs.h"
-
-/* Memory configuration (size is overridden via eeprom config) */
-#include "../../boundary/nitrogen6x/ddr-setup.cfg"
-#if defined(CONFIG_MX6Q) && CONFIG_DDR_MB == 1024
-  #include "../../boundary/nitrogen6x/1066mhz_4x128mx16.cfg"
-#elif defined(CONFIG_MX6DL) && CONFIG_DDR_MB == 1024
-  #include "../../boundary/nitrogen6x/800mhz_4x128mx16.cfg"
-#elif defined(CONFIG_MX6DL) && CONFIG_DDR_MB == 512
-  #include "../../boundary/nitrogen6x/800mhz_2x128mx16.cfg"
-#elif defined(CONFIG_MX6Q) && CONFIG_DDR_MB == 512
-  #include "../../boundary/nitrogen6x/800mhz_2x128mx16.cfg"
-#else
-  #error "Unsupported CPU/Memory configuration"
-#endif
 #include "clocks.cfg"
board/gateworks/gw_ventana/gw_ventana_spl.c new file +407 -0

407 lines not on this page · raw message

boards.cfg +1 -5
index c83aff3..9119e24 100644
@@ -322,11 +322,7 @@ Active  arm         armv7          mx6         freescale       mx6qsabreauto
 Active  arm         armv7          mx6         freescale       mx6sabresd          mx6dlsabresd                         mx6sabresd:IMX_CONFIG=board/boundary/nitrogen6x/nitrogen6dl.cfg,MX6DL                                                             Fabio Estevam <[email protected]>
 Active  arm         armv7          mx6         freescale       mx6sabresd          mx6qsabresd                          mx6sabresd:IMX_CONFIG=board/freescale/imx/ddr/mx6q_4x_mt41j128.cfg,MX6Q                                                           Fabio Estevam <[email protected]>
 Active  arm         armv7          mx6         freescale       mx6slevk            mx6slevk                             mx6slevk:IMX_CONFIG=board/freescale/mx6slevk/imximage.cfg,MX6SL                                                                   Fabio Estevam <[email protected]>
-Active  arm         armv7          mx6         gateworks       gw_ventana          gwventanadl                          gw_ventana:IMX_CONFIG=board/gateworks/gw_ventana/gw_ventana.cfg,MX6DL,DDR_MB=512                                                  Tim Harvey <[email protected]>
-Active  arm         armv7          mx6         gateworks       gw_ventana          gwventanadl1g                        gw_ventana:IMX_CONFIG=board/gateworks/gw_ventana/gw_ventana.cfg,MX6DL,DDR_MB=1024                                                 Tim Harvey <[email protected]>
-Active  arm         armv7          mx6         gateworks       gw_ventana          gwventanaq                           gw_ventana:IMX_CONFIG=board/gateworks/gw_ventana/gw_ventana.cfg,MX6Q,DDR_MB=512                                                   Tim Harvey <[email protected]>
-Active  arm         armv7          mx6         gateworks       gw_ventana          gwventanaq1g                         gw_ventana:IMX_CONFIG=board/gateworks/gw_ventana/gw_ventana.cfg,MX6Q,DDR_MB=1024                                                  Tim Harvey <[email protected]>
-Active  arm         armv7          mx6         gateworks       gw_ventana          gwventanaq1gspi                      gw_ventana:IMX_CONFIG=board/gateworks/gw_ventana/gw_ventana.cfg,MX6Q,DDR_MB=1024,SPI_FLASH                                        Tim Harvey <[email protected]>
+Active  arm         armv7          mx6         gateworks       gw_ventana          gwventana                            gw_ventana:IMX_CONFIG=board/gateworks/gw_ventana/gw_ventana.cfg,MX6QDL,SPL                                                  Tim Harvey <[email protected]>
 Active  arm         armv7          mx6         solidrun        hummingboard        hummingboard_solo                    hummingboard:IMX_CONFIG=board/solidrun/hummingboard/solo.cfg,MX6S,DDR_MB=512                                                      Jon Nettleton <[email protected]>
 Active  arm         armv7          omap3       -               overo               omap3_overo                          -                                                                                                                                 Steve Sakoman <[email protected]>
 Active  arm         armv7          omap3       -               pandora             omap3_pandora                        -                                                                                                                                 Grazvydas Ignotas <[email protected]>
include/configs/gw_ventana.h +11 -0
index 3398390..cd53737 100644
@@ -7,6 +7,17 @@
 #ifndef __CONFIG_H
 #define __CONFIG_H
 
+/* SPL */
+#define CONFIG_SPL_NAND_SUPPORT
+#define CONFIG_SPL_MMC_SUPPORT
+#define CONFIG_SPL_FAT_SUPPORT
+/*
+#define CONFIG_SPL_SATA_SUPPORT
+*/
+/* Location in NAND to read U-Boot from */
+#define CONFIG_SYS_NAND_U_BOOT_OFFS     (14 * 1024 * 1024)
+
+#include "imx6_spl.h"                  /* common IMX6 SPL configuration */
 #include "mx6_common.h"
 #define CONFIG_MX6
 #define CONFIG_DISPLAY_CPUINFO         /* display cpu info */
Signature · 1 line
1.8.3.2
author
#41 lore raw

PATCH 12/12 imx: ventana: switch to SPL

Quoted 10 lines · Tim Harvey

Switch to an SPL image. The SPL for Ventana does the following:
- setup i2c and read the factory programmed EEPROM to obtain DRAM config and model for board-specific calibration data
- configure DRAM per CPU/size/layout/devices/calibration
- load u-boot.img from NAND or MTD depending on boot device and jump to it

This allows for a single SPL+u-boot.img to replace the previous multiple board configurations.

<snip>

Quoted 9 lines
board/gateworks/gw_ventana/gw_ventana_spl.c new file +9 -0
+
+static void i2c_setup_iomux(void)
+{
+       if (is_cpu_type(MXC_CPU_MX6Q))
+               setup_i2c(0, CONFIG_SYS_I2C_SPEED, 0x7f, &mx6q_i2c_pad_info0);
+       else
+               setup_i2c(0, CONFIG_SYS_I2C_SPEED, 0x7f, &mx6dl_i2c_pad_info0);
+}
+

<snip>

Quoted 29 lines
board/gateworks/gw_ventana/gw_ventana_spl.c new file +29 -0
+
+/*
+ * called from C runtime startup code (arch/arm/lib/crt0.S:_main)
+ * - we have a stack and a place to store GD, both in SRAM
+ * - no variable global data is available
+ */
+void board_init_f(ulong dummy)
+{
+       struct ventana_board_info ventana_info;
+       int board_model;
+
+       /* iomux and setup of i2c */
+       i2c_setup_iomux();
+       timer_init();
+       board_model = read_eeprom(I2C_GSC, &ventana_info);
+
+       /* provide some some default: 32bit 128MB */
+       if (GW_UNKNOWN == board_model) {
+               ventana_info.sdram_width = 2;
+               ventana_info.sdram_size = 3;
+       }
+       spl_dram_init(8 << ventana_info.sdram_width,
+                     16 << ventana_info.sdram_size,
+                     board_model);
+
+       arch_cpu_init();
+
+       /* Clear the BSS. */
+       memset(__bss_start, 0, __bss_end - __bss_start);

board/gateworks/gw_ventana/gw_ventana_spl.c line 403

Quoted 10 lines
board/gateworks/gw_ventana/gw_ventana_spl.c new file +10 -0
+
+       /* Set global data pointer. */
+       gd = &gdata;
+
+       board_early_init_f();
+
+       preloader_console_init();
+
+       board_init_r(NULL, 0);
+}

Stefano / York,

While preparing for a v3 patch series of my IMX6 SPL bootloader, I find that commit dec1861be90c948ea9fb771927d3d26a994d2e20 [1] breaks the above code because gd is now needed within setup_i2c.

I've always been a bit fuzzy on the order of the above calls so I dug through the code and I think I understand things better. Please correct any wrong assumptions I'm making below:
- assignment to gd should 'always' be first (before anything needs
it, so why not do it first)
- arch_cpu_init() should go next as this sets up very low level
CPU/SoC resources (in this case AIPS config and watchdog disable)
- board_early_init_f() should be next as that sets up any board-specific iomux
- any additional iomux necessary for SPL should go next (I take care
of i2c iomux and setup here)
- timer_init() next as you need a timer for UART and mxc i2c (for
delays and busy checks)
- preloader_console_init() next as we are now able to send something
over the UART (this gives me early debug for sdram config now too!)
- sdram setup goes next
- after sdram is setup, the bss can be cleared
- board_init_r - pass over to generic SPL code which will load/call
an image based on boot device

So, if the above is correct, I should rework the above function as follows:

void board_init_f(ulong dummy)

{
        struct ventana_board_info ventana_info;
        int board_model;

        /* Set global data pointer. */
        gd = &gdata;

        /* setup AIPS and disable watchdog */
        arch_cpu_init();

        /* iomux and setup of i2c */
        board_early_init_f();
        i2c_setup_iomux();

        /* setup GP timer */
        timer_init();

        /* UART clocks enabled and gd valid - init serial console */
        preloader_console_init();

        /* read/validate EEPROM info to determine board model and SDRAM cfg */
        board_model = read_eeprom(I2C_GSC, &ventana_info);

        /* provide some some default: 32bit 128MB */
        if (GW_UNKNOWN == board_model) {
                ventana_info.sdram_width = 2;
                ventana_info.sdram_size = 3;
        }

        /* configure MMDC for SDRAM width/size and per-model calibration */
        spl_dram_init(8 << ventana_info.sdram_width,
                      16 << ventana_info.sdram_size,
                      board_model);

        /* Clear the BSS. */
        memset(__bss_start, 0, __bss_end - __bss_start);

        /* load/boot image from boot device */
        board_init_r(NULL, 0);
}

Does this make sense?

Thanks,

Tim

[1] - http://git.denx.de/?p=u-boot.git;a=commitdiff;h=dec1861be90c948ea9fb771927d3d26a994d2e20

Quoted 46 lines
board/gateworks/gw_ventana/gw_ventana_spl.c new file +4 -0
+
+void reset_cpu(ulong addr)
+{
+}
boards.cfg +1 -5
index c83aff3..9119e24 100644
@@ -322,11 +322,7 @@ Active  arm         armv7          mx6         freescale       mx6qsabreauto
 Active  arm         armv7          mx6         freescale       mx6sabresd          mx6dlsabresd                         mx6sabresd:IMX_CONFIG=board/boundary/nitrogen6x/nitrogen6dl.cfg,MX6DL                                                             Fabio Estevam <[email protected]>
 Active  arm         armv7          mx6         freescale       mx6sabresd          mx6qsabresd                          mx6sabresd:IMX_CONFIG=board/freescale/imx/ddr/mx6q_4x_mt41j128.cfg,MX6Q                                                           Fabio Estevam <[email protected]>
 Active  arm         armv7          mx6         freescale       mx6slevk            mx6slevk                             mx6slevk:IMX_CONFIG=board/freescale/mx6slevk/imximage.cfg,MX6SL                                                                   Fabio Estevam <[email protected]>
-Active  arm         armv7          mx6         gateworks       gw_ventana          gwventanadl                          gw_ventana:IMX_CONFIG=board/gateworks/gw_ventana/gw_ventana.cfg,MX6DL,DDR_MB=512                                                  Tim Harvey <[email protected]>
-Active  arm         armv7          mx6         gateworks       gw_ventana          gwventanadl1g                        gw_ventana:IMX_CONFIG=board/gateworks/gw_ventana/gw_ventana.cfg,MX6DL,DDR_MB=1024                                                 Tim Harvey <[email protected]>
-Active  arm         armv7          mx6         gateworks       gw_ventana          gwventanaq                           gw_ventana:IMX_CONFIG=board/gateworks/gw_ventana/gw_ventana.cfg,MX6Q,DDR_MB=512                                                   Tim Harvey <[email protected]>
-Active  arm         armv7          mx6         gateworks       gw_ventana          gwventanaq1g                         gw_ventana:IMX_CONFIG=board/gateworks/gw_ventana/gw_ventana.cfg,MX6Q,DDR_MB=1024                                                  Tim Harvey <[email protected]>
-Active  arm         armv7          mx6         gateworks       gw_ventana          gwventanaq1gspi                      gw_ventana:IMX_CONFIG=board/gateworks/gw_ventana/gw_ventana.cfg,MX6Q,DDR_MB=1024,SPI_FLASH                                        Tim Harvey <[email protected]>
+Active  arm         armv7          mx6         gateworks       gw_ventana          gwventana                            gw_ventana:IMX_CONFIG=board/gateworks/gw_ventana/gw_ventana.cfg,MX6QDL,SPL                                                  Tim Harvey <[email protected]>
 Active  arm         armv7          mx6         solidrun        hummingboard        hummingboard_solo                    hummingboard:IMX_CONFIG=board/solidrun/hummingboard/solo.cfg,MX6S,DDR_MB=512                                                      Jon Nettleton <[email protected]>
 Active  arm         armv7          omap3       -               overo               omap3_overo                          -                                                                                                                                 Steve Sakoman <[email protected]>
 Active  arm         armv7          omap3       -               pandora             omap3_pandora                        -                                                                                                                                 Grazvydas Ignotas <[email protected]>
include/configs/gw_ventana.h +11 -1
index 3398390..cd53737 100644
@@ -7,6 +7,17 @@
 #ifndef __CONFIG_H
 #define __CONFIG_H
 
+/* SPL */
+#define CONFIG_SPL_NAND_SUPPORT
+#define CONFIG_SPL_MMC_SUPPORT
+#define CONFIG_SPL_FAT_SUPPORT
+/*
+#define CONFIG_SPL_SATA_SUPPORT
+*/
+/* Location in NAND to read U-Boot from */
+#define CONFIG_SYS_NAND_U_BOOT_OFFS     (14 * 1024 * 1024)
+
+#include "imx6_spl.h"                  /* common IMX6 SPL configuration */
 #include "mx6_common.h"
 #define CONFIG_MX6
 #define CONFIG_DISPLAY_CPUINFO         /* display cpu info */
--

1.8.3.2

#42 lore raw

PATCH 12/12 imx: ventana: switch to SPL

Quoted 131 lines · Tim Harvey
Quoted 10 lines · Tim Harvey

Switch to an SPL image. The SPL for Ventana does the following:
- setup i2c and read the factory programmed EEPROM to obtain DRAM config and model for board-specific calibration data
- configure DRAM per CPU/size/layout/devices/calibration
- load u-boot.img from NAND or MTD depending on boot device and jump to it

This allows for a single SPL+u-boot.img to replace the previous multiple board configurations.

<snip>

Quoted 9 lines
board/gateworks/gw_ventana/gw_ventana_spl.c new file +9 -0
+
+static void i2c_setup_iomux(void)
+{
+       if (is_cpu_type(MXC_CPU_MX6Q))
+               setup_i2c(0, CONFIG_SYS_I2C_SPEED, 0x7f, &mx6q_i2c_pad_info0);
+       else
+               setup_i2c(0, CONFIG_SYS_I2C_SPEED, 0x7f, &mx6dl_i2c_pad_info0);
+}
+

<snip>

Quoted 29 lines
board/gateworks/gw_ventana/gw_ventana_spl.c new file +29 -0
+
+/*
+ * called from C runtime startup code (arch/arm/lib/crt0.S:_main)
+ * - we have a stack and a place to store GD, both in SRAM
+ * - no variable global data is available
+ */
+void board_init_f(ulong dummy)
+{
+       struct ventana_board_info ventana_info;
+       int board_model;
+
+       /* iomux and setup of i2c */
+       i2c_setup_iomux();
+       timer_init();
+       board_model = read_eeprom(I2C_GSC, &ventana_info);
+
+       /* provide some some default: 32bit 128MB */
+       if (GW_UNKNOWN == board_model) {
+               ventana_info.sdram_width = 2;
+               ventana_info.sdram_size = 3;
+       }
+       spl_dram_init(8 << ventana_info.sdram_width,
+                     16 << ventana_info.sdram_size,
+                     board_model);
+
+       arch_cpu_init();
+
+       /* Clear the BSS. */
+       memset(__bss_start, 0, __bss_end - __bss_start);

board/gateworks/gw_ventana/gw_ventana_spl.c line 403

Quoted 10 lines
board/gateworks/gw_ventana/gw_ventana_spl.c new file +10 -0
+
+       /* Set global data pointer. */
+       gd = &gdata;
+
+       board_early_init_f();
+
+       preloader_console_init();
+
+       board_init_r(NULL, 0);
+}

Stefano / York,

While preparing for a v3 patch series of my IMX6 SPL bootloader, I find that commit dec1861be90c948ea9fb771927d3d26a994d2e20 [1] breaks the above code because gd is now needed within setup_i2c.

I've always been a bit fuzzy on the order of the above calls so I dug through the code and I think I understand things better. Please correct any wrong assumptions I'm making below:
- assignment to gd should 'always' be first (before anything needs
it, so why not do it first)
- arch_cpu_init() should go next as this sets up very low level
CPU/SoC resources (in this case AIPS config and watchdog disable)
- board_early_init_f() should be next as that sets up any board-specific iomux
- any additional iomux necessary for SPL should go next (I take care
of i2c iomux and setup here)
- timer_init() next as you need a timer for UART and mxc i2c (for
delays and busy checks)
- preloader_console_init() next as we are now able to send something
over the UART (this gives me early debug for sdram config now too!)
- sdram setup goes next
- after sdram is setup, the bss can be cleared
- board_init_r - pass over to generic SPL code which will load/call
an image based on boot device

So, if the above is correct, I should rework the above function as follows:

void board_init_f(ulong dummy)

{
        struct ventana_board_info ventana_info;
        int board_model;

        /* Set global data pointer. */
        gd = &gdata;

        /* setup AIPS and disable watchdog */
        arch_cpu_init();

        /* iomux and setup of i2c */
        board_early_init_f();
        i2c_setup_iomux();

        /* setup GP timer */
        timer_init();

        /* UART clocks enabled and gd valid - init serial console */
        preloader_console_init();

        /* read/validate EEPROM info to determine board model and SDRAM cfg */
        board_model = read_eeprom(I2C_GSC, &ventana_info);

        /* provide some some default: 32bit 128MB */
        if (GW_UNKNOWN == board_model) {
                ventana_info.sdram_width = 2;
                ventana_info.sdram_size = 3;
        }

        /* configure MMDC for SDRAM width/size and per-model calibration */
        spl_dram_init(8 << ventana_info.sdram_width,
                      16 << ventana_info.sdram_size,
                      board_model);

        /* Clear the BSS. */
        memset(__bss_start, 0, __bss_end - __bss_start);

        /* load/boot image from boot device */
        board_init_r(NULL, 0);
}
Quoted 2 lines

Does this make sense?

Tim,

I agree gd should be set first if the memory is available. My previous change to this i2c driver was to make sure it works without DRAM. Since it uses a data structure, it has no other place to go.

York

#43 lore raw

PATCH 12/12 imx: ventana: switch to SPL

In reply to Tim Harvey

Hello Tim,

Quoted 45 lines · Tim Harvey

On Mon, Apr 28, 2014 at 1:17 PM, Tim Harvey <[email protected]> wrote:

void board_init_f(ulong dummy)

{
        struct ventana_board_info ventana_info;
        int board_model;

        /* Set global data pointer. */
        gd = &gdata;

        /* setup AIPS and disable watchdog */
        arch_cpu_init();

        /* iomux and setup of i2c */
        board_early_init_f();
        i2c_setup_iomux();

        /* setup GP timer */
        timer_init();

        /* UART clocks enabled and gd valid - init serial console */
        preloader_console_init();

        /* read/validate EEPROM info to determine board model and SDRAM cfg */
        board_model = read_eeprom(I2C_GSC, &ventana_info);

        /* provide some some default: 32bit 128MB */
        if (GW_UNKNOWN == board_model) {
                ventana_info.sdram_width = 2;
                ventana_info.sdram_size = 3;
        }

        /* configure MMDC for SDRAM width/size and per-model calibration */
        spl_dram_init(8 << ventana_info.sdram_width,
                      16 << ventana_info.sdram_size,
                      board_model);

        /* Clear the BSS. */
        memset(__bss_start, 0, __bss_end - __bss_start);

        /* load/boot image from boot device */
        board_init_r(NULL, 0);
}
Quoted 1 line

Does this make sense?

Since Crt0.S already created gd on the stack before calling board_init_f, can't the assignment of gd not simply be removed? Is there anything special about gdata?

Regards,
Jeroen

author
#44 lore raw

PATCH 12/12 imx: ventana: switch to SPL

Quoted 48 lines · Jeroen Hofstee

Hello Tim,

Quoted 45 lines · Tim Harvey

On Mon, Apr 28, 2014 at 1:17 PM, Tim Harvey <[email protected]> wrote:

void board_init_f(ulong dummy)

{
        struct ventana_board_info ventana_info;
        int board_model;

        /* Set global data pointer. */
        gd = &gdata;

        /* setup AIPS and disable watchdog */
        arch_cpu_init();

        /* iomux and setup of i2c */
        board_early_init_f();
        i2c_setup_iomux();

        /* setup GP timer */
        timer_init();

        /* UART clocks enabled and gd valid - init serial console */
        preloader_console_init();

        /* read/validate EEPROM info to determine board model and SDRAM cfg */
        board_model = read_eeprom(I2C_GSC, &ventana_info);

        /* provide some some default: 32bit 128MB */
        if (GW_UNKNOWN == board_model) {
                ventana_info.sdram_width = 2;
                ventana_info.sdram_size = 3;
        }

        /* configure MMDC for SDRAM width/size and per-model calibration */
        spl_dram_init(8 << ventana_info.sdram_width,
                      16 << ventana_info.sdram_size,
                      board_model);

        /* Clear the BSS. */
        memset(__bss_start, 0, __bss_end - __bss_start);

        /* load/boot image from boot device */
        board_init_r(NULL, 0);
}
Quoted 10 lines
Quoted 1 line

Does this make sense?

Since Crt0.S already created gd on the stack before calling board_init_f, can't the assignment of gd not simply be removed? Is there anything special about gdata?

Regards,
Jeroen

Jeroen,

That does make sense, but what I find is that York's ocmmit dec1861be90c948ea9fb771927d3d26a994d2e20 requires that gd be blanked and its not. This causes bus_i2c_init to skip its initialization because p->base is not zero.

York, does this make sense? Your patch creates a dependence on gd->srdata being blank which isn't the case with the SRAM when booting from the IMX6 boot rom.

Tim

#45 lore raw

PATCH 12/12 imx: ventana: switch to SPL

Quoted 3 lines · Tim Harvey
Quoted 2 lines · Jeroen Hofstee

Hello Tim,

<snip>

Quoted 12 lines
Quoted 9 lines

Since Crt0.S already created gd on the stack before calling board_init_f, can't the assignment of gd not simply be removed? Is there anything special about gdata?

Regards,
Jeroen

Jeroen,

Quoted 9 lines

That does make sense, but what I find is that York's ocmmit dec1861be90c948ea9fb771927d3d26a994d2e20 requires that gd be blanked and its not. This causes bus_i2c_init to skip its initialization because p->base is not zero.

York, does this make sense? Your patch creates a dependence on gd->srdata being blank which isn't the case with the SRAM when booting from the IMX6 boot rom.

GD should be cleared (zeroed). Then we don't have this problem. Whoever sets up gd (board_int_f, cpu_init_f, or others) should make sure gd is cleared. Why isn't it the case for IMX6 boot rom?

York

#46 lore raw

PATCH 12/12 imx: ventana: switch to SPL

Hi,

Quoted 11 lines · York Sun

<snip>

Quoted 10 lines
Quoted 4 lines

Since Crt0.S already created gd on the stack before calling board_init_f, can't the assignment of gd not simply be removed? Is there anything special about gdata?

That does make sense, but what I find is that York's ocmmit dec1861be90c948ea9fb771927d3d26a994d2e20 requires that gd be blanked and its not. This causes bus_i2c_init to skip its initialization because p->base is not zero.

Quoted 9 lines
Quoted 4 lines

York, does this make sense? Your patch creates a dependence on gd->srdata being blank which isn't the case with the SRAM when booting from the IMX6 boot rom.

GD should be cleared (zeroed). Then we don't have this problem. Whoever sets up gd (board_int_f, cpu_init_f, or others) should make sure gd is cleared. Why isn't it the case for IMX6 boot rom?

Seems fine to me. Albert, any objection against zeroing gd out in crt0.S?

And if not, shouldn't the same be done for arm64.

Jeroen

author
#47 lore raw

PATCH 12/12 imx: ventana: switch to SPL

In reply to York Sun
Quoted 27 lines · York Sun
Quoted 3 lines · Tim Harvey
Quoted 2 lines · Jeroen Hofstee

Hello Tim,

<snip>

Quoted 12 lines
Quoted 9 lines

Since Crt0.S already created gd on the stack before calling board_init_f, can't the assignment of gd not simply be removed? Is there anything special about gdata?

Regards,
Jeroen

Jeroen,

Quoted 9 lines

That does make sense, but what I find is that York's ocmmit dec1861be90c948ea9fb771927d3d26a994d2e20 requires that gd be blanked and its not. This causes bus_i2c_init to skip its initialization because p->base is not zero.

York, does this make sense? Your patch creates a dependence on gd->srdata being blank which isn't the case with the SRAM when booting from the IMX6 boot rom.

Quoted 6 lines

GD should be cleared (zeroed). Then we don't have this problem. Whoever sets up gd (board_int_f, cpu_init_f, or others) should make sure gd is cleared. Why isn't it the case for IMX6 boot rom?

York

York,

crt0.S is mapping gd to where the SPL stack pointer is defined, which is where Freescale says its stack pointer is for its firmware BOOT ROM, so its initial data will be dependent on what the BOOT ROM did.

I think the right solution is to have crt0.S zero it out.

Tim

#48 lore raw

PATCH 12/12 imx: ventana: switch to SPL

Quoted 35 lines · Tim Harvey
Quoted 27 lines · York Sun
Quoted 3 lines · Tim Harvey
Quoted 2 lines · Jeroen Hofstee

Hello Tim,

<snip>

Quoted 12 lines
Quoted 9 lines

Since Crt0.S already created gd on the stack before calling board_init_f, can't the assignment of gd not simply be removed? Is there anything special about gdata?

Regards,
Jeroen

Jeroen,

Quoted 9 lines

That does make sense, but what I find is that York's ocmmit dec1861be90c948ea9fb771927d3d26a994d2e20 requires that gd be blanked and its not. This causes bus_i2c_init to skip its initialization because p->base is not zero.

York, does this make sense? Your patch creates a dependence on gd->srdata being blank which isn't the case with the SRAM when booting from the IMX6 boot rom.

Quoted 6 lines

GD should be cleared (zeroed). Then we don't have this problem. Whoever sets up gd (board_int_f, cpu_init_f, or others) should make sure gd is cleared. Why isn't it the case for IMX6 boot rom?

York

Quoted 8 lines

York,

crt0.S is mapping gd to where the SPL stack pointer is defined, which is where Freescale says its stack pointer is for its firmware BOOT ROM, so its initial data will be dependent on what the BOOT ROM did.

I think the right solution is to have crt0.S zero it out.

Either crt0.S, or somewhere before gd is used for the first time. Can it be done in board_init_f()?

York

author
#49 lore raw

PATCH 12/12 imx: ventana: switch to SPL

Quoted 42 lines · York Sun
Quoted 41 lines · Tim Harvey
Quoted 27 lines · York Sun
Quoted 3 lines · Tim Harvey
Quoted 2 lines · Jeroen Hofstee

Hello Tim,

<snip>

Quoted 12 lines
Quoted 9 lines

Since Crt0.S already created gd on the stack before calling board_init_f, can't the assignment of gd not simply be removed? Is there anything special about gdata?

Regards,
Jeroen

Jeroen,

Quoted 9 lines

That does make sense, but what I find is that York's ocmmit dec1861be90c948ea9fb771927d3d26a994d2e20 requires that gd be blanked and its not. This causes bus_i2c_init to skip its initialization because p->base is not zero.

York, does this make sense? Your patch creates a dependence on gd->srdata being blank which isn't the case with the SRAM when booting from the IMX6 boot rom.

Quoted 6 lines

GD should be cleared (zeroed). Then we don't have this problem. Whoever sets up gd (board_int_f, cpu_init_f, or others) should make sure gd is cleared. Why isn't it the case for IMX6 boot rom?

York

York,

crt0.S is mapping gd to where the SPL stack pointer is defined, which is where Freescale says its stack pointer is for its firmware BOOT ROM, so its initial data will be dependent on what the BOOT ROM did.

Quoted 9 lines
Quoted 2 lines

I think the right solution is to have crt0.S zero it out.

Either crt0.S, or somewhere before gd is used for the first time. Can it be done in board_init_f()?

York

It makes more sense to do it in crt0.S so that all boards don't have to do it and can make the assumption that it is cleared.

Tim

#50 lore raw

PATCH 12/12 imx: ventana: switch to SPL

Quoted 49 lines · Tim Harvey
Quoted 48 lines · York Sun
Quoted 35 lines · Tim Harvey
Quoted 27 lines · York Sun
Quoted 3 lines · Tim Harvey
Quoted 2 lines · Jeroen Hofstee

Hello Tim,

<snip>

Quoted 12 lines
Quoted 9 lines

Since Crt0.S already created gd on the stack before calling board_init_f, can't the assignment of gd not simply be removed? Is there anything special about gdata?

Regards,
Jeroen

Jeroen,

Quoted 9 lines

That does make sense, but what I find is that York's ocmmit dec1861be90c948ea9fb771927d3d26a994d2e20 requires that gd be blanked and its not. This causes bus_i2c_init to skip its initialization because p->base is not zero.

York, does this make sense? Your patch creates a dependence on gd->srdata being blank which isn't the case with the SRAM when booting from the IMX6 boot rom.

Quoted 6 lines

GD should be cleared (zeroed). Then we don't have this problem. Whoever sets up gd (board_int_f, cpu_init_f, or others) should make sure gd is cleared. Why isn't it the case for IMX6 boot rom?

York

Quoted 8 lines

York,

crt0.S is mapping gd to where the SPL stack pointer is defined, which is where Freescale says its stack pointer is for its firmware BOOT ROM, so its initial data will be dependent on what the BOOT ROM did.

I think the right solution is to have crt0.S zero it out.

Either crt0.S, or somewhere before gd is used for the first time. Can it be done in board_init_f()?

Quoted 7 lines
Quoted 3 lines

York

It makes more sense to do it in crt0.S so that all boards don't have to do it and can make the assumption that it is cleared.

No objection as far as it is cleared.

York

#51 lore raw

PATCH 12/12 imx: ventana: switch to SPL

In reply to Tim Harvey

Hi Tim,

Quoted 17 lines · Tim Harvey

Stefano / York,

While preparing for a v3 patch series of my IMX6 SPL bootloader, I find that commit dec1861be90c948ea9fb771927d3d26a994d2e20 [1] breaks the above code because gd is now needed within setup_i2c.

I've always been a bit fuzzy on the order of the above calls so I dug through the code and I think I understand things better. Please correct any wrong assumptions I'm making below:
- assignment to gd should 'always' be first (before anything needs
it, so why not do it first)
- arch_cpu_init() should go next as this sets up very low level
CPU/SoC resources (in this case AIPS config and watchdog disable)
- board_early_init_f() should be next as that sets up any board-specific iomux
- any additional iomux necessary for SPL should go next (I take care
of i2c iomux and setup here)

Quoted 8 lines

- timer_init() next as you need a timer for UART and mxc i2c (for
delays and busy checks)
- preloader_console_init() next as we are now able to send something
over the UART (this gives me early debug for sdram config now too!)
- sdram setup goes next
- after sdram is setup, the bss can be cleared
- board_init_r - pass over to generic SPL code which will load/call
an image based on boot device

I think your analyses is correct.

Quoted 36 lines

So, if the above is correct, I should rework the above function as follows:

void board_init_f(ulong dummy)

{
        struct ventana_board_info ventana_info;
        int board_model;

        /* Set global data pointer. */
        gd = &gdata;

        /* setup AIPS and disable watchdog */
        arch_cpu_init();

        /* iomux and setup of i2c */
        board_early_init_f();
        i2c_setup_iomux();

        /* setup GP timer */
        timer_init();

        /* UART clocks enabled and gd valid - init serial console */
        preloader_console_init();

        /* read/validate EEPROM info to determine board model and SDRAM cfg */
        board_model = read_eeprom(I2C_GSC, &ventana_info);

        /* provide some some default: 32bit 128MB */
        if (GW_UNKNOWN == board_model) {
                ventana_info.sdram_width = 2;
                ventana_info.sdram_size = 3;
        }

        /* configure MMDC for SDRAM width/size and per-model calibration */
        spl_dram_init(8 << ventana_info.sdram_width,
                      16 << ventana_info.sdram_size,
Quoted 8 lines
                      board_model);

        /* Clear the BSS. */
        memset(__bss_start, 0, __bss_end - __bss_start);

        /* load/boot image from boot device */
        board_init_r(NULL, 0);
}

It seems reasonable, go on this way.

Regards,
Stefano

Signature · 5 lines
=====================================================================
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: +49-8142-66989-53 Fax: +49-8142-66989-80 Email: sbabic at denx.de
=====================================================================
author
#52 lore raw

PATCH 12/12 imx: ventana: switch to SPL

Quoted 72 lines · Stefano Babic

Hi Tim,

Quoted 17 lines · Tim Harvey

Stefano / York,

While preparing for a v3 patch series of my IMX6 SPL bootloader, I find that commit dec1861be90c948ea9fb771927d3d26a994d2e20 [1] breaks the above code because gd is now needed within setup_i2c.

I've always been a bit fuzzy on the order of the above calls so I dug through the code and I think I understand things better. Please correct any wrong assumptions I'm making below:
- assignment to gd should 'always' be first (before anything needs
it, so why not do it first)
- arch_cpu_init() should go next as this sets up very low level
CPU/SoC resources (in this case AIPS config and watchdog disable)
- board_early_init_f() should be next as that sets up any board-specific iomux
- any additional iomux necessary for SPL should go next (I take care
of i2c iomux and setup here)

Quoted 8 lines

- timer_init() next as you need a timer for UART and mxc i2c (for
delays and busy checks)
- preloader_console_init() next as we are now able to send something
over the UART (this gives me early debug for sdram config now too!)
- sdram setup goes next
- after sdram is setup, the bss can be cleared
- board_init_r - pass over to generic SPL code which will load/call
an image based on boot device

I think your analyses is correct.

Quoted 41 lines

So, if the above is correct, I should rework the above function as follows:

void board_init_f(ulong dummy)

{
        struct ventana_board_info ventana_info;
        int board_model;

        /* Set global data pointer. */
        gd = &gdata;

        /* setup AIPS and disable watchdog */
        arch_cpu_init();

        /* iomux and setup of i2c */
        board_early_init_f();
        i2c_setup_iomux();

        /* setup GP timer */
        timer_init();

        /* UART clocks enabled and gd valid - init serial console */
        preloader_console_init();

        /* read/validate EEPROM info to determine board model and SDRAM cfg */
        board_model = read_eeprom(I2C_GSC, &ventana_info);

        /* provide some some default: 32bit 128MB */
        if (GW_UNKNOWN == board_model) {
                ventana_info.sdram_width = 2;
                ventana_info.sdram_size = 3;
        }

        /* configure MMDC for SDRAM width/size and per-model calibration */
        spl_dram_init(8 << ventana_info.sdram_width,
                      16 << ventana_info.sdram_size,
                      board_model);

        /* Clear the BSS. */
        memset(__bss_start, 0, __bss_end - __bss_start);
Quoted 9 lines
Quoted 3 lines
        /* load/boot image from boot device */
        board_init_r(NULL, 0);
}

It seems reasonable, go on this way.

Regards,
Stefano

Stefano,

I've just found that one of my boards fails with the above re-org. Strangely a board which has the same mem layout, mem width/size, CPU and nand does not fail.

If I make the following change:

author
#53 lore raw

PATCH 12/12 imx: ventana: switch to SPL

Quoted 83 lines · Tim Harvey
Quoted 72 lines · Stefano Babic

Hi Tim,

Quoted 17 lines · Tim Harvey

Stefano / York,

While preparing for a v3 patch series of my IMX6 SPL bootloader, I find that commit dec1861be90c948ea9fb771927d3d26a994d2e20 [1] breaks the above code because gd is now needed within setup_i2c.

I've always been a bit fuzzy on the order of the above calls so I dug through the code and I think I understand things better. Please correct any wrong assumptions I'm making below:
- assignment to gd should 'always' be first (before anything needs
it, so why not do it first)
- arch_cpu_init() should go next as this sets up very low level
CPU/SoC resources (in this case AIPS config and watchdog disable)
- board_early_init_f() should be next as that sets up any board-specific iomux
- any additional iomux necessary for SPL should go next (I take care
of i2c iomux and setup here)

Quoted 8 lines

- timer_init() next as you need a timer for UART and mxc i2c (for
delays and busy checks)
- preloader_console_init() next as we are now able to send something
over the UART (this gives me early debug for sdram config now too!)
- sdram setup goes next
- after sdram is setup, the bss can be cleared
- board_init_r - pass over to generic SPL code which will load/call
an image based on boot device

I think your analyses is correct.

Quoted 41 lines

So, if the above is correct, I should rework the above function as follows:

void board_init_f(ulong dummy)

{
        struct ventana_board_info ventana_info;
        int board_model;

        /* Set global data pointer. */
        gd = &gdata;

        /* setup AIPS and disable watchdog */
        arch_cpu_init();

        /* iomux and setup of i2c */
        board_early_init_f();
        i2c_setup_iomux();

        /* setup GP timer */
        timer_init();

        /* UART clocks enabled and gd valid - init serial console */
        preloader_console_init();

        /* read/validate EEPROM info to determine board model and SDRAM cfg */
        board_model = read_eeprom(I2C_GSC, &ventana_info);

        /* provide some some default: 32bit 128MB */
        if (GW_UNKNOWN == board_model) {
                ventana_info.sdram_width = 2;
                ventana_info.sdram_size = 3;
        }

        /* configure MMDC for SDRAM width/size and per-model calibration */
        spl_dram_init(8 << ventana_info.sdram_width,
                      16 << ventana_info.sdram_size,
                      board_model);

        /* Clear the BSS. */
        memset(__bss_start, 0, __bss_end - __bss_start);
Quoted 9 lines
Quoted 3 lines
        /* load/boot image from boot device */
        board_init_r(NULL, 0);
}

It seems reasonable, go on this way.

Regards,
Stefano

Quoted 7 lines

Stefano,

I've just found that one of my boards fails with the above re-org. Strangely a board which has the same mem layout, mem width/size, CPU and nand does not fail.

If I make the following change:

(sorry, accidentally fat fingered and sent instead of pasting). I'll continue:

board/gateworks/gw_ventana/gw_ventana_spl.c +3 -3
@@ -380,9 +380,6 @@ void board_init_f(ulong dummy)
         */
        memset((void *)gd, 0, sizeof(struct global_data));
 
-       /* setup AIPS and disable watchdog */
-       arch_cpu_init();
-
        /* iomux and setup of i2c */
        board_early_init_f();
        i2c_setup_iomux();
@@ -407,6 +404,9 @@ void board_init_f(ulong dummy)
                      16 << ventana_info.sdram_size,
                      board_model);
 
+       /* setup AIPS and disable watchdog */
+       arch_cpu_init();
+
        /* Clear the BSS. */
        memset(__bss_start, 0, __bss_end - __bss_start);
 

Things start to work properly. I took a look@arch_cpu_init() and the call that really needs to be moved (or just duplicated here) is mxs_dma_init() to start APBH DMA. The failure mode of the one board is that apparently it hangs while loading u-boot.img from NAND (which of course uses mxs_nand and thus APBH DMA).

Anyone know what's going on here and why mxs_dma_init() needs to be called after MMDC setup, and before clearing the BSS? I don't like having magic placement of functions without understanding why.

Thanks,

Tim

author
#54 lore raw

PATCH 12/12 imx: ventana: switch to SPL

Quoted 123 lines · Tim Harvey
Quoted 83 lines · Tim Harvey
Quoted 72 lines · Stefano Babic

Hi Tim,

Quoted 17 lines · Tim Harvey

Stefano / York,

While preparing for a v3 patch series of my IMX6 SPL bootloader, I find that commit dec1861be90c948ea9fb771927d3d26a994d2e20 [1] breaks the above code because gd is now needed within setup_i2c.

I've always been a bit fuzzy on the order of the above calls so I dug through the code and I think I understand things better. Please correct any wrong assumptions I'm making below:
- assignment to gd should 'always' be first (before anything needs
it, so why not do it first)
- arch_cpu_init() should go next as this sets up very low level
CPU/SoC resources (in this case AIPS config and watchdog disable)
- board_early_init_f() should be next as that sets up any board-specific iomux
- any additional iomux necessary for SPL should go next (I take care
of i2c iomux and setup here)

Quoted 8 lines

- timer_init() next as you need a timer for UART and mxc i2c (for
delays and busy checks)
- preloader_console_init() next as we are now able to send something
over the UART (this gives me early debug for sdram config now too!)
- sdram setup goes next
- after sdram is setup, the bss can be cleared
- board_init_r - pass over to generic SPL code which will load/call
an image based on boot device

I think your analyses is correct.

Quoted 41 lines

So, if the above is correct, I should rework the above function as follows:

void board_init_f(ulong dummy)

{
        struct ventana_board_info ventana_info;
        int board_model;

        /* Set global data pointer. */
        gd = &gdata;

        /* setup AIPS and disable watchdog */
        arch_cpu_init();

        /* iomux and setup of i2c */
        board_early_init_f();
        i2c_setup_iomux();

        /* setup GP timer */
        timer_init();

        /* UART clocks enabled and gd valid - init serial console */
        preloader_console_init();

        /* read/validate EEPROM info to determine board model and SDRAM cfg */
        board_model = read_eeprom(I2C_GSC, &ventana_info);

        /* provide some some default: 32bit 128MB */
        if (GW_UNKNOWN == board_model) {
                ventana_info.sdram_width = 2;
                ventana_info.sdram_size = 3;
        }

        /* configure MMDC for SDRAM width/size and per-model calibration */
        spl_dram_init(8 << ventana_info.sdram_width,
                      16 << ventana_info.sdram_size,
                      board_model);

        /* Clear the BSS. */
        memset(__bss_start, 0, __bss_end - __bss_start);
Quoted 9 lines
Quoted 3 lines
        /* load/boot image from boot device */
        board_init_r(NULL, 0);
}

It seems reasonable, go on this way.

Regards,
Stefano

Quoted 7 lines

Stefano,

I've just found that one of my boards fails with the above re-org. Strangely a board which has the same mem layout, mem width/size, CPU and nand does not fail.

If I make the following change:

(sorry, accidentally fat fingered and sent instead of pasting). I'll continue:

board/gateworks/gw_ventana/gw_ventana_spl.c +3 -3
@@ -380,9 +380,6 @@ void board_init_f(ulong dummy)
         */
        memset((void *)gd, 0, sizeof(struct global_data));
 
-       /* setup AIPS and disable watchdog */
-       arch_cpu_init();
-
        /* iomux and setup of i2c */
        board_early_init_f();
        i2c_setup_iomux();
@@ -407,6 +404,9 @@ void board_init_f(ulong dummy)
                      16 << ventana_info.sdram_size,
                      board_model);
 
+       /* setup AIPS and disable watchdog */
+       arch_cpu_init();
+
        /* Clear the BSS. */
        memset(__bss_start, 0, __bss_end - __bss_start);
 

Things start to work properly. I took a look at arch_cpu_init() and the call that really needs to be moved (or just duplicated here) is mxs_dma_init() to start APBH DMA. The failure mode of the one board is that apparently it hangs while loading u-boot.img from NAND (which of course uses mxs_nand and thus APBH DMA).

Quoted 7 lines

Anyone know what's going on here and why mxs_dma_init() needs to be called after MMDC setup, and before clearing the BSS? I don't like having magic placement of functions without understanding why.

Thanks,

Tim

I figured this one out - it has nothing to do with the order of calling arch_cpu_init() its that the MMDC isn't always 'ready' by the time the BSS is cleared and thus in my failure case the BSS isn't getting entirely cleared which causes the spl_image global var to not be cleared as expected and triggers an invalid codepath. I will update the mmdc config patch when I find the right solution.

Sorry for the noise.

Tim

#55 lore raw

PATCH 12/12 imx: ventana: switch to SPL

Hi Tim,

Quoted 7 lines · Tim Harvey

I figured this one out - it has nothing to do with the order of calling arch_cpu_init() its that the MMDC isn't always 'ready' by the time the BSS is cleared and thus in my failure case the BSS isn't getting entirely cleared which causes the spl_image global var to not be cleared as expected and triggers an invalid codepath. I will update the mmdc config patch when I find the right solution.

Thanks for the explanation ! I cannot guess why arch_cpu_init() should be called later. Nice you found the reason !

Quoted 2 lines

Sorry for the noise.

There was no noise ;-)

Best regards,
Stefano

Signature · 5 lines
=====================================================================
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: +49-8142-66989-53 Fax: +49-8142-66989-80 Email: sbabic at denx.de
=====================================================================