U-Boot
Threads by month
- ----- 2025 -----
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2004 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2003 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2002 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2001 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2000 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
April 2013
- 204 participants
- 570 discussions

[U-Boot] [PATCH v4 01/10] imx: Homogenize and fix fuse register definitions
by Benoît Thébaudeau 28 Apr '13
by Benoît Thébaudeau 28 Apr '13
28 Apr '13
IIM:
- Homogenize prg_p naming (the reference manuals are not always self-consistent
for that).
- Add missing SCSx and bank registers.
- Fix the number of banks on i.MX53.
OCOTP:
- Rename iim to ocotp in order to avoid confusion.
- Rename fuse_data to read_fuse_data, and sticky to sw_sticky, according to the
reference manual.
- Merge the existing spinoff gp1 fuse definition on i.MX6.
- Fix the number of banks on i.MX6.
Signed-off-by: Benoît Thébaudeau <benoit.thebaudeau(a)advansee.com>
---
Changes in v4:
- Convert spaces to tabs.
Changes in v3:
- Rebase against latest u-boot-imx/master.
- Fix the number of banks on i.MX6.
- Rename iim to ocotp on i.MX6 in order to avoid confusion, and merge in the
existing gp1 fuse definition.
- Rename fuse_data to read_fuse_data, and sticky to sw_sticky, according to the
reference manual.
Changes in v2:
- Rebase against latest master.
arch/arm/cpu/armv7/mx6/soc.c | 4 ++--
arch/arm/include/asm/arch-mx25/imx-regs.h | 8 ++++++--
arch/arm/include/asm/arch-mx27/imx-regs.h | 2 +-
arch/arm/include/asm/arch-mx31/imx-regs.h | 9 +++++++--
arch/arm/include/asm/arch-mx35/imx-regs.h | 7 ++++++-
arch/arm/include/asm/arch-mx5/imx-regs.h | 6 +++++-
arch/arm/include/asm/arch-mx6/imx-regs.h | 19 +++++++------------
board/freescale/mx6qsabreauto/mx6qsabreauto.c | 5 ++++-
8 files changed, 38 insertions(+), 22 deletions(-)
diff --git a/arch/arm/cpu/armv7/mx6/soc.c b/arch/arm/cpu/armv7/mx6/soc.c
index 69b8487..fc436fb 100644
--- a/arch/arm/cpu/armv7/mx6/soc.c
+++ b/arch/arm/cpu/armv7/mx6/soc.c
@@ -172,8 +172,8 @@ void enable_caches(void)
#if defined(CONFIG_FEC_MXC)
void imx_get_mac_from_fuse(int dev_id, unsigned char *mac)
{
- struct iim_regs *iim = (struct iim_regs *)IMX_IIM_BASE;
- struct fuse_bank *bank = &iim->bank[4];
+ struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR;
+ struct fuse_bank *bank = &ocotp->bank[4];
struct fuse_bank4_regs *fuse =
(struct fuse_bank4_regs *)bank->fuse_regs;
diff --git a/arch/arm/include/asm/arch-mx25/imx-regs.h b/arch/arm/include/asm/arch-mx25/imx-regs.h
index 5f4b543..99c32d4 100644
--- a/arch/arm/include/asm/arch-mx25/imx-regs.h
+++ b/arch/arm/include/asm/arch-mx25/imx-regs.h
@@ -113,8 +113,12 @@ struct iim_regs {
u32 iim_sdat;
u32 iim_prev;
u32 iim_srev;
- u32 iim_prog_p;
- u32 res1[0x1f5];
+ u32 iim_prg_p;
+ u32 iim_scs0;
+ u32 iim_scs1;
+ u32 iim_scs2;
+ u32 iim_scs3;
+ u32 res1[0x1f1];
struct fuse_bank {
u32 fuse_regs[0x20];
u32 fuse_rsvd[0xe0];
diff --git a/arch/arm/include/asm/arch-mx27/imx-regs.h b/arch/arm/include/asm/arch-mx27/imx-regs.h
index 2f6c823..aee058f 100644
--- a/arch/arm/include/asm/arch-mx27/imx-regs.h
+++ b/arch/arm/include/asm/arch-mx27/imx-regs.h
@@ -176,7 +176,7 @@ struct iim_regs {
u32 iim_sdat;
u32 iim_prev;
u32 iim_srev;
- u32 iim_prog_p;
+ u32 iim_prg_p;
u32 iim_scs0;
u32 iim_scs1;
u32 iim_scs2;
diff --git a/arch/arm/include/asm/arch-mx31/imx-regs.h b/arch/arm/include/asm/arch-mx31/imx-regs.h
index 3f58318..f67f49c 100644
--- a/arch/arm/include/asm/arch-mx31/imx-regs.h
+++ b/arch/arm/include/asm/arch-mx31/imx-regs.h
@@ -68,7 +68,7 @@ struct cspi_regs {
u32 test;
};
-/* IIM Control Registers */
+/* IIM control registers */
struct iim_regs {
u32 iim_stat;
u32 iim_statm;
@@ -80,11 +80,16 @@ struct iim_regs {
u32 iim_sdat;
u32 iim_prev;
u32 iim_srev;
- u32 iim_prog_p;
+ u32 iim_prg_p;
u32 iim_scs0;
u32 iim_scs1;
u32 iim_scs2;
u32 iim_scs3;
+ u32 res[0x1f1];
+ struct fuse_bank {
+ u32 fuse_regs[0x20];
+ u32 fuse_rsvd[0xe0];
+ } bank[3];
};
struct iomuxc_regs {
diff --git a/arch/arm/include/asm/arch-mx35/imx-regs.h b/arch/arm/include/asm/arch-mx35/imx-regs.h
index 7f337be..64546d2 100644
--- a/arch/arm/include/asm/arch-mx35/imx-regs.h
+++ b/arch/arm/include/asm/arch-mx35/imx-regs.h
@@ -262,11 +262,16 @@ struct iim_regs {
u32 iim_sdat;
u32 iim_prev;
u32 iim_srev;
- u32 iim_prog_p;
+ u32 iim_prg_p;
u32 iim_scs0;
u32 iim_scs1;
u32 iim_scs2;
u32 iim_scs3;
+ u32 res1[0x1f1];
+ struct fuse_bank {
+ u32 fuse_regs[0x20];
+ u32 fuse_rsvd[0xe0];
+ } bank[3];
};
/* General Purpose Timer (GPT) registers */
diff --git a/arch/arm/include/asm/arch-mx5/imx-regs.h b/arch/arm/include/asm/arch-mx5/imx-regs.h
index a71cc13..b237d5f 100644
--- a/arch/arm/include/asm/arch-mx5/imx-regs.h
+++ b/arch/arm/include/asm/arch-mx5/imx-regs.h
@@ -499,7 +499,7 @@ struct iim_regs {
u32 sdat;
u32 prev;
u32 srev;
- u32 preg_p;
+ u32 prg_p;
u32 scs0;
u32 scs1;
u32 scs2;
@@ -508,7 +508,11 @@ struct iim_regs {
struct fuse_bank {
u32 fuse_regs[0x20];
u32 fuse_rsvd[0xe0];
+#if defined(CONFIG_MX51)
} bank[4];
+#elif defined(CONFIG_MX53)
+ } bank[5];
+#endif
};
struct fuse_bank0_regs {
diff --git a/arch/arm/include/asm/arch-mx6/imx-regs.h b/arch/arm/include/asm/arch-mx6/imx-regs.h
index 0e4d8fa..680e752 100644
--- a/arch/arm/include/asm/arch-mx6/imx-regs.h
+++ b/arch/arm/include/asm/arch-mx6/imx-regs.h
@@ -229,7 +229,6 @@
#define CHIP_REV_1_0 0x10
#define IRAM_SIZE 0x00040000
-#define IMX_IIM_BASE OCOTP_BASE_ADDR
#define FEC_QUIRK_ENET_MAC
#if !(defined(__KERNEL_STRICT_NAMES) || defined(__ASSEMBLY__))
@@ -258,12 +257,6 @@ struct src {
u32 gpr10;
};
-/* OCOTP Registers */
-struct ocotp_regs {
- u32 reserved[0x198];
- u32 gp1; /* 0x660 */
-};
-
/* GPR3 bitfields */
#define IOMUXC_GPR3_GPU_DBG_OFFSET 29
#define IOMUXC_GPR3_GPU_DBG_MASK (3<<IOMUXC_GPR3_GPU_DBG_OFFSET)
@@ -438,7 +431,7 @@ struct cspi_regs {
ECSPI5_BASE_ADDR
#endif
-struct iim_regs {
+struct ocotp_regs {
u32 ctrl;
u32 ctrl_set;
u32 ctrl_clr;
@@ -449,9 +442,9 @@ struct iim_regs {
u32 rsvd1[3];
u32 read_ctrl;
u32 rsvd2[3];
- u32 fuse_data;
+ u32 read_fuse_data;
u32 rsvd3[3];
- u32 sticky;
+ u32 sw_sticky;
u32 rsvd4[3];
u32 scs;
u32 scs_set;
@@ -466,7 +459,7 @@ struct iim_regs {
struct fuse_bank {
u32 fuse_regs[0x20];
- } bank[15];
+ } bank[16];
};
struct fuse_bank4_regs {
@@ -477,7 +470,9 @@ struct fuse_bank4_regs {
u32 mac_addr_low;
u32 rsvd2[3];
u32 mac_addr_high;
- u32 rsvd3[0x13];
+ u32 rsvd3[0xb];
+ u32 gp1;
+ u32 rsvd4[7];
};
struct aipstz_regs {
diff --git a/board/freescale/mx6qsabreauto/mx6qsabreauto.c b/board/freescale/mx6qsabreauto/mx6qsabreauto.c
index aec3286..a3afa58 100644
--- a/board/freescale/mx6qsabreauto/mx6qsabreauto.c
+++ b/board/freescale/mx6qsabreauto/mx6qsabreauto.c
@@ -179,7 +179,10 @@ static int mx6sabre_rev(void)
* i.MX6Q ARD RevB: 0x02
*/
struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR;
- int reg = readl(&ocotp->gp1);
+ struct fuse_bank *bank = &ocotp->bank[4];
+ struct fuse_bank4_regs *fuse =
+ (struct fuse_bank4_regs *)bank->fuse_regs;
+ int reg = readl(&fuse->gp1);
int ret;
switch (reg >> 8 & 0x0F) {
--
1.7.10.4
2
24
Hi All,
I am attempting to run a standalone program on an ARM with u boot.Currently at the stage of running the hello world application.
I would like to use a lot of the available RAM in the stand alone program i plan to write.
It is unclear to me which parts of the RAM are used by u boot and i dont want to corrupt data.
Is there any clear list or variable that holds the location of RAM used or can i force only a certain section of ram to be used by uboot.
I have already noticed the center of the RAM is modified when any action occurs on the SD card
if this is already documented or answered in another post i have been unable to find it with a search so feel free to point me toward any info.
Thanks
2
1

27 Apr '13
From: Pavel Herrmann <morpheus.ibis(a)gmail.com>
** Please note that this is very early code. I am sending out an RFC to
get comments. This is not a commit message. This will only build on sandbox
and all you can do it try the 'demo' command. I am most interested in
comments about how to optimise the implementation to minimise impact on
existing drivers, minimise code bloat and make use of existing knowledge
users may have another other driver model implementations (e.g. Linux).
This patch adds a very simple drive model implementation. It is taken from
the driver model code developed by:
Marek Vasut <marex(a)denx.de>
Pavel Herrmann <morpheus.ibis(a)gmail.com>
Viktor Křivák <viktor.krivak(a)gmail.com>
Tomas Hlavacek <tmshlvck(a)gmail.com>
and possible others?
Please see doc/driver-model/README.txt for details of how to run this and
what to look for.
You can find a test version of the code used here in branch dm2 at:
http://git.denx.de/u-boot-x86.git
(Branch dm contains the original implementation)
This patch requires sandbox generic board support and other enhancements.
Signed-off-by: Simon Glass <sjg(a)chromium.org>
---
Makefile | 3 +
arch/sandbox/include/asm/io.h | 2 +-
arch/sandbox/include/asm/types.h | 4 +-
common/Makefile | 1 +
common/board_r.c | 56 ++++++
common/cmd_demo.c | 126 +++++++++++++
common/command.c | 10 +
common/dm/Makefile | 40 ++++
common/dm/debug.c | 137 ++++++++++++++
common/dm/driver.c | 374 ++++++++++++++++++++++++++++++++++++++
common/dm/lists.c | 138 ++++++++++++++
common/dm/root.c | 101 ++++++++++
common/dm/tree.c | 71 ++++++++
common/dm/uclass.c | 227 +++++++++++++++++++++++
doc/driver-model/README.txt | 307 +++++++++++++++++++++++++++++++
drivers/demo/Makefile | 44 +++++
drivers/demo/demo-shape.c | 106 +++++++++++
drivers/demo/demo-simple.c | 82 +++++++++
drivers/demo/demo-uclass.c | 52 ++++++
include/asm-generic/global_data.h | 9 +
include/asm-generic/gpio.h | 20 ++
include/command.h | 2 +
include/common.h | 2 +-
include/config_fallbacks.h | 8 +
include/configs/sandbox.h | 2 +
include/dm-demo.h | 47 +++++
include/dm.h | 27 +++
include/dm/debug.h | 33 ++++
include/dm/manager.h | 57 ++++++
include/dm/structures.h | 97 ++++++++++
include/dm/uclass.h | 62 +++++++
31 files changed, 2243 insertions(+), 4 deletions(-)
create mode 100644 common/cmd_demo.c
create mode 100644 common/dm/Makefile
create mode 100644 common/dm/debug.c
create mode 100644 common/dm/driver.c
create mode 100644 common/dm/lists.c
create mode 100644 common/dm/root.c
create mode 100644 common/dm/tree.c
create mode 100644 common/dm/uclass.c
create mode 100644 doc/driver-model/README.txt
create mode 100644 drivers/demo/Makefile
create mode 100644 drivers/demo/demo-shape.c
create mode 100644 drivers/demo/demo-simple.c
create mode 100644 drivers/demo/demo-uclass.c
create mode 100644 include/dm-demo.h
create mode 100644 include/dm.h
create mode 100644 include/dm/debug.h
create mode 100644 include/dm/manager.h
create mode 100644 include/dm/structures.h
create mode 100644 include/dm/uclass.h
diff --git a/Makefile b/Makefile
index 42f2b02..7f6e007 100644
--- a/Makefile
+++ b/Makefile
@@ -337,6 +337,9 @@ LIBS-y += api/libapi.o
LIBS-y += post/libpost.o
LIBS-y += test/libtest.o
+LIBS-$(CONFIG_DM) += common/dm/libdm.o
+LIBS-$(CONFIG_DM) += drivers/demo/libdemo.o
+
ifneq ($(CONFIG_AM33XX)$(CONFIG_OMAP34XX)$(CONFIG_OMAP44XX)$(CONFIG_OMAP54XX)$(CONFIG_TI814X),)
LIBS-y += $(CPUDIR)/omap-common/libomap-common.o
endif
diff --git a/arch/sandbox/include/asm/io.h b/arch/sandbox/include/asm/io.h
index 0c022f1..321bc0d 100644
--- a/arch/sandbox/include/asm/io.h
+++ b/arch/sandbox/include/asm/io.h
@@ -54,6 +54,6 @@ static inline void unmap_sysmem(const void *vaddr)
}
/* Map from a pointer to our RAM buffer */
-phys_addr_t map_to_sysmem(void *ptr);
+phys_addr_t map_to_sysmem(const void *ptr);
#endif
diff --git a/arch/sandbox/include/asm/types.h b/arch/sandbox/include/asm/types.h
index 2316c2d..07c2986 100644
--- a/arch/sandbox/include/asm/types.h
+++ b/arch/sandbox/include/asm/types.h
@@ -64,8 +64,8 @@ typedef unsigned long long u64;
#define BITS_PER_LONG CONFIG_SANDBOX_BITS_PER_LONG
typedef unsigned long dma_addr_t;
-typedef unsigned long phys_addr_t;
-typedef unsigned long phys_size_t;
+typedef u32 phys_addr_t;
+typedef u32 phys_size_t;
#endif /* __KERNEL__ */
diff --git a/common/Makefile b/common/Makefile
index 0e0fff1..680ad01 100644
--- a/common/Makefile
+++ b/common/Makefile
@@ -85,6 +85,7 @@ COBJS-$(CONFIG_CMD_CONSOLE) += cmd_console.o
COBJS-$(CONFIG_CMD_CPLBINFO) += cmd_cplbinfo.o
COBJS-$(CONFIG_DATAFLASH_MMC_SELECT) += cmd_dataflash_mmc_mux.o
COBJS-$(CONFIG_CMD_DATE) += cmd_date.o
+COBJS-$(CONFIG_CMD_DEMO) += cmd_demo.o
COBJS-$(CONFIG_CMD_SOUND) += cmd_sound.o
ifdef CONFIG_4xx
COBJS-$(CONFIG_CMD_SETGETDCR) += cmd_dcr.o
diff --git a/common/board_r.c b/common/board_r.c
index f801e41..436ae83 100644
--- a/common/board_r.c
+++ b/common/board_r.c
@@ -66,7 +66,9 @@
#ifdef CONFIG_X86
#include <asm/init_helpers.h>
#endif
+#include <dm-demo.h>
#include <linux/compiler.h>
+#include <linux/err.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -269,6 +271,57 @@ static int initr_malloc(void)
return 0;
}
+static int initr_dm(void)
+{
+ dm_init();
+ static const struct dm_demo_cdata red_square = {
+ .colour = "red",
+ .sides = 4.
+ };
+ static const struct dm_demo_cdata green_triangle = {
+ .colour = "green",
+ .sides = 3.
+ };
+ static const struct dm_demo_cdata yellow_hexagon = {
+ .colour = "yellow",
+ .sides = 6.
+ };
+ static const struct driver_info info[] = {
+ {
+ .name = "demo_shape_drv",
+ .platform_data = &red_square,
+ },
+ {
+ .name = "demo_simple_drv",
+ .platform_data = &red_square,
+ },
+ {
+ .name = "demo_shape_drv",
+ .platform_data = &green_triangle,
+ },
+ {
+ .name = "demo_simple_drv",
+ .platform_data = &yellow_hexagon,
+ },
+ {
+ .name = "demo_shape_drv",
+ .platform_data = &yellow_hexagon,
+ },
+ };
+ struct device *root = get_root_instance();
+ struct device *demo1;
+
+ demo1 = driver_bind(root, &info[0]);
+ if (IS_ERR(demo1))
+ printf("Demo bind failed: %ld\n", PTR_ERR(demo1));
+ driver_bind(demo1, &info[1]);
+ driver_bind(root, &info[2]);
+ driver_bind(root, &info[3]);
+ driver_bind(root, &info[4]);
+
+ return 0;
+}
+
__weak int power_init_board(void)
{
return 0;
@@ -765,6 +818,9 @@ init_fnc_t init_sequence_r[] = {
#endif
initr_barrier,
initr_malloc,
+#ifdef CONFIG_DM
+ initr_dm,
+#endif
#ifdef CONFIG_ARCH_EARLY_INIT_R
arch_early_init_r,
#endif
diff --git a/common/cmd_demo.c b/common/cmd_demo.c
new file mode 100644
index 0000000..657a541
--- /dev/null
+++ b/common/cmd_demo.c
@@ -0,0 +1,126 @@
+/*
+ * Copyright (C) 2013 Google, Inc
+ *
+ * (C) Copyright 2012
+ * Pavel Herrmann <morpheus.ibis(a)gmail.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <dm-demo.h>
+#include <asm/io.h>
+
+struct device *demo_dev;
+
+static int do_demo_hello(cmd_tbl_t *cmdtp, int flag, int argc,
+ char * const argv[])
+{
+ int ch = '@';
+
+ if (argc)
+ ch = *argv[0];
+
+ return demo_hello(demo_dev, ch);
+}
+
+static int do_demo_status(cmd_tbl_t *cmdtp, int flag, int argc,
+ char * const argv[])
+{
+ int status;
+ int ret;
+
+ ret = demo_status(demo_dev, &status);
+ if (ret)
+ return ret;
+
+ printf("Status: %d\n", status);
+
+ return 0;
+}
+
+int do_demo_list(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+ struct uclass *class;
+ struct device *dev;
+ int i = 0;
+
+ class = class_get_instance(UCLASS_DEMO);
+ if (!class)
+ return -ENOMEM;
+
+ puts("Demo class entries:\n");
+
+ list_for_each_entry(dev, &class->class_node, class_node) {
+ printf("entry %d - instance %08x, ops %08x, platform_data %08x\n",
+ i++, map_to_sysmem(dev),
+ map_to_sysmem(dev->driver->ops),
+ map_to_sysmem(dev->info->platform_data));
+ }
+
+ return 0;
+}
+
+static cmd_tbl_t demo_commands[] = {
+ U_BOOT_CMD_MKENT(list, 0, 1, do_demo_list, "", ""),
+ U_BOOT_CMD_MKENT(hello, 2, 1, do_demo_hello, "", ""),
+ U_BOOT_CMD_MKENT(status, 1, 1, do_demo_status, "", ""),
+};
+
+static int do_demo(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+ cmd_tbl_t *demo_cmd;
+ int devnum = 0;
+ int ret;
+
+ if (argc < 2)
+ return CMD_RET_USAGE;
+ demo_cmd = find_cmd_tbl(argv[1], demo_commands,
+ ARRAY_SIZE(demo_commands));
+ argc -= 2;
+ argv += 2;
+ if (!demo_cmd || argc > demo_cmd->maxargs)
+ return CMD_RET_USAGE;
+
+ if (argc) {
+ devnum = simple_strtoul(argv[0], NULL, 10);
+ demo_dev = uclass_get_child(UCLASS_DEMO, devnum);
+ if (!demo_dev) {
+ puts("Device not found\n");
+ return 1;
+ }
+
+ ret = driver_activate(demo_dev);
+ if (ret)
+ return cmd_process_error(cmdtp, ret);
+ }
+
+ argc--;
+ argv++;
+ ret = demo_cmd->cmd(demo_cmd, flag, argc, argv);
+ return cmd_process_error(demo_cmd, ret);
+}
+
+U_BOOT_CMD(
+ demo, 4, 1, do_demo,
+ "Driver model (dm) demo operations",
+ "list List available demo devices\n"
+ "hello <num> Say hello\n"
+ "status <num> Get demo device status"
+);
diff --git a/common/command.c b/common/command.c
index 305a236..70faa60 100644
--- a/common/command.c
+++ b/common/command.c
@@ -554,3 +554,13 @@ enum command_ret_t cmd_process(int flag, int argc, char * const argv[],
rc = cmd_usage(cmdtp);
return rc;
}
+
+int cmd_process_error(cmd_tbl_t *cmdtp, int err)
+{
+ if (err) {
+ printf("Command '%s' failed: Error %d\n", cmdtp->name, err);
+ return 1;
+ }
+
+ return 0;
+}
diff --git a/common/dm/Makefile b/common/dm/Makefile
new file mode 100644
index 0000000..982a3d5
--- /dev/null
+++ b/common/dm/Makefile
@@ -0,0 +1,40 @@
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that 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, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+include $(TOPDIR)/config.mk
+
+LIB := $(obj)libdm.o
+
+COBJS := debug.o driver.o lists.o tree.o root.o uclass.o
+SRCS := $(COBJS:.o=.c)
+OBJS := $(addprefix $(obj),$(COBJS))
+
+all: $(LIB)
+
+$(LIB): $(obj).depend $(OBJS)
+ $(call cmd_link_o_target, $(OBJS))
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/common/dm/debug.c b/common/dm/debug.c
new file mode 100644
index 0000000..cb36fb4
--- /dev/null
+++ b/common/dm/debug.c
@@ -0,0 +1,137 @@
+/*
+ * (C) Copyright 2012
+ * Marek Vasut <marex(a)denx.de>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <malloc.h>
+#include <errno.h>
+#include <asm/io.h>
+#include <dm/debug.h>
+#include <dm/manager.h>
+#include <dm/structures.h>
+#include <dm/uclass.h>
+
+static int display_succ(struct device *in, char *buf)
+{
+ int len;
+ int ip = 0;
+ char local[16];
+ struct device *pos, *n, *prev = NULL;
+
+ printf("%s- %s @ %08x", buf, in->info->name, map_to_sysmem(in));
+ if (in->flags & DM_FLAG_ACTIVATED)
+ puts(" - activated");
+ puts("\n");
+
+ if (list_empty(&in->succ))
+ return 0;
+
+ len = strlen(buf);
+ strncpy(local, buf, sizeof(local));
+ snprintf(local + len, 2, "|");
+ if (len && local[len - 1] == '`')
+ local[len - 1] = ' ';
+
+ list_for_each_entry_safe(pos, n, &in->succ, sibling) {
+ if (ip++)
+ display_succ(prev, local);
+ prev = pos;
+ }
+
+ snprintf(local + len, 2, "`");
+ display_succ(prev, local);
+
+ return 0;
+}
+
+int dm_dump_all()
+{
+ struct device *root;
+
+ root = get_root_instance();
+ printf("ROOT %08x\n", map_to_sysmem(root));
+ return dm_dump(root);
+}
+
+int dm_dump(struct device *dev)
+{
+ if (!dev)
+ return -EINVAL;
+ return display_succ(dev, "");
+}
+
+static int dm_dump_classs(void)
+{
+ struct uclass *class;
+ int count, num;
+ int id;
+
+ for (id = 0; id < UCLASS_COUNT; id++) {
+ class = class_get_instance(id);
+ if (!class)
+ continue;
+
+ count = uclass_get_count(id);
+ printf("class %d: %d instances\n", id, count);
+ for (num = 0; num < count; num++) {
+ struct device *inst;
+
+ inst = uclass_get_child(id, num);
+ printf(" %08x:\n", map_to_sysmem(inst));
+ }
+ puts("\n");
+ }
+
+ return 0;
+}
+
+static int do_dm(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+ struct device *root;
+
+ if (argc != 2)
+ return -EINVAL;
+ if (!strncmp(argv[1], "dump", 4))
+ return dm_dump_all();
+
+ if (!strncmp(argv[1], "remove", 6)) {
+ root = get_root_instance();
+ return driver_remove(root);
+ }
+
+ if (!strncmp(argv[1], "unbind", 6)) {
+ root = get_root_instance();
+ return driver_unbind(root);
+ }
+
+ if (!strcmp(argv[1], "class"))
+ return dm_dump_classs();
+
+ return -EINVAL;
+}
+
+U_BOOT_CMD(
+ dm, 2, 1, do_dm,
+ "Driver model ops",
+ "dump dump driver model tree\n"
+ "class Dump list of instances for each class"
+);
diff --git a/common/dm/driver.c b/common/dm/driver.c
new file mode 100644
index 0000000..597feab
--- /dev/null
+++ b/common/dm/driver.c
@@ -0,0 +1,374 @@
+/*
+ * (C) Copyright 2013 Google, Inc
+ *
+ * (C) Copyright 2012
+ * Pavel Herrmann <morpheus.ibis(a)gmail.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <malloc.h>
+#include <dm/manager.h>
+#include <linux/err.h>
+#include <linux/list.h>
+
+/*
+ * List management functions
+ */
+
+/**
+ * driver_add_child() - Connect one driver under another
+ * @parent: Parent driver, under which will the driver be connected
+ * @child: Child driver, which is to be connected under the parent
+ */
+static void driver_add_child(struct device *parent, struct device *child)
+{
+ list_add_tail(&child->sibling, &parent->succ);
+}
+
+/**
+ * driver_remove_child() - Unbind driver's child from the driver
+ * @parent: The parent device, from which the child is unbound
+ * @child: The child device, which is being unbound
+ */
+static void driver_remove_child(struct device *parent, struct device *child)
+{
+ list_del(&child->sibling);
+}
+
+/**
+ * driver_driver_reloc() - Relocate driver's children
+ * @old: Instance of the old driver
+ * @new: Instance of the new driver
+ *
+ * Relocate the children of a driver. The supplied old device
+ * contains the list of a children, usually generated during the
+ * pre-relocation stage, whereas the new device contains no
+ * children nodes yet. The new device is usually created at
+ * the post-relocation stage. The nodes from old instance are relocated
+ * and connected under the new instance.
+ */
+static int driver_driver_reloc(struct device *old,
+ struct device *new)
+{
+ struct device *pos, *n;
+ struct device *inst;
+
+ list_for_each_entry_safe(pos, n, &old->succ, sibling) {
+ inst = driver_relocate(pos, new);
+ if (IS_ERR(inst))
+ return PTR_ERR(inst);
+ driver_add_child(new, inst);
+ }
+
+ return 0;
+}
+
+/**
+ * driver_chld_unbind() - Unbind all driver's children from the driver
+ * @dev: The driver that is to be stripped of off children
+ */
+static int driver_chld_unbind(struct device *dev)
+{
+ struct device *pos, *n;
+ int ret;
+
+ if (!dev)
+ return -EINVAL;
+
+ if (list_empty(&dev->succ))
+ return 0;
+
+ list_for_each_entry_safe(pos, n, &dev->succ, sibling) {
+ ret = driver_unbind(pos);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+
+/**
+ * driver_chld_remove() - Stop all driver's children
+ * @dev: The driver whose children are to be stopped
+ */
+static int driver_chld_remove(struct device *dev)
+{
+ struct device *pos, *n;
+ int ret;
+
+ if (!dev)
+ return -EINVAL;
+
+ list_for_each_entry_safe(pos, n, &dev->succ, sibling) {
+ ret = driver_remove(pos);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+
+/*
+ * Driver management functions
+ */
+
+/**
+ * driver_bind() - Instantiate and connect a driver under a parent one
+ * @parent: The parent driver, under which the new driver will be connected
+ * @info: Information about the driver to be probed
+ *
+ * Make a new instance of a driver based on data passed by the user. This
+ * instance is then connected under the parent driver. The driver is not yet
+ * started after being bound, it's only present in the driver tree.
+ *
+ * Returns the instance of a new driver on success, NULL on error.
+ */
+struct device *driver_bind(struct device *parent,
+ const struct driver_info *info)
+{
+ struct device *dev;
+ struct u_boot_driver *drv;
+ int ret = 0;
+
+ if (!info || !parent) {
+ ret = -EINVAL;
+ goto fail;
+ }
+
+ dev = calloc(1, sizeof(struct device));
+ if (!dev) {
+ ret = -ENOMEM;
+ goto fail;
+ }
+
+ INIT_LIST_HEAD(&dev->sibling);
+ INIT_LIST_HEAD(&dev->succ);
+ INIT_LIST_HEAD(&dev->class_node);
+ dev->info = info;
+ dev->bus = parent;
+ drv = get_driver_by_instance(dev);
+
+ if (!drv) {
+ ret = -ENOENT;
+ goto fail_free;
+ }
+ dev->driver = drv;
+
+ /* put dev into parents successor list */
+ driver_add_child(parent, dev);
+
+ ret = uclass_bind(drv->id, dev);
+ if (ret)
+ goto fail_bind;
+
+ /* if we fail to bind we remove device from successors and free it */
+ if (drv->bind) {
+ ret = drv->bind(dev);
+ if (ret)
+ goto fail_bind;
+ }
+
+ return dev;
+
+fail_bind:
+ driver_remove_child(parent, dev);
+fail_free:
+ free(dev);
+fail:
+ return ERR_PTR(ret);
+}
+
+/**
+ * driver_activate() - Start a driver
+ * @i: Instance of a driver that is to be started
+ *
+ * This function runs the .probe() function, which initializes the hardware.
+ * The hardware and all it's predecessors are started by this function.
+ */
+int driver_activate(struct device *inst)
+{
+ struct u_boot_driver *drv;
+ int ret;
+
+ if (!inst)
+ return -EINVAL;
+
+ drv = get_driver_by_instance(inst);
+ if (!drv)
+ return -ENOENT;
+
+ if (inst->flags & DM_FLAG_ACTIVATED)
+ return 0;
+
+ /* Allocate private data if requested */
+ if (drv->priv_data_size) {
+ inst->priv = calloc(1, drv->priv_data_size);
+ if (!inst->priv)
+ return -ENOMEM;
+ }
+
+ if (inst->bus) {
+ ret = driver_activate(inst->bus);
+ if (ret)
+ goto err;
+ }
+
+ if (drv->probe) {
+ ret = drv->probe(inst);
+ if (ret)
+ goto err;
+ }
+
+ inst->flags |= DM_FLAG_ACTIVATED;
+ return 0;
+err:
+ if (drv->priv_data_size)
+ free(inst->priv);
+
+ return ret;
+}
+
+/**
+ * driver_relocate() - Relocate an instance of a driver
+ * @dev: The instance of a driver to be relocated
+ * @bus: The instance of a new parent of this driver
+ *
+ * Relocate an instance of a driver and it's children. The new
+ * instance of a driver is allocated and connected under the
+ * already-relocated parent/bus. The children of the old driver
+ * are relocated afterwards as well.
+ */
+struct device *driver_relocate(struct device *dev, struct device *bus)
+{
+ struct u_boot_driver *ops;
+ struct device *new_dev;
+ int ret;
+
+ if (!dev)
+ return NULL;
+
+ ops = get_driver_by_instance(dev);
+ if (!ops || !ops->reloc)
+ return NULL;
+
+ new_dev = calloc(1, sizeof(struct device));
+ if (!new_dev)
+ return NULL;
+
+ INIT_LIST_HEAD(&new_dev->sibling);
+ INIT_LIST_HEAD(&new_dev->succ);
+ new_dev->flags = dev->flags;
+ new_dev->bus = bus;
+ new_dev->info = dev->info;
+ /* FIXME: handle driver_info in dynamic memory */
+ new_dev->priv = NULL;
+
+ /* relocate the instance */
+ ret = ops->reloc(new_dev, dev);
+ if (ret)
+ goto err;
+
+ ret = driver_driver_reloc(dev, new_dev);
+ if (ret)
+ goto err;
+
+ return new_dev;
+
+err:
+ free(new_dev);
+ return NULL;
+};
+
+/**
+ * driver_unbind() - Unbind driver from it's parent
+ * @dev: The driver to be unbound
+ *
+ * Disconnect a driver from it's parent. The driver must be deactived,
+ * otherwise this function fails and doesn't unbind the driver.
+ */
+int driver_unbind(struct device *dev)
+{
+ struct u_boot_driver *ops;
+ int ret;
+
+ if (!dev)
+ return -EINVAL;
+
+ if (dev->flags & DM_FLAG_ACTIVATED)
+ return -EINVAL;
+
+ ops = get_driver_by_instance(dev);
+ if (!ops)
+ return -EINVAL;
+
+ ret = driver_chld_unbind(dev);
+ if (ret)
+ return ret;
+
+ if (ops->unbind) {
+ ret = ops->unbind(dev);
+ if (ret)
+ return ret;
+ }
+
+ if (dev->bus)
+ driver_remove_child(dev->bus, dev);
+
+ return 0;
+}
+
+/**
+ * driver_remove() - Disable the driver and it's children
+ * @dev: The instance of a driver to be disabled
+ *
+ * Deconfigure the hardware and all it's children.
+ */
+int driver_remove(struct device *dev)
+{
+ struct u_boot_driver *ops;
+ int ret;
+
+ if (!dev)
+ return -EINVAL;
+
+ if (!(dev->flags & DM_FLAG_ACTIVATED))
+ return 0;
+
+ ops = get_driver_by_instance(dev);
+ if (!ops)
+ return -EINVAL;
+
+ ret = driver_chld_remove(dev);
+ if (ret)
+ return ret;
+
+ if (ops->remove) {
+ ret = ops->remove(dev);
+ if (ret)
+ return ret;
+ }
+
+ if (dev->driver->priv_data_size)
+ free(dev->priv);
+
+ dev->flags &= ~DM_FLAG_ACTIVATED;
+
+ return ret;
+}
diff --git a/common/dm/lists.c b/common/dm/lists.c
new file mode 100644
index 0000000..f914143
--- /dev/null
+++ b/common/dm/lists.c
@@ -0,0 +1,138 @@
+/*
+ * (C) Copyright 2012
+ * Marek Vasut <marex(a)denx.de>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <dm/manager.h>
+
+/**
+ * get_driver_by_instance() - Return u_boot_driver classsponding to instance
+ * instance: Instance of the driver
+ *
+ * This function returns pointer to an u_boot_driver, which is base for the
+ * supplied instance of a driver. Returns NULL on error.
+ */
+struct u_boot_driver *get_driver_by_instance(struct device *i)
+{
+ struct u_boot_driver *drv =
+ ll_entry_start(struct u_boot_driver, driver);
+ const int n_ents = ll_entry_count(struct u_boot_driver, driver);
+ struct u_boot_driver *entry;
+ const char *name;
+ int len;
+
+ if (!i || !drv || !n_ents)
+ return NULL;
+
+ name = i->info->name;
+ len = strlen(name);
+
+ for (entry = drv; entry != drv + n_ents; entry++) {
+ if (strncmp(name, entry->name, len))
+ continue;
+
+ /* Full match */
+ if (len == strlen(entry->name))
+ return entry;
+ }
+
+ /* Not found */
+ return NULL;
+}
+
+/**
+ * get_usb_driver_by_ids() - Return u_boot_driver based on USB IDs
+ * major: USB major ID
+ * minor: USB minor ID
+ *
+ * This function finds an u_boot_driver inside the U-Boot USB driver list
+ * based on the USB's major and minor IDs. Returns pointer to the driver on
+ * success, NULL on error.
+ */
+struct u_boot_driver *get_usb_driver_by_ids(uint16_t major, uint16_t minor)
+{
+ struct u_boot_driver *drv =
+ ll_entry_start(struct u_boot_driver, driver);
+ const int n_ents = ll_entry_count(struct u_boot_driver, driver);
+ struct u_boot_driver *entry;
+ struct usb_ids *ids;
+ int i;
+
+ if (!drv || !n_ents)
+ return NULL;
+
+ /* First walk the ID tables */
+ for (entry = drv; entry != drv + n_ents; entry++) {
+ i = 0;
+ ids = entry->aux_data;
+ for (;;) {
+ if (!ids->ids[i].major && !ids->ids[i].minor)
+ break;
+
+ if (ids->ids[i].major != major) {
+ i++;
+ continue;
+ }
+
+ if (ids->ids[i].minor != minor) {
+ i++;
+ continue;
+ }
+
+ return entry;
+ }
+ }
+
+ /* Next, try the match functions */
+ for (entry = drv; entry != drv + n_ents; entry++) {
+ ids = entry->aux_data;
+ if (ids->match && ids->match())
+ return entry;
+ }
+
+ /* No driver found */
+ return NULL;
+}
+
+/**
+ * get_class_by_id() - Return U_BOOT_CLASS based on ID of the class
+ * id: ID of the class
+ *
+ * This function returns the pointer to U_BOOT_CLASS, which is the class's
+ * base structure based on the ID of the class. Returns NULL on error.
+ */
+struct u_boot_class *get_class_by_id(enum uclass_id id)
+{
+ struct u_boot_class *class =
+ ll_entry_start(struct u_boot_class, class);
+ const int n_ents = ll_entry_count(struct u_boot_class, class);
+ struct u_boot_class *entry;
+
+ if ((id == UCLASS_INVALID) || !class)
+ return NULL;
+
+ for (entry = class; entry != class + n_ents; entry++) {
+ if (entry->id == id)
+ return entry;
+ }
+
+ return NULL;
+}
diff --git a/common/dm/root.c b/common/dm/root.c
new file mode 100644
index 0000000..3a569ef
--- /dev/null
+++ b/common/dm/root.c
@@ -0,0 +1,101 @@
+/*
+ * (C) Copyright 2012
+ * Pavel Herrmann <morpheus.ibis(a)gmail.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <dm/structures.h>
+#include <dm/manager.h>
+#include <malloc.h>
+#include <errno.h>
+#include <linux/list.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static const struct driver_info root_info = {
+ .name = "root_driver",
+};
+
+/**
+ * create_root_instance() - Instantiate the root driver
+ *
+ * Create instance of the root driver, the root of the driver tree.
+ * This root driver is pointed to by the global data. Returns 0 on
+ * success, negative value on error.
+ */
+static int create_root_instance(void)
+{
+ struct device *di;
+
+ if (gd->dm_root) {
+ puts("Virtual root driver already exists!\n");
+ return -EINVAL;
+ }
+
+ di = calloc(1, sizeof(struct device));
+ if (di == NULL)
+ return -ENOMEM;
+
+ INIT_LIST_HEAD(&di->sibling);
+ INIT_LIST_HEAD(&di->succ);
+ di->info = &root_info;
+ gd->dm_root = di;
+
+ return 0;
+}
+
+/**
+ * get_root_instance() - Return pointer to the top of the driver tree
+ *
+ * This function returns pointer to the root node of the driver tree,
+ * in case this root wasn't created yet, reports it and returns NULL.
+ */
+struct device *get_root_instance(void)
+{
+ if (!gd->dm_root) {
+ puts("Virtual root driver does not exist!\n");
+ return NULL;
+ }
+
+ return gd->dm_root;
+}
+
+/**
+ * dm_init() - Initialize Driver Model structures
+ *
+ * This function will initialize roots of driver tree and class tree.
+ * This needs to be called before anything uses the DM
+ */
+int dm_init(void)
+{
+ int retval = 0;
+
+ retval = create_root_instance();
+ if (retval)
+ hang();
+
+ INIT_LIST_HEAD(&gd->class_root);
+
+ return retval;
+}
+
+U_BOOT_DRIVER(__root_driver) = {
+ .name = "root_driver",
+};
diff --git a/common/dm/tree.c b/common/dm/tree.c
new file mode 100644
index 0000000..bd08b06
--- /dev/null
+++ b/common/dm/tree.c
@@ -0,0 +1,71 @@
+/*
+ * (C) Copyright 2012
+ * Viktor Krivak <viktor.krivak(a)gmail.com>
+ * Pavel Herrmann <morpheus.ibis(a)gmail.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <dm/manager.h>
+#include <dm/structures.h>
+#include <linux/list.h>
+#include <malloc.h>
+#include <errno.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+struct node {
+ struct list_head list;
+ enum uclass_id key;
+ struct uclass class;
+};
+
+/**
+ * classs_relocate() - Relocate classs from early init memory
+ *
+ * Allocate new memory for each class, copy key and call reloc function found
+ * in specific class ops. Return 0 if succeeded.
+ */
+int classs_relocate(void)
+{
+ struct u_boot_class *ops;
+ struct node *node;
+ struct node *new;
+ struct list_head new_head;
+ INIT_LIST_HEAD(&new_head);
+ list_for_each_entry(node, &gd->class_root, list) {
+ ops = get_class_by_id(node->key);
+ if (!ops)
+ panic("%s: No ops\n", __func__);
+ new = malloc(sizeof(*new));
+ if (!new)
+ panic("%s: Unable to allocate memory!", __func__);
+ new->key = node->key;
+ /* No reloc method. It is strage but not error */
+ if (!ops->reloc)
+ continue;
+ if (!ops->reloc(&new->class, &node->class))
+ list_add_tail(&new->list, &new_head);
+ else
+ panic("%s: Relocation of class fail!", __func__);
+ }
+ gd->class_root = new_head;
+ return 0;
+}
+
diff --git a/common/dm/uclass.c b/common/dm/uclass.c
new file mode 100644
index 0000000..97430b2
--- /dev/null
+++ b/common/dm/uclass.c
@@ -0,0 +1,227 @@
+/*
+ * (C) Copyright 2012
+ * Pavel Herrmann <morpheus.ibis(a)gmail.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <malloc.h>
+#include <dm/manager.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/**
+ * search() - Search class by key in list
+ * @key: Key used to search apropriet class instance
+ *
+ * Linear search in list and if found something, replace it at beginning
+ * of the list and return class instance inside node.
+ * If nothing was found return NULL.
+ */
+static struct uclass *class_search(enum uclass_id key)
+{
+ struct uclass *inst;
+
+ list_for_each_entry(inst, &gd->class_root, succ) {
+ if (inst->dm_class->id == key)
+ return inst;
+ }
+ return NULL;
+}
+
+/**
+ * class_add_instance() - Create and add new class in list
+ * @key: Key used to init class instance
+ *
+ * Call init_node to create class instance and its container structure.
+ * After that add this class to list.
+ */
+static struct uclass *class_add_instance(enum uclass_id key)
+{
+ struct u_boot_class *cls;
+ struct uclass *inst;
+
+ cls = get_class_by_id(key);
+ if (!cls)
+ panic("Cannot find class for id %d\n", key);
+ inst = calloc(1, sizeof(*inst));
+ inst->dm_class = cls;
+ INIT_LIST_HEAD(&inst->succ);
+ INIT_LIST_HEAD(&inst->class_node);
+ list_add(&inst->succ, &gd->class_root);
+
+ return inst;
+}
+
+/**
+ * class_get_instance() - Return or create class by key
+ * @key: Search class with this key or create new one
+ *
+ * Try to find class in list structure. If fail create a new class and place it
+ * in list. If fail to create new class, return NULL. Otherwise return
+ * pointer to designated class.
+ */
+struct uclass *class_get_instance(enum uclass_id key)
+{
+ struct uclass *instance;
+
+ instance = class_search(key);
+ if (!instance)
+ instance = class_add_instance(key);
+ return instance;
+}
+
+/**
+ * uclass_get_count() - Return number of registered children with class
+ * @id: ID of the class
+ *
+ * Count the number of members registered with this class and return
+ * the value. Negative value is returned in case of failure.
+ */
+int uclass_get_count(enum uclass_id id)
+{
+ struct uclass *class;
+ struct device *inst;
+ int count = 0;
+
+ class = class_get_instance(id);
+ if (!class)
+ return -ENOMEM;
+
+ list_for_each_entry(inst, &class->class_node, class_node)
+ count++;
+
+ return count;
+}
+
+/**
+ * uclass_get_child() - Return n-th child of class
+ * @id: ID of the class
+ * @index: Position of the child in class's list
+ *
+ * Return the instance pointer of a child at the given index or
+ * return NULL on error.
+ */
+struct device *uclass_get_child(enum uclass_id id, int index)
+{
+ struct uclass *class;
+ struct device *inst;
+
+ class = class_get_instance(id);
+ if (!class)
+ return NULL;
+
+ list_for_each_entry(inst, &class->class_node, class_node) {
+ if (!index--)
+ return inst;
+ }
+
+ return NULL;
+}
+
+/**
+ * uclass_bind() - Associate driver with a class
+ * @id: ID of the class
+ * @dev: Pointer to the driver's instance
+ * @ops: Structure carrying operations this driver provides to the class
+ *
+ * Connect the driver into class's list of drivers. Returns 0 on success,
+ * negative value on error.
+ */
+int uclass_bind(enum uclass_id id, struct device *dev)
+{
+ struct uclass *class;
+ struct u_boot_class *class_ops;
+ int ret;
+
+ class = class_get_instance(id);
+ if (!class)
+ return -ENOMEM;
+
+ class_ops = get_class_by_id(id);
+ if (!class_ops)
+ return -ENOENT;
+ if (class_ops->ops)
+ return -EINVAL;
+
+ list_add_tail(&dev->class_node, &class->class_node);
+
+ if (class_ops->bind) {
+ ret = class_ops->bind(class, dev);
+ if (ret) {
+ list_del(&dev->class_node);
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
+/**
+ * uclass_unbind() - Deassociate driver with a class
+ * @id: ID of the class
+ * @dev: Pointer to the driver's instance
+ *
+ * Disconnect the driver from class's list of drivers.
+ * Returns 0 on success, negative value on error.
+ */
+int uclass_unbind(enum uclass_id id, struct device *dev)
+{
+ struct uclass *class;
+ struct u_boot_class *class_ops;
+
+ class = class_get_instance(id);
+ if (!class)
+ return -ENOMEM;
+
+ class_ops = get_class_by_id(id);
+ if (!class_ops)
+ return -ENOENT;
+
+ return class_ops->unbind(class, dev);
+}
+
+/**
+ * uclass_replace() - Replace instance of a driver with another in class's list
+ * @id: ID of the class
+ * @new: Pointer to the driver's new instance
+ * @old: Pointer to the driver's old instance
+ *
+ * Replace old instance of a driver, usually pre-relocation one, in the list
+ * of drivers associated with a class with a new one, usually a post-relocation
+ * one. All of the internal state of the class associated with the old instance
+ * is preserved.
+ *
+ * Returns 0 on success, negative value on error.
+ */
+int uclass_replace(enum uclass_id id, struct device *new, struct device *old)
+{
+ struct uclass *class;
+ struct u_boot_class *class_ops;
+
+ class = class_get_instance(id);
+ if (!class)
+ return -ENOMEM;
+
+ class_ops = get_class_by_id(id);
+ if (!class_ops)
+ return -ENOENT;
+
+ return class_ops->replace(class, new, old);
+}
diff --git a/doc/driver-model/README.txt b/doc/driver-model/README.txt
new file mode 100644
index 0000000..e077220
--- /dev/null
+++ b/doc/driver-model/README.txt
@@ -0,0 +1,307 @@
+Driver Model RFC
+================
+
+This README contains information about an early RFC implementation of
+driver model. The original work was done by:
+
+ Marek Vasut <marex(a)denx.de>
+ Pavel Herrmann <morpheus.ibis(a)gmail.com>
+ Viktor Křivák <viktor.krivak(a)gmail.com>
+ Tomas Hlavacek <tmshlvck(a)gmail.com>
+
+The code was taken from branch dm at:
+
+ git://git.denx.de/u-boot-marex.git
+
+You can find a test version of the code used here in branch dm2 at:
+
+ http://git.denx.de/u-boot-x86.git
+
+(Branch dm contains the original implementation)
+
+
+The goal of this effort is to get a very basic implementation into
+the U-Boot source tree quickly - something which people can build on,
+rather than something that solves all of the problems immediately.
+The only driver support that I am planning to add is GPIO, because
+it is simple, but non-trivial, and much of the work is already done
+by the people above.
+
+NOTE: This code is an early incoherent, inconsistent and largely
+incorrect draft. Please use it for making comments on the approach.
+Some knowledge of the existing driver model design is helpful.
+
+NOTE: Please read the above note again.
+
+
+How to try it
+-------------
+
+Build U-Boot sandbox and run it:
+
+ make sandbox_config
+ make
+ ./u-boot
+
+ (type 'reset' to exit U-Boot)
+
+
+The only available device class (uclass) is 'demo'. This uclass handles
+saying hello, and reporting its status. There are two drivers in this
+uclass:
+
+ - simple: Just prints a message for hello, doesn't implement status
+ - shape: Prints shapes and reports number of characters printed as status
+
+The demo class is pretty simple, but not trivial. The intention is that it
+can be used for testing, so it will implement all driver model features and
+provide 100% code coverage of them. It does have multiple drivers, it
+handles parameter data and platform_data (data which tells the driver how
+to operate on a particular platform) and it uses private driver data.
+
+To try it, see the example session below:
+
+=>demo hello 1
+probe from 07981110
+Hello '@' from 07981110: red 4
+=>demo status 2
+Status: 0
+=>demo hello 2
+g
+r@
+e@@
+e@@@
+n@@@@
+g@@@@@
+=>demo status 2
+Status: 21
+=>demo hello 4 ^
+ y^^^
+ e^^^^^
+l^^^^^^^
+l^^^^^^^
+ o^^^^^
+ w^^^
+=>demo status 4
+Status: 36
+=>
+
+
+What is going on?
+-----------------
+
+Let's start at the top. The demo command is in common/cmd_demo.c. It does
+the usual command procesing and then:
+
+ struct device *demo_dev;
+
+ demo_dev = uclass_get_child(UCLASS_DEMO, devnum);
+
+UCLASS_DEMO means the class of devices which implement 'demo'. Other
+classes might be MMC, or GPIO, hashing or serial. The idea is that the
+devices in the class all share a particular way of working. The class
+presents a unified view of all these devices to U-Boot.
+
+This function looks up the device for the demo uclass. Given a device
+number we can find the device because all devices have registered with
+the UCLASS_DEMO uclass.
+
+Having found the device, we activate it with:
+
+ ret = driver_activate(demo_dev);
+
+This is because all devices are inactive until used in U-Boot. The exact
+mechanism of activating a driver will hopefully change. For example, i
+may be possible to combine uclass_get_child() and driver_activate().
+
+Now that we have the device we can do things like:
+
+ return demo_hello(demo_dev, ch);
+
+This function is in the demo uclass. It takes care of calling the 'hello'
+method of the relevant driver. Bearing in mind that there are two drivers,
+this particular device may use one or other of them.
+
+The code for demo_hello() is in drivers/demo/demo-uclass.c:
+
+int demo_hello(struct device *dev, int ch)
+{
+ const struct demo_ops *ops = device_get_ops(dev);
+
+ if (!ops->hello)
+ return -ENOSYS;
+
+ return ops->hello(dev, ch);
+}
+
+As you can see it just calls the relevant driver method. One of these is
+in drivers/demo/demo-simple.c:
+
+static int simple_hello(struct device *dev, int ch)
+{
+ const struct dm_demo_cdata *pdata = dev->info->platform_data;
+
+ printf("Hello '%c' from %08x: %s %d\n", ch, map_to_sysmem(dev),
+ pdata->colour, pdata->sides);
+
+ return 0;
+}
+
+
+So that is a trip from top to bottom but it leaves a lot of topics to
+address.
+
+
+Declaring Drivers
+-----------------
+
+A driver declaration looks something like this (see
+drivers/demo/demo-shape.c):
+
+static const struct demo_ops simple_ops = {
+ .hello = shape_hello,
+ .status = shape_status,
+};
+
+U_BOOT_DRIVER(demo_shape_drv) = {
+ .name = "demo_shape_drv",
+ .id = UCLASS_DEMO,
+ .ops = &simple_ops,
+ .priv_data_size = sizeof(struct shape_data),
+};
+
+
+This driver has two methods (hello and status) and requires a bit
+of private data (accessible through dev->priv once the driver has
+been probed). It is a member of UCLASS_DEMO so will register itself
+there.
+
+In U_BOOT_DRIVER it is also possible to specify special methods for probe,
+and bind, and these are called at appropriate times. For many drivers
+it is hoped that only 'probe' and 'remove' will be needed.
+
+The U_BOOT_DRIVER macro creates a data structure accessible from C,
+so driver model can find the drivers that are available.
+
+
+Platform Data
+-------------
+
+Where does the platform data come from? See common/board_r.c which
+sets up a table of driver names and their associated platform data.
+The data can be interpreted by the drivers however they like - it is
+basically a communication scheme between the board-specific code and
+the generic drivers, which are intended to work on any board.
+
+Drivers can acceess their data via dev->info->platform_data. Here is
+the declaration for the platform data, which would normally appear
+in the board file.
+
+ static const struct dm_demo_cdata red_square = {
+ .colour = "red",
+ .sides = 4.
+ };
+ static const struct driver_info info[] = {
+ {
+ .name = "demo_shape_drv",
+ .platform_data = &red_square,
+ },
+ };
+
+ demo1 = driver_bind(root, &info[0]);
+
+
+Device Tree
+-----------
+
+This is not yet implemented but will be before this work leaves RFC status.
+We will use device tree to specify the platform data and activated drivers.
+In other words we replace the above code with the following device tree
+fragment:
+
+ red-square {
+ compatible = "demo-shape";
+ colour = "red";
+ sides = <4>;
+ };
+
+
+Driver model will look after creating a new device and feeding the device
+node into it. The driver itself will decode the device tree node and
+produce its own platform_data from it.
+
+
+Declaring Uclasses
+------------------
+
+The demo uclass is declared like this:
+
+U_BOOT_CLASS(demo) = {
+ .id = UCLASS_DEMO,
+};
+
+It is also possible to specify special methods for probe, etc. The uclass
+numbering comes from include/dm/uclass.h.
+
+
+Data Structures
+---------------
+
+Driver model uses a doubly-linked list as the basic data structure. Some
+nodes have several lists running through them. Creating a more efficient
+data structure might be worthwhile in some rare cases, once we understand
+what the bottlenecks are.
+
+
+Changes so far
+--------------
+
+The documenation in this direction is out of data and until the patch
+is in more solid form I have avoided updating it. This implementation
+uses a very similar approach, but makes at least the following changes:
+
+- Tried to agressively remove boilerplate, so that for most drivers there
+is little or no 'driver model' code to write.
+- Moved some data from code into data structure - e.g. store a pointer to
+the driver operations structure in the driver, rather than passing it
+to the driver bind function.
+- Rename some structures to make them more similar to Linux (struct device
+instead of struct instance, struct platform_data, etc.)
+- Change the name 'core' to 'uclass', meaning U-Boot class. It seems that
+this concept relates to a class of drivers (or a subsystem). We shouldn't
+use 'class' since it is a C++ reserved word, so U-Boot class (uclass) seems
+better than 'core'.
+- Remove 'struct driver_instance' and just use a single 'struct device'.
+This removes a level of indirection that doesn't seem necessary.
+
+
+Proposed additional changes
+---------------------------
+
+- Build in device tree support, to avoid the need for platform_data
+- Possibly remove the concept of driver relocation, and just make it
+possible for the new driver (created after relocation) to access the old
+driver data. I feel that relocation is a very special case and will only
+apply to a few drivers, many of which can/will just re-init anyway. So
+the overhead of dealing with this might not be worth it. This is TBD
+though.
+- Implement for GPIO subsystem. An implementation is already done in the
+driver model tree
+
+
+Things to punt for later
+------------------------
+
+- SPL support - this will have to be present before many drivers can be
+converted, but it seems like we can add it once we are happy with the
+core implementation.
+- Pre-relocation support - similar story
+
+That is not to say that no thinking has gone into these - in fact there
+is quite a lot there. However, getting these right is non-trivial and
+there is a high cost associated with going down the wrong path.
+
+
+Simon Glass
+sjg(a)chromium.org
+April 2013
diff --git a/drivers/demo/Makefile b/drivers/demo/Makefile
new file mode 100644
index 0000000..60a2b88
--- /dev/null
+++ b/drivers/demo/Makefile
@@ -0,0 +1,44 @@
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that 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, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+include $(TOPDIR)/config.mk
+
+LIB := $(obj)libdemo.o
+
+COBJS-$(CONFIG_DM_DEMO) += demo-uclass.o
+COBJS-$(CONFIG_DM_DEMO_SIMPLE) += demo-simple.o
+COBJS-$(CONFIG_DM_DEMO_SHAPE) += demo-shape.o
+
+COBJS := $(COBJS-y)
+SRCS := $(COBJS:.o=.c)
+OBJS := $(addprefix $(obj),$(COBJS))
+
+all: $(LIB)
+
+$(LIB): $(obj).depend $(OBJS)
+ $(call cmd_link_o_target, $(OBJS))
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/drivers/demo/demo-shape.c b/drivers/demo/demo-shape.c
new file mode 100644
index 0000000..b72fcba
--- /dev/null
+++ b/drivers/demo/demo-shape.c
@@ -0,0 +1,106 @@
+/*
+ * (C) Copyright 2013 Google, Inc
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <malloc.h>
+#include <dm-demo.h>
+#include <asm/io.h>
+#include <dm/manager.h>
+
+/* Shape size */
+#define WIDTH 8
+#define HEIGHT 6
+
+struct shape_data {
+ int num_chars; /* Number of non-space characters output so far */
+};
+
+/* Crazy little function to draw shapes on the console */
+static int shape_hello(struct device *dev, int ch)
+{
+ const struct dm_demo_cdata *pdata = dev->info->platform_data;
+ struct shape_data *data = dev->priv;
+ static const struct shape {
+ int start;
+ int end;
+ int dstart;
+ int dend;
+ } shapes[3] = {
+ { 0, 1, 0, 1 },
+ { 0, WIDTH, 0, 0 },
+ { HEIGHT / 2 - 1, WIDTH - HEIGHT / 2 + 1, -1, 1},
+ };
+ struct shape shape;
+ unsigned int index;
+ int line, pos, inside;
+ const char *colour = pdata->colour;
+ int first = 0;
+
+ index = (pdata->sides / 2) - 1;
+ if (index >= ARRAY_SIZE(shapes))
+ return -EIO;
+ shape = shapes[index];
+
+ for (line = 0; line < HEIGHT; line++) {
+ first = 1;
+ for (pos = 0; pos < WIDTH; pos++) {
+ inside = pos >= shape.start && pos < shape.end;
+ if (inside) {
+ putc(first ? *colour++ : ch);
+ data->num_chars++;
+ first = 0;
+ if (!*colour)
+ colour = pdata->colour;
+ } else {
+ putc(' ');
+ }
+ }
+ putc('\n');
+ shape.start += shape.dstart;
+ shape.end += shape.dend;
+ if (shape.start < 0) {
+ shape.dstart = -shape.dstart;
+ shape.dend = -shape.dend;
+ shape.start += shape.dstart;
+ shape.end += shape.dend;
+ }
+ }
+
+ return 0;
+}
+
+static int shape_status(struct device *dev, int *status)
+{
+ struct shape_data *data = dev->priv;
+
+ *status = data->num_chars;
+ return 0;
+}
+
+static const struct demo_ops simple_ops = {
+ .hello = shape_hello,
+ .status = shape_status,
+};
+
+U_BOOT_DRIVER(demo_shape_drv) = {
+ .name = "demo_shape_drv",
+ .id = UCLASS_DEMO,
+ .ops = &simple_ops,
+ .priv_data_size = sizeof(struct shape_data),
+};
diff --git a/drivers/demo/demo-simple.c b/drivers/demo/demo-simple.c
new file mode 100644
index 0000000..e0c55f3
--- /dev/null
+++ b/drivers/demo/demo-simple.c
@@ -0,0 +1,82 @@
+/*
+ * (C) Copyright 2013 Google, Inc
+ *
+ * (C) Copyright 2012
+ * Pavel Herrmann <morpheus.ibis(a)gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <dm-demo.h>
+#include <asm/io.h>
+#include <dm/manager.h>
+
+static int simple_hello(struct device *dev, int ch)
+{
+ const struct dm_demo_cdata *pdata = dev->info->platform_data;
+
+ printf("Hello '%c' from %08x: %s %d\n", ch, map_to_sysmem(dev),
+ pdata->colour, pdata->sides);
+
+ return 0;
+}
+
+static const struct demo_ops simple_ops = {
+ .hello = simple_hello,
+};
+
+static int simple_bind(struct device *dev)
+{
+ printf("bind from %08x\n", map_to_sysmem(dev));
+ return 0;
+}
+
+static int simple_probe(struct device *dev)
+{
+ printf("probe from %08x\n", map_to_sysmem(dev));
+ return 0;
+}
+
+static int simple_reloc(struct device *new, struct device *old)
+{
+ printf("reloc to %08x from %08x\n", map_to_sysmem(new),
+ map_to_sysmem(old));
+ return 0;
+}
+
+static int simple_remove(struct device *dev)
+{
+ printf("remove from %08x\n", map_to_sysmem(dev));
+ return 0;
+}
+
+static int simple_unbind(struct device *dev)
+{
+ printf("unbind from %08x\n", map_to_sysmem(dev));
+ return 0;
+}
+
+U_BOOT_DRIVER(demo_simple_drv) = {
+ .name = "demo_simple_drv",
+ .id = UCLASS_DEMO,
+ .ops = &simple_ops,
+ .bind = simple_bind,
+ .probe = simple_probe,
+ .reloc = simple_reloc,
+ .remove = simple_remove,
+ .unbind = simple_unbind,
+};
diff --git a/drivers/demo/demo-uclass.c b/drivers/demo/demo-uclass.c
new file mode 100644
index 0000000..a5a3367
--- /dev/null
+++ b/drivers/demo/demo-uclass.c
@@ -0,0 +1,52 @@
+/*
+ * (C) Copyright 2012
+ * Pavel Herrmann <morpheus.ibis(a)gmail.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <malloc.h>
+#include <dm-demo.h>
+#include <asm/io.h>
+#include <dm/manager.h>
+#include <linux/list.h>
+
+U_BOOT_CLASS(demo) = {
+ .id = UCLASS_DEMO,
+};
+
+int demo_hello(struct device *dev, int ch)
+{
+ const struct demo_ops *ops = device_get_ops(dev);
+
+ if (!ops->hello)
+ return -ENOSYS;
+
+ return ops->hello(dev, ch);
+}
+
+int demo_status(struct device *dev, int *status)
+{
+ const struct demo_ops *ops = device_get_ops(dev);
+
+ if (!ops->status)
+ return -ENOSYS;
+
+ return ops->status(dev, status);
+}
diff --git a/include/asm-generic/global_data.h b/include/asm-generic/global_data.h
index 5416f46..4425284 100644
--- a/include/asm-generic/global_data.h
+++ b/include/asm-generic/global_data.h
@@ -24,6 +24,9 @@
#ifndef __ASM_GENERIC_GBL_DATA_H
#define __ASM_GENERIC_GBL_DATA_H
+
+#include <linux/list.h>
+
/*
* The following data structure is placed in some memory which is
* available very early after boot (like DPRAM on MPC8xx/MPC82xx, or
@@ -80,6 +83,12 @@ typedef struct global_data {
unsigned long start_addr_sp; /* start_addr_stackpointer */
unsigned long reloc_off;
struct global_data *new_gd; /* relocated global data */
+
+#ifdef CONFIG_DM
+ struct device *dm_root; /* Root instance for Driver Model */
+ struct list_head class_root; /* Head of core tree */
+#endif
+
const void *fdt_blob; /* Our device tree, NULL if none */
void *new_fdt; /* Relocated FDT */
unsigned long fdt_size; /* Space reserved for relocated FDT */
diff --git a/include/asm-generic/gpio.h b/include/asm-generic/gpio.h
index bfedbe4..ead3515 100644
--- a/include/asm-generic/gpio.h
+++ b/include/asm-generic/gpio.h
@@ -94,4 +94,24 @@ int gpio_get_value(unsigned gpio);
* @return 0 if ok, -1 on error
*/
int gpio_set_value(unsigned gpio, int value);
+
+/*
+ * Driver model GPIO operations, refer to functions above for description.
+ * These function copy the old API.
+ *
+ * This is trying to be close to Linux GPIO API. Once the U-Boot uses the
+ * new DM GPIO API, this should be really easy to flip over to the Linux
+ * GPIO API-alike interface.
+ */
+struct dm_gpio_ops {
+ int base;
+ u16 ngpio;
+ int (*gpio_request)(unsigned gpio, const char *label);
+ int (*gpio_free)(unsigned gpio);
+ int (*gpio_direction_input)(unsigned gpio);
+ int (*gpio_direction_output)(unsigned gpio, int value);
+ int (*gpio_get_value)(unsigned gpio);
+ int (*gpio_set_value)(unsigned gpio, int value);
+};
+
#endif /* _ASM_GENERIC_GPIO_H_ */
diff --git a/include/command.h b/include/command.h
index 65692fd..445c9e8 100644
--- a/include/command.h
+++ b/include/command.h
@@ -80,6 +80,8 @@ extern int var_complete(int argc, char * const argv[], char last_char, int maxv,
extern int cmd_auto_complete(const char *const prompt, char *buf, int *np, int *colp);
#endif
+int cmd_process_error(cmd_tbl_t *cmdtp, int err);
+
/*
* Monitor Command
*
diff --git a/include/common.h b/include/common.h
index 28aa4b9..bdf598f 100644
--- a/include/common.h
+++ b/include/common.h
@@ -911,7 +911,7 @@ static inline void unmap_sysmem(const void *vaddr)
{
}
-static inline phys_addr_t map_to_sysmem(void *ptr)
+static inline phys_addr_t map_to_sysmem(const void *ptr)
{
return (phys_addr_t)(uintptr_t)ptr;
}
diff --git a/include/config_fallbacks.h b/include/config_fallbacks.h
index e59ee96..c91a383 100644
--- a/include/config_fallbacks.h
+++ b/include/config_fallbacks.h
@@ -53,4 +53,12 @@
#define HAVE_BLOCK_DEVICE
#endif
+#ifdef CONFIG_DM
+/* For now, enable the driver model demo command */
+#define CONFIG_DM_DEMO
+#define CONFIG_CMD_DEMO
+#define CONFIG_DM_DEMO_SIMPLE
+#define CONFIG_DM_DEMO_SHAPE
+#endif
+
#endif /* __CONFIG_FALLBACKS_H */
diff --git a/include/configs/sandbox.h b/include/configs/sandbox.h
index 788207d..76c4398 100644
--- a/include/configs/sandbox.h
+++ b/include/configs/sandbox.h
@@ -22,6 +22,8 @@
#ifndef __CONFIG_H
#define __CONFIG_H
+#define CONFIG_DM
+
/* Number of bits in a C 'long' on this architecture */
#define CONFIG_SANDBOX_BITS_PER_LONG 64
diff --git a/include/dm-demo.h b/include/dm-demo.h
new file mode 100644
index 0000000..3bfac5a
--- /dev/null
+++ b/include/dm-demo.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2013 The Chromium OS Authors.
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef __DM_DEMO_H
+#define __DM_DEMO_H
+
+#include <dm.h>
+
+/**
+ * struct dm_demo_cdata - configuration data for demo instance
+ *
+ * @colour: Color of the demo
+ * @sides: Numbers of sides
+ */
+struct dm_demo_cdata {
+ const char *colour;
+ int sides;
+};
+
+struct demo_ops {
+ int (*hello)(struct device *i, int ch);
+ int (*status)(struct device *i, int *status);
+};
+
+int demo_hello(struct device *i, int ch);
+int demo_status(struct device *i, int *status);
+int demo_list(void);
+
+#endif
diff --git a/include/dm.h b/include/dm.h
new file mode 100644
index 0000000..6af3900
--- /dev/null
+++ b/include/dm.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2013 Google, Inc
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef _DM_H_
+#define _DM_H
+
+#include <dm/manager.h>
+#include <dm/structures.h>
+#include <dm/uclass.h>
+
+#endif
diff --git a/include/dm/debug.h b/include/dm/debug.h
new file mode 100644
index 0000000..3f5ea7b
--- /dev/null
+++ b/include/dm/debug.h
@@ -0,0 +1,33 @@
+/*
+ * (C) Copyright 2012
+ * Pavel Herrmann <morpheus.ibis(a)gmail.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+
+#ifndef _DM_DEBUG_H_
+#define _DM_DEBUG_H_ 1
+
+#include <dm/structures.h>
+
+int dm_dump_all(void);
+int dm_dump(struct device *i);
+
+#endif
diff --git a/include/dm/manager.h b/include/dm/manager.h
new file mode 100644
index 0000000..fcc001e
--- /dev/null
+++ b/include/dm/manager.h
@@ -0,0 +1,57 @@
+/*
+ * (C) Copyright 2012
+ * Pavel Herrmann <morpheus.ibis(a)gmail.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef _DM_MANAGER_H_
+#define _DM_MANAGER_H_
+
+#include <dm/uclass.h>
+#include <dm/structures.h>
+
+/* find-and-add function for the class tree */
+struct uclass *class_get_instance(enum uclass_id id);
+struct u_boot_class *get_class_by_id(enum uclass_id id);
+
+/* class API wrappers */
+int uclass_get_count(enum uclass_id id);
+struct device *uclass_get_child(enum uclass_id id, int index);
+int uclass_bind(enum uclass_id id, struct device *dev);
+int uclass_unbind(enum uclass_id id, struct device *dev);
+int uclass_replace(enum uclass_id id, struct device *new, struct device *old);
+
+/* driver manager API */
+struct device *driver_bind(struct device *parent,
+ const struct driver_info *info);
+int driver_activate(struct device *i);
+int driver_remove(struct device *i);
+int driver_unbind(struct device *dev);
+struct u_boot_driver *get_driver_by_instance(struct device *i);
+
+/* relocation stuff */
+struct device *driver_relocate(struct device *dev, struct device *bus);
+int classs_relocate(void);
+
+/* tree creation helpers */
+int dm_init(void);
+struct device *get_root_instance(void);
+
+#endif
diff --git a/include/dm/structures.h b/include/dm/structures.h
new file mode 100644
index 0000000..32ca832
--- /dev/null
+++ b/include/dm/structures.h
@@ -0,0 +1,97 @@
+/*
+ * (C) Copyright 2012
+ * Pavel Herrmann <morpheus.ibis(a)gmail.com>
+ * Marek Vasut <marex(a)denx.de>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef _DM_STRUCTURES_H_
+#define _DM_STRUCTURES_H_
+
+#include <common.h>
+#include <errno.h>
+#include <linker_lists.h>
+#include <dm/uclass.h>
+#include <linux/list.h>
+
+struct driver_info {
+ const char *name;
+ const void *platform_data;
+};
+
+#define DM_FLAG_ACTIVATED 1
+
+struct device {
+ struct u_boot_driver *driver;
+ const struct driver_info *info;
+ struct device *bus;
+ void *priv;
+ struct list_head class_node; /* attach instances to class */
+ struct list_head succ; /* list of all instances */
+ struct list_head sibling; /* siblings */
+ uint32_t flags;
+};
+
+#define device_get_ops(dev) (dev->driver->ops)
+
+/* structures for driver manager */
+
+enum aux_data_type {
+ U_BOOT_DRIVER_AUX_NONE = 0,
+ U_BOOT_DRIVER_AUX_USB,
+ U_BOOT_DRIVER_AUX_PCI,
+};
+
+struct u_boot_driver {
+ char *name;
+ enum uclass_id id;
+ int (*bind)(struct device *i);
+ int (*probe)(struct device *i);
+ int (*reloc)(struct device *new, struct device *old);
+ int (*remove)(struct device *i);
+ int (*unbind)(struct device *i);
+ int priv_data_size;
+ const void *ops; /* driver-specific operations */
+ enum aux_data_type aux_data_type;
+ void *aux_data;
+};
+
+struct usb_ids {
+ int (*match)(void);
+ struct {
+ uint16_t major;
+ uint16_t minor;
+ } ids[];
+};
+
+/*
+ * The USB driver has special needs, hence the separate type of driver.
+ * Yet, the struct u_boot_driver must be located at the first place, so the
+ * generic searching functions can be used.
+ */
+struct u_boot_usb_driver {
+ struct u_boot_driver driver;
+ struct usb_ids *ids;
+};
+
+#define U_BOOT_DRIVER(__name) \
+ ll_entry_declare(struct u_boot_driver, __name, driver)
+
+#endif
diff --git a/include/dm/uclass.h b/include/dm/uclass.h
new file mode 100644
index 0000000..ce040e7
--- /dev/null
+++ b/include/dm/uclass.h
@@ -0,0 +1,62 @@
+/*
+ * (C) Copyright 2012
+ * Pavel Herrmann <morpheus.ibis(a)gmail.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef _DM_UCLASS_H
+#define _DM_UCLASS_H
+
+#include <linux/list.h>
+
+/* TODO: this could be compile-time generated */
+enum uclass_id {
+ UCLASS_GPIO = 0,
+ UCLASS_DEMO,
+
+ UCLASS_COUNT,
+ UCLASS_INVALID = -1,
+};
+
+struct uclass {
+ void *priv;
+ struct u_boot_class *dm_class;
+ struct list_head class_node; /* instances for this class */
+ struct list_head succ;
+};
+
+struct device;
+
+struct u_boot_class {
+ enum uclass_id id;
+ int (*bind)(struct uclass *class, struct device *dev);
+ int (*unbind)(struct uclass *class, struct device *dev);
+ int (*init)(struct uclass *class);
+ int (*reloc)(struct uclass *new, struct uclass *old);
+ int (*destroy)(struct uclass *class);
+ int (*replace)(struct uclass *class, struct device *new,
+ struct device *old);
+ const void *ops; /* class-specific operations */
+};
+
+#define U_BOOT_CLASS(__name) \
+ ll_entry_declare(struct u_boot_class, __name, class)
+
+#endif
--
1.8.2.1
2
5
Hi, experts:
There are many picture format: BMP / PNG / JPEG etc.
How many picture formats does uboot support currently?
Best wishes,
1
0
Hi, experts:
I found some macro definitions, such as:
#define CONFIG_ARM_ERRATA_743622
#define CONFIG_ARM_ERRATA_751472
So, my question is:
Where do i get these errata descriptions?
Are there related to specific ARM SOC Vendors? Or just ARM Core's common
errata?
Best wishes,
1
0

[U-Boot] [PATCH v1] mmc: bfin: Ensure MMR writing is done before next command.
by Sonic Zhang 27 Apr '13
by Sonic Zhang 27 Apr '13
27 Apr '13
From: Sonic Zhang <sonic.zhang(a)analog.com>
- Ensure MMR writing is done before next command.
- Invalidate the buffer before starting to read.
Signed-off-by: Sonic Zhang <sonic.zhang(a)analog.com>
---
drivers/mmc/bfin_sdh.c | 30 +++++++++++++++++++++++-------
1 files changed, 23 insertions(+), 7 deletions(-)
diff --git a/drivers/mmc/bfin_sdh.c b/drivers/mmc/bfin_sdh.c
index 0f98b96..028cb58 100644
--- a/drivers/mmc/bfin_sdh.c
+++ b/drivers/mmc/bfin_sdh.c
@@ -136,6 +136,9 @@ static int sdh_setup_data(struct mmc *mmc, struct mmc_data *data)
/* Don't support write yet. */
if (data->flags & MMC_DATA_WRITE)
return UNUSABLE_ERR;
+ blackfin_dcache_flush_invalidate_range(data->dest,
+ data->dest + data_size);
+ SSYNC();
#ifndef RSI_BLKSZ
data_ctl |= ((ffs(data_size) - 1) << 4);
#else
@@ -143,21 +146,22 @@ static int sdh_setup_data(struct mmc *mmc, struct mmc_data *data)
#endif
data_ctl |= DTX_DIR;
bfin_write_SDH_DATA_CTL(data_ctl);
+ SSYNC();
dma_cfg = WDSIZE_32 | PSIZE_32 | RESTART | WNR | DMAEN;
bfin_write_SDH_DATA_TIMER(-1);
-
- blackfin_dcache_flush_invalidate_range(data->dest,
- data->dest + data_size);
+ SSYNC();
/* configure DMA */
bfin_write_DMA_START_ADDR(data->dest);
bfin_write_DMA_X_COUNT(data_size / 4);
bfin_write_DMA_X_MODIFY(4);
bfin_write_DMA_CONFIG(dma_cfg);
+ SSYNC();
bfin_write_SDH_DATA_LGTH(data_size);
+ SSYNC();
/* kick off transfer */
bfin_write_SDH_DATA_CTL(bfin_read_SDH_DATA_CTL() | DTX_DMA_E | DTX_E);
-
+ SSYNC();
return 0;
}
@@ -167,6 +171,7 @@ static int bfin_sdh_request(struct mmc *mmc, struct mmc_cmd *cmd,
{
u32 status;
int ret = 0;
+ u16 reg = 0;
if (data) {
ret = sdh_setup_data(mmc, data);
@@ -191,14 +196,18 @@ static int bfin_sdh_request(struct mmc *mmc, struct mmc_cmd *cmd,
} while (!(status & (DAT_BLK_END | DAT_END | DAT_TIME_OUT | DAT_CRC_FAIL | RX_OVERRUN)));
if (status & DAT_TIME_OUT) {
- bfin_write_SDH_STATUS_CLR(DAT_TIMEOUT_STAT);
+ reg |= DAT_TIMEOUT_STAT;
ret |= TIMEOUT;
} else if (status & (DAT_CRC_FAIL | RX_OVERRUN)) {
- bfin_write_SDH_STATUS_CLR(DAT_CRC_FAIL_STAT | RX_OVERRUN_STAT);
+ reg |= DAT_CRC_FAIL_STAT | RX_OVERRUN_STAT;
ret |= COMM_ERR;
} else
- bfin_write_SDH_STATUS_CLR(DAT_BLK_END_STAT | DAT_END_STAT);
+ reg |= DAT_BLK_END_STAT | DAT_END_STAT;
+ bfin_write_SDH_STATUS_CLR(reg);
+ bfin_write_DMA_CONFIG(0);
+ bfin_write_SDH_DATA_CTL(0);
+ SSYNC();
if (ret) {
printf("tranfering data failed\n");
return ret;
@@ -218,6 +227,7 @@ static void sdh_set_clk(unsigned long clk)
/* setting SD_CLK */
sys_clk = get_sclk();
bfin_write_SDH_CLK_CTL(clk_ctl & ~CLK_E);
+ SSYNC();
if (sys_clk % (2 * clk) == 0)
clk_div = sys_clk / (2 * clk) - 1;
else
@@ -230,6 +240,7 @@ static void sdh_set_clk(unsigned long clk)
bfin_write_SDH_CLK_CTL(clk_ctl);
} else
bfin_write_SDH_CLK_CTL(clk_ctl & ~CLK_E);
+ SSYNC();
}
static void bfin_sdh_set_ios(struct mmc *mmc)
@@ -247,6 +258,7 @@ static void bfin_sdh_set_ios(struct mmc *mmc)
clk_ctl |= WIDE_BUS_4;
}
bfin_write_SDH_CLK_CTL(clk_ctl);
+ SSYNC();
sdh_set_clk(mmc->clock);
}
@@ -262,14 +274,18 @@ static int bfin_sdh_init(struct mmc *mmc)
#if defined(__ADSPBF54x__)
bfin_write_DMAC1_PERIMUX(bfin_read_DMAC1_PERIMUX() | 0x1);
#endif
+ SSYNC();
bfin_write_SDH_CFG(bfin_read_SDH_CFG() | CLKS_EN);
+ SSYNC();
/* Disable card detect pin */
bfin_write_SDH_CFG((bfin_read_SDH_CFG() & 0x1F) | 0x60);
+ SSYNC();
#ifndef RSI_BLKSZ
bfin_write_SDH_PWR_CTL(PWR_ON | ROD_CTL);
#else
bfin_write_SDH_CFG(bfin_read_SDH_CFG() | PWR_ON);
#endif
+ SSYNC();
return 0;
}
--
1.7.0.4
2
2
Hi All,
I need some help regarding mmc write and mmc read commands usage.
I am using a 4GB SD/MMC plus and socked eMMC cards, usually I am
formatting these cards on my host pc with
fat partition and copy the images into card. while in the u-boot level
I am reading the images from card and copy it onto mem addr
like fatload mmc 0 0x1000 uImage.
Can we write the images onto these cards in u-boot level?, using mmc write.
same way can we read back using mmc read? if so how to do that.
Request for help.
Thanks,
Jagan.
2
4
Greetings,
I've gotten a new custom OMAP4 board and can't get the SDRAM to work.
My plan is to retest part of this on a 4460 ES1.1 Pandaboard next week but
wanted to put a feeler out now to see if this is known. I've see this today
using DENX Mainline u-boot and u-boot-arm/master.
I'm currently on u-boot-arm/master:
U-Boot SPL 2013.04-rc2-14354-gf2e8a87-dirty (Apr 26 2013 - 18:37:55)
I have one case that works. An older board (whose CPU I think is identical
to the Panda mentioned above). Using pre-canned SDRAM/EMIFS settings this
seems to work. However with what seems to be a new CPU the pre-canned
settings hang (it seems in omap_sdram_size()).
So I tried to use the SDRAM auto-detect modes:
#undef CONFIG_SYS_EMIF_PRECALCULATED_TIMING_REGS
#define CONFIG_SYS_AUTOMATIC_SDRAM_DETECTION
(I've tried it with and without CONFIG_SYS_DEFAULT_LPDDR2_TIMINGS and see
no difference.)
It still hangs in omap_sdram_size() on both the old and new CPUs but
interestingly the new one reports:
EMIF1 CS0 Micron LPDDR2-S4 512 MB
get_mr: EMIF1 cs 1 mr 80000000 val 0xffffffff
EMIF2 CS0 Micron LPDDR2-S4 512 MB
get_mr: EMIF2 cs 1 mr 80000000 val 0xffffffff
emif1_size 0x20000000 emif2_size 0x20000000
<<dmm_init() EMIF1 en: 1, EMIF2 en: 1
When I try that auto-detect mode on the old CPU I get:
EMIF1 CS0 Micron LPDDR2-S4 256 MB
EMIF1 CS1 Micron LPDDR2-S4 256 MB
EMIF2 CS0 Micron LPDDR2-S4 256 MB
EMIF2 CS1 Micron LPDDR2-S4 256 MB
Are the SDRAM auto-detect modes expected to work on OMAP4460ES1.1?
I'll report the Panda testing next week.
Thanks
-Mike Cashwell
1
0
Allow usage of the imx-common/iomux-v3.h framework by including pad settings for
the i.MX25. The content of the file is taken from Linux kernel at commit
267dd34, plus the required changes to make it work in U-Boot.
Signed-off-by: Benoît Thébaudeau <benoit.thebaudeau(a)advansee.com>
---
arch/arm/imx-common/Makefile | 5 +-
arch/arm/include/asm/arch-mx25/imx-regs.h | 1 +
arch/arm/include/asm/arch-mx25/iomux-mx25.h | 545 +++++++++++++++++++++++++++
3 files changed, 550 insertions(+), 1 deletion(-)
create mode 100644 arch/arm/include/asm/arch-mx25/iomux-mx25.h
diff --git a/arch/arm/imx-common/Makefile b/arch/arm/imx-common/Makefile
index 9309439..df54040 100644
--- a/arch/arm/imx-common/Makefile
+++ b/arch/arm/imx-common/Makefile
@@ -27,8 +27,11 @@ include $(TOPDIR)/config.mk
LIB = $(obj)libimx-common.o
+ifeq ($(SOC),$(filter $(SOC),mx25 mx5 mx6))
+COBJS-y = iomux-v3.o
+endif
ifeq ($(SOC),$(filter $(SOC),mx5 mx6))
-COBJS-y = iomux-v3.o timer.o cpu.o speed.o
+COBJS-y = timer.o cpu.o speed.o
COBJS-$(CONFIG_I2C_MXC) += i2c-mxv7.o
endif
ifeq ($(SOC),$(filter $(SOC),mx6 mxs))
diff --git a/arch/arm/include/asm/arch-mx25/imx-regs.h b/arch/arm/include/asm/arch-mx25/imx-regs.h
index 5f4b543..08609c1 100644
--- a/arch/arm/include/asm/arch-mx25/imx-regs.h
+++ b/arch/arm/include/asm/arch-mx25/imx-regs.h
@@ -187,6 +187,7 @@ struct aips_regs {
#define IMX_CSPI1_BASE (0x43FA4000)
#define IMX_KPP_BASE (0x43FA8000)
#define IMX_IOPADMUX_BASE (0x43FAC000)
+#define IOMUXC_BASE_ADDR IMX_IOPADMUX_BASE
#define IMX_IOPADCTL_BASE (0x43FAC22C)
#define IMX_IOPADGRPCTL_BASE (0x43FAC418)
#define IMX_IOPADINPUTSEL_BASE (0x43FAC460)
diff --git a/arch/arm/include/asm/arch-mx25/iomux-mx25.h b/arch/arm/include/asm/arch-mx25/iomux-mx25.h
new file mode 100644
index 0000000..c0f5c61
--- /dev/null
+++ b/arch/arm/include/asm/arch-mx25/iomux-mx25.h
@@ -0,0 +1,545 @@
+/*
+ * (C) Copyright 2013 ADVANSEE
+ * Benoît Thébaudeau <benoit.thebaudeau(a)advansee.com>
+ *
+ * Based on mainline Linux i.MX iomux-mx25.h file:
+ * Copyright (C) 2009 by Lothar Wassmann <LW(a)KARO-electronics.de>
+ *
+ * Based on Linux arch/arm/mach-mx25/mx25_pins.h:
+ * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved.
+ * and Linux arch/arm/plat-mxc/include/mach/iomux-mx35.h:
+ * Copyright (C) 2009 by Jan Weitzel Phytec Messtechnik GmbH <armlinux(a)phytec.de>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef __IOMUX_MX25_H__
+#define __IOMUX_MX25_H__
+
+#include <asm/imx-common/iomux-v3.h>
+
+/* Pad control groupings */
+#define MX25_KPP_ROW_PAD_CTRL PAD_CTL_PUS_100K_UP
+#define MX25_KPP_COL_PAD_CTRL (PAD_CTL_PUS_100K_UP | PAD_CTL_ODE)
+
+/*
+ * The naming convention for the pad modes is MX25_PAD_<padname>__<padmode>
+ * If <padname> or <padmode> refers to a GPIO, it is named GPIO_<unit>_<num>
+ * See also iomux-v3.h
+ */
+
+/* PAD MUX ALT INPSE PATH PADCTRL */
+enum {
+ MX25_PAD_A10__A10 = IOMUX_PAD(0x000, 0x008, 0x00, 0, 0, NO_PAD_CTRL),
+ MX25_PAD_A10__GPIO_4_0 = IOMUX_PAD(0x000, 0x008, 0x05, 0, 0, NO_PAD_CTRL),
+
+ MX25_PAD_A13__A13 = IOMUX_PAD(0x22C, 0x00c, 0x00, 0, 0, NO_PAD_CTRL),
+ MX25_PAD_A13__GPIO_4_1 = IOMUX_PAD(0x22C, 0x00c, 0x05, 0, 0, NO_PAD_CTRL),
+
+ MX25_PAD_A14__A14 = IOMUX_PAD(0x230, 0x010, 0x10, 0, 0, NO_PAD_CTRL),
+ MX25_PAD_A14__GPIO_2_0 = IOMUX_PAD(0x230, 0x010, 0x15, 0, 0, NO_PAD_CTRL),
+
+ MX25_PAD_A15__A15 = IOMUX_PAD(0x234, 0x014, 0x10, 0, 0, NO_PAD_CTRL),
+ MX25_PAD_A15__GPIO_2_1 = IOMUX_PAD(0x234, 0x014, 0x15, 0, 0, NO_PAD_CTRL),
+
+ MX25_PAD_A16__A16 = IOMUX_PAD(0x000, 0x018, 0x10, 0, 0, NO_PAD_CTRL),
+ MX25_PAD_A16__GPIO_2_2 = IOMUX_PAD(0x000, 0x018, 0x15, 0, 0, NO_PAD_CTRL),
+
+ MX25_PAD_A17__A17 = IOMUX_PAD(0x238, 0x01c, 0x10, 0, 0, NO_PAD_CTRL),
+ MX25_PAD_A17__GPIO_2_3 = IOMUX_PAD(0x238, 0x01c, 0x15, 0, 0, NO_PAD_CTRL),
+
+ MX25_PAD_A18__A18 = IOMUX_PAD(0x23c, 0x020, 0x10, 0, 0, NO_PAD_CTRL),
+ MX25_PAD_A18__GPIO_2_4 = IOMUX_PAD(0x23c, 0x020, 0x15, 0, 0, NO_PAD_CTRL),
+ MX25_PAD_A18__FEC_COL = IOMUX_PAD(0x23c, 0x020, 0x17, 0x504, 0, NO_PAD_CTRL),
+
+ MX25_PAD_A19__A19 = IOMUX_PAD(0x240, 0x024, 0x10, 0, 0, NO_PAD_CTRL),
+ MX25_PAD_A19__FEC_RX_ER = IOMUX_PAD(0x240, 0x024, 0x17, 0x518, 0, NO_PAD_CTRL),
+ MX25_PAD_A19__GPIO_2_5 = IOMUX_PAD(0x240, 0x024, 0x15, 0, 0, NO_PAD_CTRL),
+
+ MX25_PAD_A20__A20 = IOMUX_PAD(0x244, 0x028, 0x10, 0, 0, NO_PAD_CTRL),
+ MX25_PAD_A20__GPIO_2_6 = IOMUX_PAD(0x244, 0x028, 0x15, 0, 0, NO_PAD_CTRL),
+ MX25_PAD_A20__FEC_RDATA2 = IOMUX_PAD(0x244, 0x028, 0x17, 0x50c, 0, NO_PAD_CTRL),
+
+ MX25_PAD_A21__A21 = IOMUX_PAD(0x248, 0x02c, 0x10, 0, 0, NO_PAD_CTRL),
+ MX25_PAD_A21__GPIO_2_7 = IOMUX_PAD(0x248, 0x02c, 0x15, 0, 0, NO_PAD_CTRL),
+ MX25_PAD_A21__FEC_RDATA3 = IOMUX_PAD(0x248, 0x02c, 0x17, 0x510, 0, NO_PAD_CTRL),
+
+ MX25_PAD_A22__A22 = IOMUX_PAD(0x000, 0x030, 0x10, 0, 0, NO_PAD_CTRL),
+ MX25_PAD_A22__GPIO_2_8 = IOMUX_PAD(0x000, 0x030, 0x15, 0, 0, NO_PAD_CTRL),
+
+ MX25_PAD_A23__A23 = IOMUX_PAD(0x24c, 0x034, 0x10, 0, 0, NO_PAD_CTRL),
+ MX25_PAD_A23__GPIO_2_9 = IOMUX_PAD(0x24c, 0x034, 0x15, 0, 0, NO_PAD_CTRL),
+
+ MX25_PAD_A24__A24 = IOMUX_PAD(0x250, 0x038, 0x10, 0, 0, NO_PAD_CTRL),
+ MX25_PAD_A24__GPIO_2_10 = IOMUX_PAD(0x250, 0x038, 0x15, 0, 0, NO_PAD_CTRL),
+ MX25_PAD_A24__FEC_RX_CLK = IOMUX_PAD(0x250, 0x038, 0x17, 0x514, 0, NO_PAD_CTRL),
+
+ MX25_PAD_A25__A25 = IOMUX_PAD(0x254, 0x03c, 0x10, 0, 0, NO_PAD_CTRL),
+ MX25_PAD_A25__GPIO_2_11 = IOMUX_PAD(0x254, 0x03c, 0x15, 0, 0, NO_PAD_CTRL),
+ MX25_PAD_A25__FEC_CRS = IOMUX_PAD(0x254, 0x03c, 0x17, 0x508, 0, NO_PAD_CTRL),
+
+ MX25_PAD_EB0__EB0 = IOMUX_PAD(0x258, 0x040, 0x10, 0, 0, NO_PAD_CTRL),
+ MX25_PAD_EB0__AUD4_TXD = IOMUX_PAD(0x258, 0x040, 0x14, 0x464, 0, NO_PAD_CTRL),
+ MX25_PAD_EB0__GPIO_2_12 = IOMUX_PAD(0x258, 0x040, 0x15, 0, 0, NO_PAD_CTRL),
+
+ MX25_PAD_EB1__EB1 = IOMUX_PAD(0x25c, 0x044, 0x10, 0, 0, NO_PAD_CTRL),
+ MX25_PAD_EB1__AUD4_RXD = IOMUX_PAD(0x25c, 0x044, 0x14, 0x460, 0, NO_PAD_CTRL),
+ MX25_PAD_EB1__GPIO_2_13 = IOMUX_PAD(0x25c, 0x044, 0x15, 0, 0, NO_PAD_CTRL),
+
+ MX25_PAD_OE__OE = IOMUX_PAD(0x260, 0x048, 0x10, 0, 0, NO_PAD_CTRL),
+ MX25_PAD_OE__AUD4_TXC = IOMUX_PAD(0x260, 0x048, 0x14, 0, 0, NO_PAD_CTRL),
+ MX25_PAD_OE__GPIO_2_14 = IOMUX_PAD(0x260, 0x048, 0x15, 0, 0, NO_PAD_CTRL),
+
+ MX25_PAD_CS0__CS0 = IOMUX_PAD(0x000, 0x04c, 0x00, 0, 0, NO_PAD_CTRL),
+ MX25_PAD_CS0__GPIO_4_2 = IOMUX_PAD(0x000, 0x04c, 0x05, 0, 0, NO_PAD_CTRL),
+
+ MX25_PAD_CS1__CS1 = IOMUX_PAD(0x000, 0x050, 0x00, 0, 0, NO_PAD_CTRL),
+ MX25_PAD_CS1__NF_CE3 = IOMUX_PAD(0x000, 0x050, 0x01, 0, 0, NO_PAD_CTRL),
+ MX25_PAD_CS1__GPIO_4_3 = IOMUX_PAD(0x000, 0x050, 0x05, 0, 0, NO_PAD_CTRL),
+
+ MX25_PAD_CS4__CS4 = IOMUX_PAD(0x264, 0x054, 0x10, 0, 0, NO_PAD_CTRL),
+ MX25_PAD_CS4__NF_CE1 = IOMUX_PAD(0x264, 0x054, 0x01, 0, 0, NO_PAD_CTRL),
+ MX25_PAD_CS4__UART5_CTS = IOMUX_PAD(0x264, 0x054, 0x13, 0, 0, NO_PAD_CTRL),
+ MX25_PAD_CS4__GPIO_3_20 = IOMUX_PAD(0x264, 0x054, 0x15, 0, 0, NO_PAD_CTRL),
+
+ MX25_PAD_CS5__CS5 = IOMUX_PAD(0x268, 0x058, 0x10, 0, 0, NO_PAD_CTRL),
+ MX25_PAD_CS5__NF_CE2 = IOMUX_PAD(0x268, 0x058, 0x01, 0, 0, NO_PAD_CTRL),
+ MX25_PAD_CS5__UART5_RTS = IOMUX_PAD(0x268, 0x058, 0x13, 0x574, 0, NO_PAD_CTRL),
+ MX25_PAD_CS5__GPIO_3_21 = IOMUX_PAD(0x268, 0x058, 0x15, 0, 0, NO_PAD_CTRL),
+
+ MX25_PAD_NF_CE0__NF_CE0 = IOMUX_PAD(0x26c, 0x05c, 0x10, 0, 0, NO_PAD_CTRL),
+ MX25_PAD_NF_CE0__GPIO_3_22 = IOMUX_PAD(0x26c, 0x05c, 0x15, 0, 0, NO_PAD_CTRL),
+
+ MX25_PAD_ECB__ECB = IOMUX_PAD(0x270, 0x060, 0x10, 0, 0, NO_PAD_CTRL),
+ MX25_PAD_ECB__UART5_TXD_MUX = IOMUX_PAD(0x270, 0x060, 0x13, 0, 0, NO_PAD_CTRL),
+ MX25_PAD_ECB__GPIO_3_23 = IOMUX_PAD(0x270, 0x060, 0x15, 0, 0, NO_PAD_CTRL),
+
+ MX25_PAD_LBA__LBA = IOMUX_PAD(0x274, 0x064, 0x10, 0, 0, NO_PAD_CTRL),
+ MX25_PAD_LBA__UART5_RXD_MUX = IOMUX_PAD(0x274, 0x064, 0x13, 0x578, 0, NO_PAD_CTRL),
+ MX25_PAD_LBA__GPIO_3_24 = IOMUX_PAD(0x274, 0x064, 0x15, 0, 0, NO_PAD_CTRL),
+
+ MX25_PAD_BCLK__BCLK = IOMUX_PAD(0x000, 0x068, 0x00, 0, 0, NO_PAD_CTRL),
+ MX25_PAD_BCLK__GPIO_4_4 = IOMUX_PAD(0x000, 0x068, 0x05, 0, 0, NO_PAD_CTRL),
+
+ MX25_PAD_RW__RW = IOMUX_PAD(0x278, 0x06c, 0x10, 0, 0, NO_PAD_CTRL),
+ MX25_PAD_RW__AUD4_TXFS = IOMUX_PAD(0x278, 0x06c, 0x14, 0x474, 0, NO_PAD_CTRL),
+ MX25_PAD_RW__GPIO_3_25 = IOMUX_PAD(0x278, 0x06c, 0x15, 0, 0, NO_PAD_CTRL),
+
+ MX25_PAD_NFWE_B__NFWE_B = IOMUX_PAD(0x000, 0x070, 0x10, 0, 0, NO_PAD_CTRL),
+ MX25_PAD_NFWE_B__GPIO_3_26 = IOMUX_PAD(0x000, 0x070, 0x15, 0, 0, NO_PAD_CTRL),
+
+ MX25_PAD_NFRE_B__NFRE_B = IOMUX_PAD(0x000, 0x074, 0x10, 0, 0, NO_PAD_CTRL),
+ MX25_PAD_NFRE_B__GPIO_3_27 = IOMUX_PAD(0x000, 0x074, 0x15, 0, 0, NO_PAD_CTRL),
+
+ MX25_PAD_NFALE__NFALE = IOMUX_PAD(0x000, 0x078, 0x10, 0, 0, NO_PAD_CTRL),
+ MX25_PAD_NFALE__GPIO_3_28 = IOMUX_PAD(0x000, 0x078, 0x15, 0, 0, NO_PAD_CTRL),
+
+ MX25_PAD_NFCLE__NFCLE = IOMUX_PAD(0x000, 0x07c, 0x10, 0, 0, NO_PAD_CTRL),
+ MX25_PAD_NFCLE__GPIO_3_29 = IOMUX_PAD(0x000, 0x07c, 0x15, 0, 0, NO_PAD_CTRL),
+
+ MX25_PAD_NFWP_B__NFWP_B = IOMUX_PAD(0x000, 0x080, 0x10, 0, 0, NO_PAD_CTRL),
+ MX25_PAD_NFWP_B__GPIO_3_30 = IOMUX_PAD(0x000, 0x080, 0x15, 0, 0, NO_PAD_CTRL),
+
+ MX25_PAD_NFRB__NFRB = IOMUX_PAD(0x27c, 0x084, 0x10, 0, 0, PAD_CTL_PKE),
+ MX25_PAD_NFRB__GPIO_3_31 = IOMUX_PAD(0x27c, 0x084, 0x15, 0, 0, NO_PAD_CTRL),
+
+ MX25_PAD_D15__D15 = IOMUX_PAD(0x280, 0x088, 0x00, 0, 0, NO_PAD_CTRL),
+ MX25_PAD_D15__LD16 = IOMUX_PAD(0x280, 0x088, 0x01, 0, 0, PAD_CTL_SRE_FAST),
+ MX25_PAD_D15__GPIO_4_5 = IOMUX_PAD(0x280, 0x088, 0x05, 0, 0, NO_PAD_CTRL),
+
+ MX25_PAD_D14__D14 = IOMUX_PAD(0x284, 0x08c, 0x00, 0, 0, NO_PAD_CTRL),
+ MX25_PAD_D14__LD17 = IOMUX_PAD(0x284, 0x08c, 0x01, 0, 0, PAD_CTL_SRE_FAST),
+ MX25_PAD_D14__GPIO_4_6 = IOMUX_PAD(0x284, 0x08c, 0x05, 0, 0, NO_PAD_CTRL),
+
+ MX25_PAD_D13__D13 = IOMUX_PAD(0x288, 0x090, 0x00, 0, 0, NO_PAD_CTRL),
+ MX25_PAD_D13__LD18 = IOMUX_PAD(0x288, 0x090, 0x01, 0, 0, PAD_CTL_SRE_FAST),
+ MX25_PAD_D13__GPIO_4_7 = IOMUX_PAD(0x288, 0x090, 0x05, 0, 0, NO_PAD_CTRL),
+
+ MX25_PAD_D12__D12 = IOMUX_PAD(0x28c, 0x094, 0x00, 0, 0, NO_PAD_CTRL),
+ MX25_PAD_D12__GPIO_4_8 = IOMUX_PAD(0x28c, 0x094, 0x05, 0, 0, NO_PAD_CTRL),
+
+ MX25_PAD_D11__D11 = IOMUX_PAD(0x290, 0x098, 0x00, 0, 0, NO_PAD_CTRL),
+ MX25_PAD_D11__GPIO_4_9 = IOMUX_PAD(0x290, 0x098, 0x05, 0, 0, NO_PAD_CTRL),
+
+ MX25_PAD_D10__D10 = IOMUX_PAD(0x294, 0x09c, 0x00, 0, 0, NO_PAD_CTRL),
+ MX25_PAD_D10__GPIO_4_10 = IOMUX_PAD(0x294, 0x09c, 0x05, 0, 0, NO_PAD_CTRL),
+ MX25_PAD_D10__USBOTG_OC = IOMUX_PAD(0x294, 0x09c, 0x06, 0x57c, 0, PAD_CTL_PUS_100K_UP),
+
+ MX25_PAD_D9__D9 = IOMUX_PAD(0x298, 0x0a0, 0x00, 0, 0, NO_PAD_CTRL),
+ MX25_PAD_D9__GPIO_4_11 = IOMUX_PAD(0x298, 0x0a0, 0x05, 0, 0, NO_PAD_CTRL),
+ MX25_PAD_D9__USBH2_PWR = IOMUX_PAD(0x298, 0x0a0, 0x06, 0, 0, PAD_CTL_PKE),
+
+ MX25_PAD_D8__D8 = IOMUX_PAD(0x29c, 0x0a4, 0x00, 0, 0, NO_PAD_CTRL),
+ MX25_PAD_D8__GPIO_4_12 = IOMUX_PAD(0x29c, 0x0a4, 0x05, 0, 0, NO_PAD_CTRL),
+ MX25_PAD_D8__USBH2_OC = IOMUX_PAD(0x29c, 0x0a4, 0x06, 0x580, 0, PAD_CTL_PUS_100K_UP),
+
+ MX25_PAD_D7__D7 = IOMUX_PAD(0x2a0, 0x0a8, 0x00, 0, 0, NO_PAD_CTRL),
+ MX25_PAD_D7__GPIO_4_13 = IOMUX_PAD(0x2a0, 0x0a8, 0x05, 0, 0, NO_PAD_CTRL),
+
+ MX25_PAD_D6__D6 = IOMUX_PAD(0x2a4, 0x0ac, 0x00, 0, 0, NO_PAD_CTRL),
+ MX25_PAD_D6__GPIO_4_14 = IOMUX_PAD(0x2a4, 0x0ac, 0x05, 0, 0, NO_PAD_CTRL),
+
+ MX25_PAD_D5__D5 = IOMUX_PAD(0x2a8, 0x0b0, 0x00, 0, 0, NO_PAD_CTRL),
+ MX25_PAD_D5__GPIO_4_15 = IOMUX_PAD(0x2a8, 0x0b0, 0x05, 0, 0, NO_PAD_CTRL),
+
+ MX25_PAD_D4__D4 = IOMUX_PAD(0x2ac, 0x0b4, 0x00, 0, 0, NO_PAD_CTRL),
+ MX25_PAD_D4__GPIO_4_16 = IOMUX_PAD(0x2ac, 0x0b4, 0x05, 0, 0, NO_PAD_CTRL),
+
+ MX25_PAD_D3__D3 = IOMUX_PAD(0x2b0, 0x0b8, 0x00, 0, 0, NO_PAD_CTRL),
+ MX25_PAD_D3__GPIO_4_17 = IOMUX_PAD(0x2b0, 0x0b8, 0x05, 0, 0, NO_PAD_CTRL),
+
+ MX25_PAD_D2__D2 = IOMUX_PAD(0x2b4, 0x0bc, 0x00, 0, 0, NO_PAD_CTRL),
+ MX25_PAD_D2__GPIO_4_18 = IOMUX_PAD(0x2b4, 0x0bc, 0x05, 0, 0, NO_PAD_CTRL),
+
+ MX25_PAD_D1__D1 = IOMUX_PAD(0x2b8, 0x0c0, 0x00, 0, 0, NO_PAD_CTRL),
+ MX25_PAD_D1__GPIO_4_19 = IOMUX_PAD(0x2b8, 0x0c0, 0x05, 0, 0, NO_PAD_CTRL),
+
+ MX25_PAD_D0__D0 = IOMUX_PAD(0x2bc, 0x0c4, 0x00, 0, 0, NO_PAD_CTRL),
+ MX25_PAD_D0__GPIO_4_20 = IOMUX_PAD(0x2bc, 0x0c4, 0x05, 0, 0, NO_PAD_CTRL),
+
+ MX25_PAD_LD0__LD0 = IOMUX_PAD(0x2c0, 0x0c8, 0x10, 0, 0, PAD_CTL_SRE_FAST),
+ MX25_PAD_LD0__CSI_D0 = IOMUX_PAD(0x2c0, 0x0c8, 0x12, 0x488, 0, NO_PAD_CTRL),
+ MX25_PAD_LD0__GPIO_2_15 = IOMUX_PAD(0x2c0, 0x0c8, 0x15, 0, 0, NO_PAD_CTRL),
+
+ MX25_PAD_LD1__LD1 = IOMUX_PAD(0x2c4, 0x0cc, 0x10, 0, 0, PAD_CTL_SRE_FAST),
+ MX25_PAD_LD1__CSI_D1 = IOMUX_PAD(0x2c4, 0x0cc, 0x12, 0x48c, 0, NO_PAD_CTRL),
+ MX25_PAD_LD1__GPIO_2_16 = IOMUX_PAD(0x2c4, 0x0cc, 0x15, 0, 0, NO_PAD_CTRL),
+
+ MX25_PAD_LD2__LD2 = IOMUX_PAD(0x2c8, 0x0d0, 0x10, 0, 0, PAD_CTL_SRE_FAST),
+ MX25_PAD_LD2__GPIO_2_17 = IOMUX_PAD(0x2c8, 0x0d0, 0x15, 0, 0, NO_PAD_CTRL),
+
+ MX25_PAD_LD3__LD3 = IOMUX_PAD(0x2cc, 0x0d4, 0x10, 0, 0, PAD_CTL_SRE_FAST),
+ MX25_PAD_LD3__GPIO_2_18 = IOMUX_PAD(0x2cc, 0x0d4, 0x15, 0, 0, NO_PAD_CTRL),
+
+ MX25_PAD_LD4__LD4 = IOMUX_PAD(0x2d0, 0x0d8, 0x10, 0, 0, PAD_CTL_SRE_FAST),
+ MX25_PAD_LD4__GPIO_2_19 = IOMUX_PAD(0x2d0, 0x0d8, 0x15, 0, 0, NO_PAD_CTRL),
+
+ MX25_PAD_LD5__LD5 = IOMUX_PAD(0x2d4, 0x0dc, 0x10, 0, 0, PAD_CTL_SRE_FAST),
+ MX25_PAD_LD5__GPIO_1_19 = IOMUX_PAD(0x2d4, 0x0dc, 0x15, 0, 0, NO_PAD_CTRL),
+
+ MX25_PAD_LD6__LD6 = IOMUX_PAD(0x2d8, 0x0e0, 0x10, 0, 0, PAD_CTL_SRE_FAST),
+ MX25_PAD_LD6__GPIO_1_20 = IOMUX_PAD(0x2d8, 0x0e0, 0x15, 0, 0, NO_PAD_CTRL),
+
+ MX25_PAD_LD7__LD7 = IOMUX_PAD(0x2dc, 0x0e4, 0x10, 0, 0, PAD_CTL_SRE_FAST),
+ MX25_PAD_LD7__GPIO_1_21 = IOMUX_PAD(0x2dc, 0x0e4, 0x15, 0, 0, NO_PAD_CTRL),
+
+ MX25_PAD_LD8__LD8 = IOMUX_PAD(0x2e0, 0x0e8, 0x10, 0, 0, PAD_CTL_SRE_FAST),
+ MX25_PAD_LD8__FEC_TX_ERR = IOMUX_PAD(0x2e0, 0x0e8, 0x15, 0, 0, NO_PAD_CTRL),
+
+ MX25_PAD_LD9__LD9 = IOMUX_PAD(0x2e4, 0x0ec, 0x10, 0, 0, PAD_CTL_SRE_FAST),
+ MX25_PAD_LD9__FEC_COL = IOMUX_PAD(0x2e4, 0x0ec, 0x15, 0x504, 1, NO_PAD_CTRL),
+
+ MX25_PAD_LD10__LD10 = IOMUX_PAD(0x2e8, 0x0f0, 0x10, 0, 0, PAD_CTL_SRE_FAST),
+ MX25_PAD_LD10__FEC_RX_ER = IOMUX_PAD(0x2e8, 0x0f0, 0x15, 0x518, 1, NO_PAD_CTRL),
+
+ MX25_PAD_LD11__LD11 = IOMUX_PAD(0x2ec, 0x0f4, 0x10, 0, 0, PAD_CTL_SRE_FAST),
+ MX25_PAD_LD11__FEC_RDATA2 = IOMUX_PAD(0x2ec, 0x0f4, 0x15, 0x50c, 1, NO_PAD_CTRL),
+
+ MX25_PAD_LD12__LD12 = IOMUX_PAD(0x2f0, 0x0f8, 0x10, 0, 0, PAD_CTL_SRE_FAST),
+ MX25_PAD_LD12__FEC_RDATA3 = IOMUX_PAD(0x2f0, 0x0f8, 0x15, 0x510, 1, NO_PAD_CTRL),
+
+ MX25_PAD_LD13__LD13 = IOMUX_PAD(0x2f4, 0x0fc, 0x10, 0, 0, PAD_CTL_SRE_FAST),
+ MX25_PAD_LD13__FEC_TDATA2 = IOMUX_PAD(0x2f4, 0x0fc, 0x15, 0, 0, NO_PAD_CTRL),
+
+ MX25_PAD_LD14__LD14 = IOMUX_PAD(0x2f8, 0x100, 0x10, 0, 0, PAD_CTL_SRE_FAST),
+ MX25_PAD_LD14__FEC_TDATA3 = IOMUX_PAD(0x2f8, 0x100, 0x15, 0, 0, NO_PAD_CTRL),
+
+ MX25_PAD_LD15__LD15 = IOMUX_PAD(0x2fc, 0x104, 0x10, 0, 0, PAD_CTL_SRE_FAST),
+ MX25_PAD_LD15__FEC_RX_CLK = IOMUX_PAD(0x2fc, 0x104, 0x15, 0x514, 1, NO_PAD_CTRL),
+
+ MX25_PAD_HSYNC__HSYNC = IOMUX_PAD(0x300, 0x108, 0x10, 0, 0, NO_PAD_CTRL),
+ MX25_PAD_HSYNC__GPIO_1_22 = IOMUX_PAD(0x300, 0x108, 0x15, 0, 0, NO_PAD_CTRL),
+
+ MX25_PAD_VSYNC__VSYNC = IOMUX_PAD(0x304, 0x10c, 0x10, 0, 0, NO_PAD_CTRL),
+ MX25_PAD_VSYNC__GPIO_1_23 = IOMUX_PAD(0x304, 0x10c, 0x15, 0, 0, NO_PAD_CTRL),
+
+ MX25_PAD_LSCLK__LSCLK = IOMUX_PAD(0x308, 0x110, 0x10, 0, 0, NO_PAD_CTRL),
+ MX25_PAD_LSCLK__GPIO_1_24 = IOMUX_PAD(0x308, 0x110, 0x15, 0, 0, NO_PAD_CTRL),
+
+ MX25_PAD_OE_ACD__OE_ACD = IOMUX_PAD(0x30c, 0x114, 0x10, 0, 0, NO_PAD_CTRL),
+ MX25_PAD_OE_ACD__GPIO_1_25 = IOMUX_PAD(0x30c, 0x114, 0x15, 0, 0, NO_PAD_CTRL),
+
+ MX25_PAD_CONTRAST__CONTRAST = IOMUX_PAD(0x310, 0x118, 0x10, 0, 0, NO_PAD_CTRL),
+ MX25_PAD_CONTRAST__PWM4_PWMO = IOMUX_PAD(0x310, 0x118, 0x14, 0, 0, NO_PAD_CTRL),
+ MX25_PAD_CONTRAST__FEC_CRS = IOMUX_PAD(0x310, 0x118, 0x15, 0x508, 1, NO_PAD_CTRL),
+
+ MX25_PAD_PWM__PWM = IOMUX_PAD(0x314, 0x11c, 0x10, 0, 0, NO_PAD_CTRL),
+ MX25_PAD_PWM__GPIO_1_26 = IOMUX_PAD(0x314, 0x11c, 0x15, 0, 0, NO_PAD_CTRL),
+ MX25_PAD_PWM__USBH2_OC = IOMUX_PAD(0x314, 0x11c, 0x16, 0x580, 1, PAD_CTL_PUS_100K_UP),
+
+ MX25_PAD_CSI_D2__CSI_D2 = IOMUX_PAD(0x318, 0x120, 0x10, 0, 0, NO_PAD_CTRL),
+ MX25_PAD_CSI_D2__UART5_RXD_MUX = IOMUX_PAD(0x318, 0x120, 0x11, 0x578, 1, NO_PAD_CTRL),
+ MX25_PAD_CSI_D2__GPIO_1_27 = IOMUX_PAD(0x318, 0x120, 0x15, 0, 0, NO_PAD_CTRL),
+ MX25_PAD_CSI_D2__CSPI3_MOSI = IOMUX_PAD(0x318, 0x120, 0x17, 0, 0, NO_PAD_CTRL),
+
+ MX25_PAD_CSI_D3__CSI_D3 = IOMUX_PAD(0x31c, 0x124, 0x10, 0, 0, NO_PAD_CTRL),
+ MX25_PAD_CSI_D3__GPIO_1_28 = IOMUX_PAD(0x31c, 0x124, 0x15, 0, 0, NO_PAD_CTRL),
+ MX25_PAD_CSI_D3__CSPI3_MISO = IOMUX_PAD(0x31c, 0x124, 0x17, 0x4b4, 1, NO_PAD_CTRL),
+
+ MX25_PAD_CSI_D4__CSI_D4 = IOMUX_PAD(0x320, 0x128, 0x10, 0, 0, NO_PAD_CTRL),
+ MX25_PAD_CSI_D4__UART5_RTS = IOMUX_PAD(0x320, 0x128, 0x11, 0x574, 1, NO_PAD_CTRL),
+ MX25_PAD_CSI_D4__GPIO_1_29 = IOMUX_PAD(0x320, 0x128, 0x15, 0, 0, NO_PAD_CTRL),
+ MX25_PAD_CSI_D4__CSPI3_SCLK = IOMUX_PAD(0x320, 0x128, 0x17, 0, 0, NO_PAD_CTRL),
+
+ MX25_PAD_CSI_D5__CSI_D5 = IOMUX_PAD(0x324, 0x12c, 0x10, 0, 0, NO_PAD_CTRL),
+ MX25_PAD_CSI_D5__GPIO_1_30 = IOMUX_PAD(0x324, 0x12c, 0x15, 0, 0, NO_PAD_CTRL),
+ MX25_PAD_CSI_D5__CSPI3_RDY = IOMUX_PAD(0x324, 0x12c, 0x17, 0, 0, NO_PAD_CTRL),
+
+ MX25_PAD_CSI_D6__CSI_D6 = IOMUX_PAD(0x328, 0x130, 0x10, 0, 0, NO_PAD_CTRL),
+ MX25_PAD_CSI_D6__GPIO_1_31 = IOMUX_PAD(0x328, 0x130, 0x15, 0, 0, NO_PAD_CTRL),
+
+ MX25_PAD_CSI_D7__CSI_D7 = IOMUX_PAD(0x32c, 0x134, 0x10, 0, 0, NO_PAD_CTRL),
+ MX25_PAD_CSI_D7__GPIO_1_6 = IOMUX_PAD(0x32c, 0x134, 0x15, 0, 0, NO_PAD_CTRL),
+
+ MX25_PAD_CSI_D8__CSI_D8 = IOMUX_PAD(0x330, 0x138, 0x10, 0, 0, NO_PAD_CTRL),
+ MX25_PAD_CSI_D8__GPIO_1_7 = IOMUX_PAD(0x330, 0x138, 0x15, 0, 0, NO_PAD_CTRL),
+
+ MX25_PAD_CSI_D9__CSI_D9 = IOMUX_PAD(0x334, 0x13c, 0x10, 0, 0, NO_PAD_CTRL),
+ MX25_PAD_CSI_D9__GPIO_4_21 = IOMUX_PAD(0x334, 0x13c, 0x15, 0, 0, NO_PAD_CTRL),
+
+ MX25_PAD_CSI_MCLK__CSI_MCLK = IOMUX_PAD(0x338, 0x140, 0x10, 0, 0, NO_PAD_CTRL),
+ MX25_PAD_CSI_MCLK__GPIO_1_8 = IOMUX_PAD(0x338, 0x140, 0x15, 0, 0, NO_PAD_CTRL),
+
+ MX25_PAD_CSI_VSYNC__CSI_VSYNC = IOMUX_PAD(0x33c, 0x144, 0x10, 0, 0, NO_PAD_CTRL),
+ MX25_PAD_CSI_VSYNC__GPIO_1_9 = IOMUX_PAD(0x33c, 0x144, 0x15, 0, 0, NO_PAD_CTRL),
+
+ MX25_PAD_CSI_HSYNC__CSI_HSYNC = IOMUX_PAD(0x340, 0x148, 0x10, 0, 0, NO_PAD_CTRL),
+ MX25_PAD_CSI_HSYNC__GPIO_1_10 = IOMUX_PAD(0x340, 0x148, 0x15, 0, 0, NO_PAD_CTRL),
+
+ MX25_PAD_CSI_PIXCLK__CSI_PIXCLK = IOMUX_PAD(0x344, 0x14c, 0x10, 0, 0, NO_PAD_CTRL),
+ MX25_PAD_CSI_PIXCLK__GPIO_1_11 = IOMUX_PAD(0x344, 0x14c, 0x15, 0, 0, NO_PAD_CTRL),
+
+ MX25_PAD_I2C1_CLK__I2C1_CLK = IOMUX_PAD(0x348, 0x150, 0x10, 0, 0, NO_PAD_CTRL),
+ MX25_PAD_I2C1_CLK__GPIO_1_12 = IOMUX_PAD(0x348, 0x150, 0x15, 0, 0, NO_PAD_CTRL),
+
+ MX25_PAD_I2C1_DAT__I2C1_DAT = IOMUX_PAD(0x34c, 0x154, 0x10, 0, 0, NO_PAD_CTRL),
+ MX25_PAD_I2C1_DAT__GPIO_1_13 = IOMUX_PAD(0x34c, 0x154, 0x15, 0, 0, NO_PAD_CTRL),
+
+ MX25_PAD_CSPI1_MOSI__CSPI1_MOSI = IOMUX_PAD(0x350, 0x158, 0x10, 0, 0, NO_PAD_CTRL),
+ MX25_PAD_CSPI1_MOSI__GPIO_1_14 = IOMUX_PAD(0x350, 0x158, 0x15, 0, 0, NO_PAD_CTRL),
+
+ MX25_PAD_CSPI1_MISO__CSPI1_MISO = IOMUX_PAD(0x354, 0x15c, 0x10, 0, 0, NO_PAD_CTRL),
+ MX25_PAD_CSPI1_MISO__GPIO_1_15 = IOMUX_PAD(0x354, 0x15c, 0x15, 0, 0, NO_PAD_CTRL),
+
+ MX25_PAD_CSPI1_SS0__CSPI1_SS0 = IOMUX_PAD(0x358, 0x160, 0x10, 0, 0, NO_PAD_CTRL),
+ MX25_PAD_CSPI1_SS0__GPIO_1_16 = IOMUX_PAD(0x358, 0x160, 0x15, 0, 0, NO_PAD_CTRL),
+
+ MX25_PAD_CSPI1_SS1__CSPI1_SS1 = IOMUX_PAD(0x35c, 0x164, 0x10, 0, 0, NO_PAD_CTRL),
+ MX25_PAD_CSPI1_SS1__I2C3_DAT = IOMUX_PAD(0x35c, 0x164, 0x11, 0x528, 1, NO_PAD_CTRL),
+ MX25_PAD_CSPI1_SS1__GPIO_1_17 = IOMUX_PAD(0x35c, 0x164, 0x15, 0, 0, NO_PAD_CTRL),
+
+ MX25_PAD_CSPI1_SCLK__CSPI1_SCLK = IOMUX_PAD(0x360, 0x168, 0x10, 0, 0, NO_PAD_CTRL),
+ MX25_PAD_CSPI1_SCLK__GPIO_1_18 = IOMUX_PAD(0x360, 0x168, 0x15, 0, 0, NO_PAD_CTRL),
+
+ MX25_PAD_CSPI1_RDY__CSPI1_RDY = IOMUX_PAD(0x364, 0x16c, 0x10, 0, 0, PAD_CTL_PKE),
+ MX25_PAD_CSPI1_RDY__GPIO_2_22 = IOMUX_PAD(0x364, 0x16c, 0x15, 0, 0, NO_PAD_CTRL),
+
+ MX25_PAD_UART1_RXD__UART1_RXD = IOMUX_PAD(0x368, 0x170, 0x10, 0, 0, PAD_CTL_PUS_100K_DOWN),
+ MX25_PAD_UART1_RXD__GPIO_4_22 = IOMUX_PAD(0x368, 0x170, 0x15, 0, 0, NO_PAD_CTRL),
+
+ MX25_PAD_UART1_TXD__UART1_TXD = IOMUX_PAD(0x36c, 0x174, 0x10, 0, 0, NO_PAD_CTRL),
+ MX25_PAD_UART1_TXD__GPIO_4_23 = IOMUX_PAD(0x36c, 0x174, 0x15, 0, 0, NO_PAD_CTRL),
+
+ MX25_PAD_UART1_RTS__UART1_RTS = IOMUX_PAD(0x370, 0x178, 0x10, 0, 0, PAD_CTL_PUS_100K_UP),
+ MX25_PAD_UART1_RTS__CSI_D0 = IOMUX_PAD(0x370, 0x178, 0x11, 0x488, 1, NO_PAD_CTRL),
+ MX25_PAD_UART1_RTS__GPIO_4_24 = IOMUX_PAD(0x370, 0x178, 0x15, 0, 0, NO_PAD_CTRL),
+
+ MX25_PAD_UART1_CTS__UART1_CTS = IOMUX_PAD(0x374, 0x17c, 0x10, 0, 0, PAD_CTL_PUS_100K_UP),
+ MX25_PAD_UART1_CTS__CSI_D1 = IOMUX_PAD(0x374, 0x17c, 0x11, 0x48c, 1, NO_PAD_CTRL),
+ MX25_PAD_UART1_CTS__GPIO_4_25 = IOMUX_PAD(0x374, 0x17c, 0x15, 0, 0, NO_PAD_CTRL),
+
+ MX25_PAD_UART2_RXD__UART2_RXD = IOMUX_PAD(0x378, 0x180, 0x10, 0, 0, NO_PAD_CTRL),
+ MX25_PAD_UART2_RXD__GPIO_4_26 = IOMUX_PAD(0x378, 0x180, 0x15, 0, 0, NO_PAD_CTRL),
+
+ MX25_PAD_UART2_TXD__UART2_TXD = IOMUX_PAD(0x37c, 0x184, 0x10, 0, 0, NO_PAD_CTRL),
+ MX25_PAD_UART2_TXD__GPIO_4_27 = IOMUX_PAD(0x37c, 0x184, 0x15, 0, 0, NO_PAD_CTRL),
+
+ MX25_PAD_UART2_RTS__UART2_RTS = IOMUX_PAD(0x380, 0x188, 0x10, 0, 0, NO_PAD_CTRL),
+ MX25_PAD_UART2_RTS__FEC_COL = IOMUX_PAD(0x380, 0x188, 0x12, 0x504, 2, NO_PAD_CTRL),
+ MX25_PAD_UART2_RTS__GPIO_4_28 = IOMUX_PAD(0x380, 0x188, 0x15, 0, 0, NO_PAD_CTRL),
+
+ MX25_PAD_UART2_CTS__FEC_RX_ER = IOMUX_PAD(0x384, 0x18c, 0x12, 0x518, 2, NO_PAD_CTRL),
+ MX25_PAD_UART2_CTS__UART2_CTS = IOMUX_PAD(0x384, 0x18c, 0x10, 0, 0, NO_PAD_CTRL),
+ MX25_PAD_UART2_CTS__GPIO_4_29 = IOMUX_PAD(0x384, 0x18c, 0x15, 0, 0, NO_PAD_CTRL),
+
+ MX25_PAD_SD1_CMD__SD1_CMD = IOMUX_PAD(0x388, 0x190, 0x10, 0, 0, PAD_CTL_PUS_47K_UP),
+ MX25_PAD_SD1_CMD__FEC_RDATA2 = IOMUX_PAD(0x388, 0x190, 0x12, 0x50c, 2, NO_PAD_CTRL),
+ MX25_PAD_SD1_CMD__GPIO_2_23 = IOMUX_PAD(0x388, 0x190, 0x15, 0, 0, NO_PAD_CTRL),
+
+ MX25_PAD_SD1_CLK__SD1_CLK = IOMUX_PAD(0x38c, 0x194, 0x10, 0, 0, PAD_CTL_PUS_47K_UP),
+ MX25_PAD_SD1_CLK__FEC_RDATA3 = IOMUX_PAD(0x38c, 0x194, 0x12, 0x510, 2, NO_PAD_CTRL),
+ MX25_PAD_SD1_CLK__GPIO_2_24 = IOMUX_PAD(0x38c, 0x194, 0x15, 0, 0, NO_PAD_CTRL),
+
+ MX25_PAD_SD1_DATA0__SD1_DATA0 = IOMUX_PAD(0x390, 0x198, 0x10, 0, 0, PAD_CTL_PUS_47K_UP),
+ MX25_PAD_SD1_DATA0__GPIO_2_25 = IOMUX_PAD(0x390, 0x198, 0x15, 0, 0, NO_PAD_CTRL),
+
+ MX25_PAD_SD1_DATA1__SD1_DATA1 = IOMUX_PAD(0x394, 0x19c, 0x10, 0, 0, PAD_CTL_PUS_47K_UP),
+ MX25_PAD_SD1_DATA1__AUD7_RXD = IOMUX_PAD(0x394, 0x19c, 0x13, 0x478, 0, NO_PAD_CTRL),
+ MX25_PAD_SD1_DATA1__GPIO_2_26 = IOMUX_PAD(0x394, 0x19c, 0x15, 0, 0, NO_PAD_CTRL),
+
+ MX25_PAD_SD1_DATA2__SD1_DATA2 = IOMUX_PAD(0x398, 0x1a0, 0x10, 0, 0, PAD_CTL_PUS_47K_UP),
+ MX25_PAD_SD1_DATA2__FEC_RX_CLK = IOMUX_PAD(0x398, 0x1a0, 0x15, 0x514, 2, NO_PAD_CTRL),
+ MX25_PAD_SD1_DATA2__GPIO_2_27 = IOMUX_PAD(0x398, 0x1a0, 0x15, 0, 0, NO_PAD_CTRL),
+
+ MX25_PAD_SD1_DATA3__SD1_DATA3 = IOMUX_PAD(0x39c, 0x1a4, 0x10, 0, 0, PAD_CTL_PUS_47K_UP),
+ MX25_PAD_SD1_DATA3__FEC_CRS = IOMUX_PAD(0x39c, 0x1a4, 0x10, 0x508, 2, NO_PAD_CTRL),
+ MX25_PAD_SD1_DATA3__GPIO_2_28 = IOMUX_PAD(0x39c, 0x1a4, 0x15, 0, 0, NO_PAD_CTRL),
+
+ MX25_PAD_KPP_ROW0__KPP_ROW0 = IOMUX_PAD(0x3a0, 0x1a8, 0x10, 0, 0, MX25_KPP_ROW_PAD_CTRL),
+ MX25_PAD_KPP_ROW0__GPIO_2_29 = IOMUX_PAD(0x3a0, 0x1a8, 0x15, 0, 0, NO_PAD_CTRL),
+
+ MX25_PAD_KPP_ROW1__KPP_ROW1 = IOMUX_PAD(0x3a4, 0x1ac, 0x10, 0, 0, MX25_KPP_ROW_PAD_CTRL),
+ MX25_PAD_KPP_ROW1__GPIO_2_30 = IOMUX_PAD(0x3a4, 0x1ac, 0x15, 0, 0, NO_PAD_CTRL),
+
+ MX25_PAD_KPP_ROW2__KPP_ROW2 = IOMUX_PAD(0x3a8, 0x1b0, 0x10, 0, 0, MX25_KPP_ROW_PAD_CTRL),
+ MX25_PAD_KPP_ROW2__CSI_D0 = IOMUX_PAD(0x3a8, 0x1b0, 0x13, 0x488, 2, NO_PAD_CTRL),
+ MX25_PAD_KPP_ROW2__GPIO_2_31 = IOMUX_PAD(0x3a8, 0x1b0, 0x15, 0, 0, NO_PAD_CTRL),
+
+ MX25_PAD_KPP_ROW3__KPP_ROW3 = IOMUX_PAD(0x3ac, 0x1b4, 0x10, 0, 0, MX25_KPP_ROW_PAD_CTRL),
+ MX25_PAD_KPP_ROW3__CSI_LD1 = IOMUX_PAD(0x3ac, 0x1b4, 0x13, 0x48c, 2, NO_PAD_CTRL),
+ MX25_PAD_KPP_ROW3__GPIO_3_0 = IOMUX_PAD(0x3ac, 0x1b4, 0x15, 0, 0, NO_PAD_CTRL),
+
+ MX25_PAD_KPP_COL0__KPP_COL0 = IOMUX_PAD(0x3b0, 0x1b8, 0x10, 0, 0, MX25_KPP_COL_PAD_CTRL),
+ MX25_PAD_KPP_COL0__UART4_RXD_MUX = IOMUX_PAD(0x3b0, 0x1b8, 0x11, 0x570, 1, NO_PAD_CTRL),
+ MX25_PAD_KPP_COL0__AUD5_TXD = IOMUX_PAD(0x3b0, 0x1b8, 0x12, 0, 0, PAD_CTL_PUS_100K_UP),
+ MX25_PAD_KPP_COL0__GPIO_3_1 = IOMUX_PAD(0x3b0, 0x1b8, 0x15, 0, 0, NO_PAD_CTRL),
+
+ MX25_PAD_KPP_COL1__KPP_COL1 = IOMUX_PAD(0x3b4, 0x1bc, 0x10, 0, 0, MX25_KPP_COL_PAD_CTRL),
+ MX25_PAD_KPP_COL1__UART4_TXD_MUX = IOMUX_PAD(0x3b4, 0x1bc, 0x11, 0, 0, NO_PAD_CTRL),
+ MX25_PAD_KPP_COL1__AUD5_RXD = IOMUX_PAD(0x3b4, 0x1bc, 0x12, 0, 0, PAD_CTL_PUS_100K_UP),
+ MX25_PAD_KPP_COL1__GPIO_3_2 = IOMUX_PAD(0x3b4, 0x1bc, 0x15, 0, 0, NO_PAD_CTRL),
+
+ MX25_PAD_KPP_COL2__KPP_COL2 = IOMUX_PAD(0x3b8, 0x1c0, 0x10, 0, 0, MX25_KPP_COL_PAD_CTRL),
+ MX25_PAD_KPP_COL2__UART4_RTS = IOMUX_PAD(0x3b8, 0x1c0, 0x11, 0, 0, NO_PAD_CTRL),
+ MX25_PAD_KPP_COL2__AUD5_TXC = IOMUX_PAD(0x3b8, 0x1c0, 0x12, 0, 0, PAD_CTL_PUS_100K_UP),
+ MX25_PAD_KPP_COL2__GPIO_3_3 = IOMUX_PAD(0x3b8, 0x1c0, 0x15, 0, 0, NO_PAD_CTRL),
+
+ MX25_PAD_KPP_COL3__KPP_COL3 = IOMUX_PAD(0x3bc, 0x1c4, 0x10, 0, 0, MX25_KPP_COL_PAD_CTRL),
+ MX25_PAD_KPP_COL3__UART4_CTS = IOMUX_PAD(0x3bc, 0x1c4, 0x11, 0, 0, NO_PAD_CTRL),
+ MX25_PAD_KPP_COL3__AUD5_TXFS = IOMUX_PAD(0x3bc, 0x1c4, 0x12, 0, 0, PAD_CTL_PUS_100K_UP),
+ MX25_PAD_KPP_COL3__GPIO_3_4 = IOMUX_PAD(0x3bc, 0x1c4, 0x15, 0, 0, NO_PAD_CTRL),
+
+ MX25_PAD_FEC_MDC__FEC_MDC = IOMUX_PAD(0x3c0, 0x1c8, 0x10, 0, 0, NO_PAD_CTRL),
+ MX25_PAD_FEC_MDC__AUD4_TXD = IOMUX_PAD(0x3c0, 0x1c8, 0x12, 0x464, 1, NO_PAD_CTRL),
+ MX25_PAD_FEC_MDC__GPIO_3_5 = IOMUX_PAD(0x3c0, 0x1c8, 0x15, 0, 0, NO_PAD_CTRL),
+
+ MX25_PAD_FEC_MDIO__FEC_MDIO = IOMUX_PAD(0x3c4, 0x1cc, 0x10, 0, 0, PAD_CTL_HYS | PAD_CTL_PUS_22K_UP),
+ MX25_PAD_FEC_MDIO__AUD4_RXD = IOMUX_PAD(0x3c4, 0x1cc, 0x12, 0x460, 1, NO_PAD_CTRL),
+ MX25_PAD_FEC_MDIO__GPIO_3_6 = IOMUX_PAD(0x3c4, 0x1cc, 0x15, 0, 0, NO_PAD_CTRL),
+
+ MX25_PAD_FEC_TDATA0__FEC_TDATA0 = IOMUX_PAD(0x3c8, 0x1d0, 0x10, 0, 0, NO_PAD_CTRL),
+ MX25_PAD_FEC_TDATA0__GPIO_3_7 = IOMUX_PAD(0x3c8, 0x1d0, 0x15, 0, 0, NO_PAD_CTRL),
+
+ MX25_PAD_FEC_TDATA1__FEC_TDATA1 = IOMUX_PAD(0x3cc, 0x1d4, 0x10, 0, 0, NO_PAD_CTRL),
+ MX25_PAD_FEC_TDATA1__AUD4_TXFS = IOMUX_PAD(0x3cc, 0x1d4, 0x12, 0x474, 1, NO_PAD_CTRL),
+ MX25_PAD_FEC_TDATA1__GPIO_3_8 = IOMUX_PAD(0x3cc, 0x1d4, 0x15, 0, 0, NO_PAD_CTRL),
+
+ MX25_PAD_FEC_TX_EN__FEC_TX_EN = IOMUX_PAD(0x3d0, 0x1d8, 0x10, 0, 0, NO_PAD_CTRL),
+ MX25_PAD_FEC_TX_EN__GPIO_3_9 = IOMUX_PAD(0x3d0, 0x1d8, 0x15, 0, 0, NO_PAD_CTRL),
+
+ MX25_PAD_FEC_RDATA0__FEC_RDATA0 = IOMUX_PAD(0x3d4, 0x1dc, 0x10, 0, 0, PAD_CTL_HYS | PAD_CTL_PUS_100K_DOWN),
+ MX25_PAD_FEC_RDATA0__GPIO_3_10 = IOMUX_PAD(0x3d4, 0x1dc, 0x15, 0, 0, NO_PAD_CTRL),
+
+ MX25_PAD_FEC_RDATA1__FEC_RDATA1 = IOMUX_PAD(0x3d8, 0x1e0, 0x10, 0, 0, PAD_CTL_HYS | PAD_CTL_PUS_100K_DOWN),
+ MX25_PAD_FEC_RDATA1__GPIO_3_11 = IOMUX_PAD(0x3d8, 0x1e0, 0x15, 0, 0, NO_PAD_CTRL),
+
+ MX25_PAD_FEC_RX_DV__FEC_RX_DV = IOMUX_PAD(0x3dc, 0x1e4, 0x10, 0, 0, PAD_CTL_HYS | PAD_CTL_PUS_100K_DOWN),
+ MX25_PAD_FEC_RX_DV__CAN2_RX = IOMUX_PAD(0x3dc, 0x1e4, 0x14, 0x484, 0, PAD_CTL_PUS_22K_UP),
+ MX25_PAD_FEC_RX_DV__GPIO_3_12 = IOMUX_PAD(0x3dc, 0x1e4, 0x15, 0, 0, NO_PAD_CTRL),
+
+ MX25_PAD_FEC_TX_CLK__FEC_TX_CLK = IOMUX_PAD(0x3e0, 0x1e8, 0x10, 0, 0, PAD_CTL_HYS | PAD_CTL_PUS_100K_DOWN),
+ MX25_PAD_FEC_TX_CLK__GPIO_3_13 = IOMUX_PAD(0x3e0, 0x1e8, 0x15, 0, 0, NO_PAD_CTRL),
+
+ MX25_PAD_RTCK__RTCK = IOMUX_PAD(0x3e4, 0x1ec, 0x10, 0, 0, NO_PAD_CTRL),
+ MX25_PAD_RTCK__OWIRE = IOMUX_PAD(0x3e4, 0x1ec, 0x11, 0, 0, NO_PAD_CTRL),
+ MX25_PAD_RTCK__GPIO_3_14 = IOMUX_PAD(0x3e4, 0x1ec, 0x15, 0, 0, NO_PAD_CTRL),
+
+ MX25_PAD_DE_B__DE_B = IOMUX_PAD(0x3ec, 0x1f0, 0x10, 0, 0, NO_PAD_CTRL),
+ MX25_PAD_DE_B__GPIO_2_20 = IOMUX_PAD(0x3ec, 0x1f0, 0x15, 0, 0, NO_PAD_CTRL),
+
+ MX25_PAD_TDO__TDO = IOMUX_PAD(0x3e8, 0x000, 0x00, 0, 0, NO_PAD_CTRL),
+
+ MX25_PAD_GPIO_A__GPIO_A = IOMUX_PAD(0x3f0, 0x1f4, 0x10, 0, 0, NO_PAD_CTRL),
+ MX25_PAD_GPIO_A__CAN1_TX = IOMUX_PAD(0x3f0, 0x1f4, 0x16, 0, 0, PAD_CTL_PUS_22K_UP),
+ MX25_PAD_GPIO_A__USBOTG_PWR = IOMUX_PAD(0x3f0, 0x1f4, 0x12, 0, 0, PAD_CTL_PKE),
+
+ MX25_PAD_GPIO_B__GPIO_B = IOMUX_PAD(0x3f4, 0x1f8, 0x10, 0, 0, NO_PAD_CTRL),
+ MX25_PAD_GPIO_B__CAN1_RX = IOMUX_PAD(0x3f4, 0x1f8, 0x16, 0x480, 1, PAD_CTL_PUS_22K_UP),
+ MX25_PAD_GPIO_B__USBOTG_OC = IOMUX_PAD(0x3f4, 0x1f8, 0x12, 0x57c, 1, PAD_CTL_PUS_100K_UP),
+
+ MX25_PAD_GPIO_C__GPIO_C = IOMUX_PAD(0x3f8, 0x1fc, 0x10, 0, 0, NO_PAD_CTRL),
+ MX25_PAD_GPIO_C__CAN2_TX = IOMUX_PAD(0x3f8, 0x1fc, 0x16, 0, 0, PAD_CTL_PUS_22K_UP),
+
+ MX25_PAD_GPIO_D__GPIO_D = IOMUX_PAD(0x3fc, 0x200, 0x10, 0, 0, NO_PAD_CTRL),
+ MX25_PAD_GPIO_E__LD16 = IOMUX_PAD(0x400, 0x204, 0x02, 0, 0, PAD_CTL_SRE_FAST),
+ MX25_PAD_GPIO_D__CAN2_RX = IOMUX_PAD(0x3fc, 0x200, 0x16, 0x484, 1, PAD_CTL_PUS_22K_UP),
+
+ MX25_PAD_GPIO_E__GPIO_E = IOMUX_PAD(0x400, 0x204, 0x10, 0, 0, NO_PAD_CTRL),
+ MX25_PAD_GPIO_F__LD17 = IOMUX_PAD(0x404, 0x208, 0x02, 0, 0, PAD_CTL_SRE_FAST),
+ MX25_PAD_GPIO_E__I2C3_CLK = IOMUX_PAD(0x400, 0x204, 0x11, 0x524, 2, NO_PAD_CTRL),
+ MX25_PAD_GPIO_E__AUD7_TXD = IOMUX_PAD(0x400, 0x204, 0x14, 0, 0, NO_PAD_CTRL),
+
+ MX25_PAD_GPIO_F__GPIO_F = IOMUX_PAD(0x404, 0x208, 0x10, 0, 0, NO_PAD_CTRL),
+ MX25_PAD_GPIO_F__AUD7_TXC = IOMUX_PAD(0x404, 0x208, 0x14, 0, 0, NO_PAD_CTRL),
+
+ MX25_PAD_EXT_ARMCLK__EXT_ARMCLK = IOMUX_PAD(0x000, 0x20c, 0x10, 0, 0, NO_PAD_CTRL),
+ MX25_PAD_EXT_ARMCLK__GPIO_3_15 = IOMUX_PAD(0x000, 0x20c, 0x15, 0, 0, NO_PAD_CTRL),
+
+ MX25_PAD_UPLL_BYPCLK__UPLL_BYPCLK = IOMUX_PAD(0x000, 0x210, 0x10, 0, 0, NO_PAD_CTRL),
+ MX25_PAD_UPLL_BYPCLK__GPIO_3_16 = IOMUX_PAD(0x000, 0x210, 0x15, 0, 0, NO_PAD_CTRL),
+
+ MX25_PAD_VSTBY_REQ__VSTBY_REQ = IOMUX_PAD(0x408, 0x214, 0x10, 0, 0, NO_PAD_CTRL),
+ MX25_PAD_VSTBY_REQ__AUD7_TXFS = IOMUX_PAD(0x408, 0x214, 0x14, 0, 0, NO_PAD_CTRL),
+ MX25_PAD_VSTBY_REQ__GPIO_3_17 = IOMUX_PAD(0x408, 0x214, 0x15, 0, 0, NO_PAD_CTRL),
+ MX25_PAD_VSTBY_ACK__VSTBY_ACK = IOMUX_PAD(0x40c, 0x218, 0x10, 0, 0, NO_PAD_CTRL),
+ MX25_PAD_VSTBY_ACK__GPIO_3_18 = IOMUX_PAD(0x40c, 0x218, 0x15, 0, 0, NO_PAD_CTRL),
+
+ MX25_PAD_POWER_FAIL__POWER_FAIL = IOMUX_PAD(0x410, 0x21c, 0x10, 0, 0, NO_PAD_CTRL),
+ MX25_PAD_POWER_FAIL__AUD7_RXD = IOMUX_PAD(0x410, 0x21c, 0x14, 0x478, 1, NO_PAD_CTRL),
+ MX25_PAD_POWER_FAIL__GPIO_3_19 = IOMUX_PAD(0x410, 0x21c, 0x15, 0, 0, NO_PAD_CTRL),
+
+ MX25_PAD_CLKO__CLKO = IOMUX_PAD(0x414, 0x220, 0x10, 0, 0, NO_PAD_CTRL),
+ MX25_PAD_CLKO__GPIO_2_21 = IOMUX_PAD(0x414, 0x220, 0x15, 0, 0, NO_PAD_CTRL),
+
+ MX25_PAD_BOOT_MODE0__BOOT_MODE0 = IOMUX_PAD(0x000, 0x224, 0x00, 0, 0, NO_PAD_CTRL),
+ MX25_PAD_BOOT_MODE0__GPIO_4_30 = IOMUX_PAD(0x000, 0x224, 0x05, 0, 0, NO_PAD_CTRL),
+ MX25_PAD_BOOT_MODE1__BOOT_MODE1 = IOMUX_PAD(0x000, 0x228, 0x00, 0, 0, NO_PAD_CTRL),
+ MX25_PAD_BOOT_MODE1__GPIO_4_31 = IOMUX_PAD(0x000, 0x228, 0x05, 0, 0, NO_PAD_CTRL),
+
+ MX25_PAD_CTL_GRP_DVS_MISC = IOMUX_PAD(0x418, 0x000, 0, 0, 0, NO_PAD_CTRL),
+ MX25_PAD_CTL_GRP_DSE_FEC = IOMUX_PAD(0x41c, 0x000, 0, 0, 0, NO_PAD_CTRL),
+ MX25_PAD_CTL_GRP_DVS_JTAG = IOMUX_PAD(0x420, 0x000, 0, 0, 0, NO_PAD_CTRL),
+ MX25_PAD_CTL_GRP_DSE_NFC = IOMUX_PAD(0x424, 0x000, 0, 0, 0, NO_PAD_CTRL),
+ MX25_PAD_CTL_GRP_DSE_CSI = IOMUX_PAD(0x428, 0x000, 0, 0, 0, NO_PAD_CTRL),
+ MX25_PAD_CTL_GRP_DSE_WEIM = IOMUX_PAD(0x42c, 0x000, 0, 0, 0, NO_PAD_CTRL),
+ MX25_PAD_CTL_GRP_DSE_DDR = IOMUX_PAD(0x430, 0x000, 0, 0, 0, NO_PAD_CTRL),
+ MX25_PAD_CTL_GRP_DVS_CRM = IOMUX_PAD(0x434, 0x000, 0, 0, 0, NO_PAD_CTRL),
+ MX25_PAD_CTL_GRP_DSE_KPP = IOMUX_PAD(0x438, 0x000, 0, 0, 0, NO_PAD_CTRL),
+ MX25_PAD_CTL_GRP_DSE_SDHC1 = IOMUX_PAD(0x43c, 0x000, 0, 0, 0, NO_PAD_CTRL),
+ MX25_PAD_CTL_GRP_DSE_LCD = IOMUX_PAD(0x440, 0x000, 0, 0, 0, NO_PAD_CTRL),
+ MX25_PAD_CTL_GRP_DSE_UART = IOMUX_PAD(0x444, 0x000, 0, 0, 0, NO_PAD_CTRL),
+ MX25_PAD_CTL_GRP_DVS_NFC = IOMUX_PAD(0x448, 0x000, 0, 0, 0, NO_PAD_CTRL),
+ MX25_PAD_CTL_GRP_DVS_CSI = IOMUX_PAD(0x44c, 0x000, 0, 0, 0, NO_PAD_CTRL),
+ MX25_PAD_CTL_GRP_DSE_CSPI1 = IOMUX_PAD(0x450, 0x000, 0, 0, 0, NO_PAD_CTRL),
+ MX25_PAD_CTL_GRP_DDRTYPE = IOMUX_PAD(0x454, 0x000, 0, 0, 0, NO_PAD_CTRL),
+ MX25_PAD_CTL_GRP_DVS_SDHC1 = IOMUX_PAD(0x458, 0x000, 0, 0, 0, NO_PAD_CTRL),
+ MX25_PAD_CTL_GRP_DVS_LCD = IOMUX_PAD(0x45c, 0x000, 0, 0, 0, NO_PAD_CTRL),
+};
+
+#endif /* __IOMUX_MX25_H__ */
--
1.7.10.4
1
5

26 Apr '13
Hi,
On Tue, Apr 23, 2013 at 3:11 PM, Jagan Teki <jagannadh.teki(a)gmail.com> wrote:
> Hi Simon,
>
> On Wed, Apr 24, 2013 at 3:25 AM, Jagan Teki <jagannadh.teki(a)gmail.com> wrote:
>> Hi Simon,
>>
>> On Wed, Apr 24, 2013 at 3:10 AM, Simon Glass <sjg(a)chromium.org> wrote:
>>> Hi Jagan,
>>>
>>> On Tue, Apr 23, 2013 at 2:31 PM, Jagan Teki <jagannadh.teki(a)gmail.com> wrote:
>>>> Hi Simon,
>>>>
>>>> On Wed, Apr 24, 2013 at 2:48 AM, Simon Glass <sjg(a)chromium.org> wrote:
>>>>> Hi Jagan,
>>>>>
>>>>> On Tue, Apr 23, 2013 at 2:15 PM, Jagan Teki <jagannadh.teki(a)gmail.com> wrote:
>>>>>> Hi Simon,
>>>>>>
>>>>>> On Wed, Apr 24, 2013 at 2:43 AM, Simon Glass <sjg(a)chromium.org> wrote:
>>>>>>> Hi Jagan,
>>>>>>>
>>>>>>> On Tue, Apr 23, 2013 at 2:01 PM, Jagan Teki <jagannadh.teki(a)gmail.com> wrote:
>>>>>>>> Hi Simon,
>>>>>>>>
>>>>>>>> On Wed, Apr 24, 2013 at 2:20 AM, Simon Glass <sjg(a)chromium.org> wrote:
>>>>>>>>> Hi Jagan,
>>>>>>>>>
>>>>>>>>> On Tue, Apr 23, 2013 at 1:44 PM, Jagan Teki <jagannadh.teki(a)gmail.com> wrote:
>>>>>>>>>> Hi Simon,
>>>>>>>>>>
>>>>>>>>>> On Mon, Mar 11, 2013 at 9:38 PM, Simon Glass <sjg(a)chromium.org> wrote:
>>>>>>>>>>> Some SPI flash controllers (e.g. Intel ICH) have a limit on the number of
>>>>>>>>>>> bytes that can be in a write transaction. Support this by breaking the
>>>>>>>>>>> writes into multiple transactions.
>>>>>>>>>>>
>>>>>>>>>>> Signed-off-by: Simon Glass <sjg(a)chromium.org>
>>>>>>>>>>> ---
>>>>>>>>>>> Changes in v2: None
>>>>>>>>>>>
>>>>>>>>>>> drivers/mtd/spi/spi_flash.c | 10 ++++++++--
>>>>>>>>>>> 1 file changed, 8 insertions(+), 2 deletions(-)
>>>>>>>>>>>
>>>>>>>>>>> diff --git a/drivers/mtd/spi/spi_flash.c b/drivers/mtd/spi/spi_flash.c
>>>>>>>>>>> index 17f3d3c..b82011d 100644
>>>>>>>>>>> --- a/drivers/mtd/spi/spi_flash.c
>>>>>>>>>>> +++ b/drivers/mtd/spi/spi_flash.c
>>>>>>>>>>> @@ -87,6 +87,9 @@ int spi_flash_cmd_write_multi(struct spi_flash *flash, u32 offset,
>>>>>>>>>>> for (actual = 0; actual < len; actual += chunk_len) {
>>>>>>>>>>> chunk_len = min(len - actual, page_size - byte_addr);
>>>>>>>>>>>
>>>>>>>>>>> + if (flash->spi->max_write_size)
>>>>>>>>>>> + chunk_len = min(chunk_len, flash->spi->max_write_size);
>>>>>>>>>>> +
>>>>>>>>>>> cmd[1] = page_addr >> 8;
>>>>>>>>>>> cmd[2] = page_addr;
>>>>>>>>>>> cmd[3] = byte_addr;
>>>>>>>>>>> @@ -111,8 +114,11 @@ int spi_flash_cmd_write_multi(struct spi_flash *flash, u32 offset,
>>>>>>>>>>> if (ret)
>>>>>>>>>>> break;
>>>>>>>>>>>
>>>>>>>>>>> - page_addr++;
>>>>>>>>>>> - byte_addr = 0;
>>>>>>>>>>> + byte_addr += chunk_len;
>>>>>>>>>>> + if (byte_addr == page_size) {
>>>>>>>>>>> + page_addr++;
>>>>>>>>>>> + byte_addr = 0;
>>>>>>>>>>> + }
>>>>>>>>>>
>>>>>>>>>> Does this change required to handle < page_size writes, means if the
>>>>>>>>>> user is giving an offset other than
>>>>>>>>>> multiples of page_sizes?
>>>>>>>>>
>>>>>>>>> I'm not quite sure what you are saying, but let me try to response.
>>>>>>>>>
>>>>>>>>> I believe what should happen is that byte_addr should become aligned
>>>>>>>>> to the page_size after the first transfer, and from then on it should
>>>>>>>>> start at 0 for each page.
>>>>>>>>>
>>>>>>>>> Are you seeing a problem?
>>>>>>>>
>>>>>>>> My question,what if this change doesn't have.?
>>>>>>>> Can't I able to write data starts from unaligned page_sizes?
>>>>>>>
>>>>>>> It should work fine - I did in fact find a problem in the driver in
>>>>>>> this case, which I fixed. Let me know if you see any problem.
>>>>>>
>>>>>> Means this change is for proper handling of write data starts from
>>>>>> unaligned page_sizes, is it?
>>>>>
>>>>> Not really - it was designed to handle the case where the driver
>>>>> cannot write a whole page at once. The Intel ICH peripheral has this
>>>>> problem.
>>>>>
>>>>> I believe that writing starting from unaligned page sizes worked OK
>>>>> before this change.
>>>>
>>>> Thanks.
>>>>
>>>> But I am some how confusing instead of this change may be you may
>>>> place the existing code as it is
>>>> page_addr++;
>>>> byte_addr = 0;
>>>> prior to above may be you can place intel ICH per hack as other will
>>>> do whole page at once, i may be wrong.
>>>
>>> The old code assumed that it could skip to the start of the next page
>>> after each write. The new code skips forward by chunk_len, which
>>> generally takes as to the start of the next page, but not always (e.g.
>>> with Intel ICH).
>>>
>>> Yes, AFAIK every other SPI driver can still do a whole page at a time,
>>> with or without this patch.
>>
>> Thats what if the user is giving an unaligned page size suppose 0x80
>> with 512 bytes (if the page_size=256)
>> sf write 0x100 0x80 0x200
>> the loop will goes 2 non page_sizes and 1 pages_size like this
>> iteration 1--- 128
>> iteration 2-- 256
>> iteration 3-- 128
>
> I was tested the old and new code w.r.t this unaligned page_size as a start
> the result is same
> uboot> sf write 0x100 0x80 0x200
> actual = 0.....chunk_len = 128
> actual = 128.....chunk_len = 256
> actual = 384.....chunk_len = 128
> SF: program success 512 bytes @ 0x80
>
> Means the old and new code does the same thing, but still i couldn't understand.
> What exactly this change is for, if it is specific to intel flash what
> is state in above condition.
Yes it is for the Intel SPI controller which has a strange limitation
that it can only write 64 bytes at a time.
Regards,
Simon
>
> Thanks,
> Jagan.
>
>>
>> May be the new code handle this situation as earlier may not have.?
2
8