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 2017
- 194 participants
- 746 discussions

13 Apr '17
Add NAND secure boot target for ls1043ardb.
- Change the u-boot size defined by a macro for copying the main
U-Boot by SPL to also include the u-boot Secure Boot header size as
header is appended to u-boot image. So header will also be copied from SD to DDR.
- MACRO for CONFIG_BOOTSCRIPT_COPY_RAM is enabled to copy Bootscript from NAND to
DDR. Offsets for Bootscript on NAND and DDR have been also defined.
Signed-off-by: Vinitha Pillai <vinitha.pillai(a)nxp.com>
Signed-off-by: Sumit Garg <sumit.garg(a)nxp.com>
Signed-off-by: Ruchika Gupta <ruchika.gupta(a)nxp.com>
---
Changes in v3:
Removed changes to ls1043ardb.c
Changes in v2:
- Rebased this patch to the latest dependent patch-set.
Dependent patch set:
SECURE boot target addition for NOR on LS1043, LS1046
https://patchwork.ozlabs.org/patch/742548/
https://patchwork.ozlabs.org/patch/742552/
https://patchwork.ozlabs.org/patch/742549/
https://patchwork.ozlabs.org/patch/742551/
https://patchwork.ozlabs.org/patch/742550/
https://patchwork.ozlabs.org/patch/742553/
https://patchwork.ozlabs.org/patch/742554/
and
SPL size reduction patches
https://patchwork.ozlabs.org/patch/744755/
https://patchwork.ozlabs.org/patch/744756/
arch/arm/include/asm/fsl_secure_boot.h | 7 +++-
configs/ls1043ardb_nand_SECURE_BOOT_defconfig | 57 +++++++++++++++++++++++++++
include/config_fsl_chain_trust.h | 9 +++--
include/configs/ls1043a_common.h | 18 ++++++++-
include/configs/ls1043ardb.h | 2 +-
5 files changed, 86 insertions(+), 7 deletions(-)
create mode 100644 configs/ls1043ardb_nand_SECURE_BOOT_defconfig
diff --git a/arch/arm/include/asm/fsl_secure_boot.h b/arch/arm/include/asm/fsl_secure_boot.h
index 56a6ba0..9ca7abe 100644
--- a/arch/arm/include/asm/fsl_secure_boot.h
+++ b/arch/arm/include/asm/fsl_secure_boot.h
@@ -70,7 +70,7 @@
/* Copying Bootscript and Header to DDR from NOR for LS2 and for rest, from
* Non-XIP Memory (Nand/SD)*/
#if defined(CONFIG_SYS_RAMBOOT) || defined(CONFIG_FSL_LSCH3) || \
- defined(CONFIG_SD_BOOT)
+ defined(CONFIG_SD_BOOT) || defined(CONFIG_NAND_BOOT)
#define CONFIG_BOOTSCRIPT_COPY_RAM
#endif
/* The address needs to be modified according to NOR, NAND, SD and
@@ -96,6 +96,11 @@
#define CONFIG_BS_ADDR_DEVICE 0x00000940
#define CONFIG_BS_HDR_SIZE 0x00000010
#define CONFIG_BS_SIZE 0x00000008
+#elif defined(CONFIG_NAND_BOOT)
+#define CONFIG_BS_HDR_ADDR_DEVICE 0x00800000
+#define CONFIG_BS_ADDR_DEVICE 0x00802000
+#define CONFIG_BS_HDR_SIZE 0x00002000
+#define CONFIG_BS_SIZE 0x00001000
#elif defined(CONFIG_QSPI_BOOT)
#ifdef CONFIG_ARCH_LS1046A
#define CONFIG_BS_HDR_ADDR_DEVICE 0x40780000
diff --git a/configs/ls1043ardb_nand_SECURE_BOOT_defconfig b/configs/ls1043ardb_nand_SECURE_BOOT_defconfig
new file mode 100644
index 0000000..66c89fa
--- /dev/null
+++ b/configs/ls1043ardb_nand_SECURE_BOOT_defconfig
@@ -0,0 +1,57 @@
+CONFIG_ARM=y
+CONFIG_TARGET_LS1043ARDB=y
+CONFIG_SPL_LIBCOMMON_SUPPORT=y
+CONFIG_SPL_LIBGENERIC_SUPPORT=y
+CONFIG_SPL_NAND_SUPPORT=y
+CONFIG_SPL_SERIAL_SUPPORT=y
+CONFIG_SPL_ENV_SUPPORT=y
+CONFIG_SPL_DRIVERS_MISC_SUPPORT=y
+CONFIG_SPL_WATCHDOG_SUPPORT=y
+CONFIG_DEFAULT_DEVICE_TREE="fsl-ls1043a-rdb"
+CONFIG_FIT=y
+CONFIG_FIT_VERBOSE=y
+CONFIG_OF_BOARD_SETUP=y
+CONFIG_SYS_EXTRA_OPTIONS="RAMBOOT_PBL,SPL_FSL_PBL,NAND_BOOT"
+CONFIG_NAND_BOOT=y
+CONFIG_SECURE_BOOT=y
+CONFIG_BOOTDELAY=10
+CONFIG_SPL=y
+CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR=y
+CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR=0xf0
+CONFIG_SPL_MPC8XXX_INIT_DDR_SUPPORT=y
+CONFIG_HUSH_PARSER=y
+CONFIG_CMD_GPT=y
+CONFIG_CMD_MMC=y
+CONFIG_CMD_SF=y
+CONFIG_CMD_I2C=y
+CONFIG_CMD_USB=y
+CONFIG_CMD_DHCP=y
+CONFIG_CMD_PXE=y
+CONFIG_CMD_MII=y
+CONFIG_CMD_PING=y
+CONFIG_CMD_CACHE=y
+CONFIG_CMD_EXT2=y
+CONFIG_CMD_FAT=y
+# CONFIG_SPL_EFI_PARTITION is not set
+CONFIG_OF_CONTROL=y
+CONFIG_DM=y
+CONFIG_SPL_DM=y
+CONFIG_MTD_NOR_FLASH=y
+CONFIG_SPI_FLASH=y
+CONFIG_NETDEVICES=y
+CONFIG_E1000=y
+CONFIG_PCI=y
+CONFIG_DM_PCI=y
+CONFIG_DM_PCI_COMPAT=y
+CONFIG_PCIE_LAYERSCAPE=y
+CONFIG_SYS_NS16550=y
+CONFIG_DM_SPI=y
+CONFIG_USB=y
+CONFIG_DM_USB=y
+CONFIG_USB_XHCI_HCD=y
+CONFIG_USB_XHCI_DWC3=y
+CONFIG_USB_STORAGE=y
+CONFIG_RSA=y
+CONFIG_SPL_RSA=y
+CONFIG_SPL_CRYPTO_SUPPORT=y
+CONFIG_SPL_HASH_SUPPORT=y
diff --git a/include/config_fsl_chain_trust.h b/include/config_fsl_chain_trust.h
index eb45e98..40d323e 100644
--- a/include/config_fsl_chain_trust.h
+++ b/include/config_fsl_chain_trust.h
@@ -81,17 +81,18 @@
"setenv bs_size " __stringify(CONFIG_BS_SIZE)";"
/* For secure boot flow, default environment used will be used */
-#if defined(CONFIG_SYS_RAMBOOT)
-#if defined(CONFIG_RAMBOOT_NAND)
+#if defined(CONFIG_SYS_RAMBOOT) || defined(CONFIG_NAND_BOOT) || \
+ defined(CONFIG_SD_BOOT)
+#if defined(CONFIG_RAMBOOT_NAND) || defined(CONFIG_NAND_BOOT)
#define CONFIG_BS_COPY_CMD \
"nand read $bs_hdr_ram $bs_hdr_device $bs_hdr_size ;" \
"nand read $bs_ram $bs_device $bs_size ;"
-#endif /* CONFIG_RAMBOOT_NAND */
#elif defined(CONFIG_SD_BOOT)
#define CONFIG_BS_COPY_CMD \
"mmc read $bs_hdr_ram $bs_hdr_device $bs_hdr_size ;" \
"mmc read $bs_ram $bs_device $bs_size ;"
-#else /* CONFIG_SD_BOOT */
+#endif
+#else
#define CONFIG_BS_COPY_CMD \
"cp.b $bs_hdr_device $bs_hdr_ram $bs_hdr_size ;" \
"cp.b $bs_device $bs_ram $bs_size ;"
diff --git a/include/configs/ls1043a_common.h b/include/configs/ls1043a_common.h
index b71456e..202372d 100644
--- a/include/configs/ls1043a_common.h
+++ b/include/configs/ls1043a_common.h
@@ -105,7 +105,23 @@
#define CONFIG_SPL_BSS_START_ADDR 0x80100000
#define CONFIG_SYS_SPL_MALLOC_SIZE 0x100000
#define CONFIG_SPL_BSS_MAX_SIZE 0x80000
-#define CONFIG_SYS_MONITOR_LEN 0xa0000
+
+#ifdef CONFIG_SECURE_BOOT
+#define CONFIG_U_BOOT_HDR_SIZE (16 << 10)
+#endif /* ifdef CONFIG_SECURE_BOOT */
+
+#ifdef CONFIG_U_BOOT_HDR_SIZE
+/*
+ * HDR would be appended at end of image and copied to DDR along
+ * with U-Boot image. Here u-boot max. size is 512K. So if binary
+ * size increases then increase this size in case of secure boot as
+ * it uses raw u-boot image instead of fit image.
+ */
+#define CONFIG_SYS_MONITOR_LEN (0x100000 + CONFIG_U_BOOT_HDR_SIZE)
+#else
+#define CONFIG_SYS_MONITOR_LEN 0x100000
+#endif /* ifdef CONFIG_U_BOOT_HDR_SIZE */
+
#endif
/* IFC */
diff --git a/include/configs/ls1043ardb.h b/include/configs/ls1043ardb.h
index 7ef5c25..6455393 100644
--- a/include/configs/ls1043ardb.h
+++ b/include/configs/ls1043ardb.h
@@ -149,7 +149,7 @@
#ifdef CONFIG_NAND_BOOT
#define CONFIG_SPL_PAD_TO 0x20000 /* block aligned */
#define CONFIG_SYS_NAND_U_BOOT_OFFS CONFIG_SPL_PAD_TO
-#define CONFIG_SYS_NAND_U_BOOT_SIZE (640 << 10)
+#define CONFIG_SYS_NAND_U_BOOT_SIZE (1024 << 10)
#endif
/*
--
1.9.1
2
4
Add Support of devices that follow the NVM Express standard
basic functions:
nvme init/scan
nvme info - show the basic information of device
nvme Read/Write
driver model:
Use block device(CONFIG_BLK)'s structure to support nvme's DM.
Use UCLASS_PCI as a parent uclass.
The driver code heavily copy from the NVMe driver code in Linux Kernel.
Signed-off-by: Zhikang Zhang <zhikang.zhang(a)nxp.com>
Signed-off-by: Wenbin Song <wenbin.song(a)nxp.com>
---
common/Makefile | 1 +
common/board_r.c | 13 +
common/nvme.c | 127 ++++++
doc/README.nvme | 17 +
drivers/block/Kconfig | 16 +
drivers/block/Makefile | 1 +
drivers/block/blk-uclass.c | 2 +
drivers/block/nvme.c | 1048 ++++++++++++++++++++++++++++++++++++++++++++
drivers/block/nvme.h | 114 +++++
drivers/block/nvme_uapi.h | 570 ++++++++++++++++++++++++
include/blk.h | 1 +
include/nvme.h | 50 +++
12 files changed, 1960 insertions(+)
create mode 100644 common/nvme.c
create mode 100644 doc/README.nvme
create mode 100644 drivers/block/nvme.c
create mode 100644 drivers/block/nvme.h
create mode 100644 drivers/block/nvme_uapi.h
create mode 100644 include/nvme.h
diff --git a/common/Makefile b/common/Makefile
index ecc23e6..70c539b 100644
--- a/common/Makefile
+++ b/common/Makefile
@@ -81,6 +81,7 @@ obj-$(CONFIG_LCD_DT_SIMPLEFB) += lcd_simplefb.o
obj-$(CONFIG_LYNXKDI) += lynxkdi.o
obj-$(CONFIG_MENU) += menu.o
obj-$(CONFIG_CMD_SATA) += sata.o
+obj-$(CONFIG_NVME) += nvme.o
obj-$(CONFIG_SCSI) += scsi.o
obj-$(CONFIG_UPDATE_TFTP) += update.o
obj-$(CONFIG_DFU_TFTP) += update.o
diff --git a/common/board_r.c b/common/board_r.c
index 48fa4ee..843f4e5 100644
--- a/common/board_r.c
+++ b/common/board_r.c
@@ -49,6 +49,7 @@
#include <timer.h>
#include <trace.h>
#include <watchdog.h>
+#include <nvme.h>
#ifdef CONFIG_CMD_AMBAPP
#include <ambapp.h>
#endif
@@ -458,6 +459,15 @@ static int initr_dataflash(void)
}
#endif
+#ifdef CONFIG_NVME
+static int initr_nvme(void)
+{
+ puts("NVMe: ");
+ nvme_initialize();
+ return 0;
+}
+#endif
+
/*
* Tell if it's OK to load the environment early in boot.
*
@@ -942,6 +952,9 @@ init_fnc_t init_sequence_r[] = {
#if defined(CONFIG_SPARC)
prom_init,
#endif
+#ifdef CONFIG_NVME
+ initr_nvme,
+#endif
run_main_loop,
};
diff --git a/common/nvme.c b/common/nvme.c
new file mode 100644
index 0000000..ed3250f
--- /dev/null
+++ b/common/nvme.c
@@ -0,0 +1,127 @@
+/*
+ * Copyright (C) 2017 NXP Semiconductors
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <nvme.h>
+
+struct blk_desc nvme_dev_desc[CONFIG_SYS_NVME_MAX_DEVICE];
+
+struct pci_device_id nvme_supported[] = {
+ { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x0953) },
+ {}
+};
+#ifdef CONFIG_PARTITIONS
+struct blk_desc *nvme_get_dev(int dev)
+{
+ return (dev < CONFIG_SYS_NVME_MAX_DEVICE) ? &nvme_dev_desc[dev] : NULL;
+}
+#endif
+
+#ifdef CONFIG_BLK
+struct udevice *udev;
+static unsigned long nvme_bread(struct udevice *dev, lbaint_t start,
+ lbaint_t blkcnt, void *dst)
+{
+ return nvme_read(dev, start, blkcnt, dst);
+}
+
+static unsigned long nvme_bwrite(struct udevice *dev, lbaint_t start,
+ lbaint_t blkcnt, const void *buffer)
+{
+ return nvme_write(dev, start, blkcnt, buffer);
+}
+#else
+static unsigned long nvme_bread(struct blk_desc *block_dev, lbaint_t start,
+ lbaint_t blkcnt, void *dst)
+{
+ return nvme_read(block_dev->devnum, start, blkcnt, dst);
+}
+
+static unsigned long nvme_bwrite(struct blk_desc *block_dev, lbaint_t start,
+ lbaint_t blkcnt, const void *buffer)
+{
+ return nvme_write(block_dev->devnum, start, blkcnt, buffer);
+}
+#endif
+
+int __nvme_initialize(void)
+{
+ int rc, ret = -1;
+ int i;
+
+ for (i = 0; i < CONFIG_SYS_NVME_MAX_DEVICE; i++) {
+#ifdef CONFIG_BLK
+ rc = init_nvme(udev);
+ if (!rc)
+ rc = scan_nvme(udev);
+#else
+ rc = init_nvme(i);
+ if (!rc)
+ rc = scan_nvme(i);
+#endif
+
+ if (!rc && nvme_dev_desc[i].lba > 0) {
+ nvme_dev_desc[i].if_type = IF_TYPE_NVME;
+ nvme_dev_desc[i].devnum = i;
+ nvme_dev_desc[i].part_type = PART_TYPE_UNKNOWN;
+ nvme_dev_desc[i].type = DEV_TYPE_HARDDISK;
+#ifndef CONFIG_BLK
+ nvme_dev_desc[i].block_read = nvme_bread;
+ nvme_dev_desc[i].block_write = nvme_bwrite;
+#endif
+
+ part_init(&nvme_dev_desc[i]);
+ ret = i;
+ } else {
+ memset(&nvme_dev_desc[i], 0, sizeof(struct blk_desc));
+ }
+ printf("devnum: %d Vendor: %s Prod: %s\n",
+ i,
+ nvme_dev_desc[i].vendor,
+ nvme_dev_desc[i].product);
+ }
+ return ret;
+}
+int nvme_initialize(void) __attribute__((weak, alias("__nvme_initialize")));
+
+#ifdef CONFIG_BLK
+static void nvme_name(char *str, int cardnum)
+{
+ sprintf(str, "nvme#%u", cardnum);
+}
+
+static int nvme_bind(struct udevice *dev)
+{
+ udev = dev;
+ int num_cards = 0;
+ char name[20];
+ nvme_name(name, num_cards++);
+
+ return device_set_name(udev, name);
+}
+
+static const struct blk_ops nvme_ops = {
+ .read = nvme_bread,
+ .write = nvme_bwrite,
+};
+
+U_BOOT_DRIVER(nvme) = {
+ .name = "nvme",
+ .id = UCLASS_BLK,
+ .bind = nvme_bind,
+ .ops = &nvme_ops,
+ .priv_auto_alloc_size = sizeof(struct nvme_ns),
+};
+U_BOOT_PCI_DEVICE(nvme, nvme_supported);
+#else
+U_BOOT_LEGACY_BLK(nvme) = {
+ .if_typename = "nvme",
+ .if_type = IF_TYPE_NVME,
+ .max_devs = CONFIG_SYS_NVME_MAX_DEVICE,
+ .desc = nvme_dev_desc,
+};
+#endif
diff --git a/doc/README.nvme b/doc/README.nvme
new file mode 100644
index 0000000..892e0fb
--- /dev/null
+++ b/doc/README.nvme
@@ -0,0 +1,17 @@
+/*
+ * Copyright (C) 2017 NXP Semiconductors
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+1. NVMe Config Switches:
+
+CONFIG_NVME enables basic NVMe device support
+ NVMe is a basic device which mounted on PCIe bus,
+ so is depends on CONFIG_PCI.
+CONFIG_SYS_NVME_MAX_DEVICE configs the max num of NVMe devices
+
+2. Driver Model Support:
+
+Use block device(CONFIG_BLK)'s structure to support nvme's DM.
+Use UCLASS_PCI as a parent uclass.
diff --git a/drivers/block/Kconfig b/drivers/block/Kconfig
index 88e66e2..665d471 100644
--- a/drivers/block/Kconfig
+++ b/drivers/block/Kconfig
@@ -49,3 +49,19 @@ config SATA_CEVA
AHCI 1.3 specifications with hot-plug detect feature.
endmenu
+
+config NVME
+ bool "Support NVMe devices"
+ depends on PCI
+ help
+ This option enables supporting for all NVMe devices.
+ It supports the basic functions before using NVMe devices
+ such as "nvme init" "nvme scan" and R/W.
+ It also contains other functions to use the devices.
+
+config SYS_NVME_MAX_DEVICE
+ int "Config the Max Num of NVMe Devices"
+ depends on NVME
+ default 1
+ help
+ Set the max num of NVMe Devices.
diff --git a/drivers/block/Makefile b/drivers/block/Makefile
index a72feec..65d4bde 100644
--- a/drivers/block/Makefile
+++ b/drivers/block/Makefile
@@ -31,3 +31,4 @@ obj-$(CONFIG_SANDBOX) += sandbox.o sandbox_scsi.o sata_sandbox.o
obj-$(CONFIG_SCSI_SYM53C8XX) += sym53c8xx.o
obj-$(CONFIG_SYSTEMACE) += systemace.o
obj-$(CONFIG_BLOCK_CACHE) += blkcache.o
+obj-$(CONFIG_NVME) += nvme.o
diff --git a/drivers/block/blk-uclass.c b/drivers/block/blk-uclass.c
index 38cb938..25e3d90 100644
--- a/drivers/block/blk-uclass.c
+++ b/drivers/block/blk-uclass.c
@@ -22,6 +22,7 @@ static const char *if_typename_str[IF_TYPE_COUNT] = {
[IF_TYPE_SATA] = "sata",
[IF_TYPE_HOST] = "host",
[IF_TYPE_SYSTEMACE] = "ace",
+ [IF_TYPE_NVME] = "nvme",
};
static enum uclass_id if_type_uclass_id[IF_TYPE_COUNT] = {
@@ -34,6 +35,7 @@ static enum uclass_id if_type_uclass_id[IF_TYPE_COUNT] = {
[IF_TYPE_SD] = UCLASS_INVALID,
[IF_TYPE_SATA] = UCLASS_AHCI,
[IF_TYPE_HOST] = UCLASS_ROOT,
+ [IF_TYPE_NVME] = UCLASS_PCI,
[IF_TYPE_SYSTEMACE] = UCLASS_INVALID,
};
diff --git a/drivers/block/nvme.c b/drivers/block/nvme.c
new file mode 100644
index 0000000..2e06477
--- /dev/null
+++ b/drivers/block/nvme.c
@@ -0,0 +1,1048 @@
+/*
+ * Copyright (C) 2017 NXP Semiconductors
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <errno.h>
+#include <linux/compat.h>
+#include <dm.h>
+#include <pci.h>
+#include <memalign.h>
+#include <linux/err.h>
+#include <linux/ioport.h>
+#include <console.h>
+#include <asm/armv8/mmu.h>
+#include "nvme.h"
+
+#define NVME_Q_DEPTH 2
+#define NVME_AQ_DEPTH 2
+#define SQ_SIZE(depth) (depth * sizeof(struct nvme_command))
+#define CQ_SIZE(depth) (depth * sizeof(struct nvme_completion))
+#define ADMIN_TIMEOUT 60
+#define MAX_PRP_POOL 512
+
+static struct nvme_info nvme_info = {.maxport = 0, .idx = 0,
+ .dev_list = LIST_HEAD_INIT(nvme_info.dev_list)};
+
+/*
+ *An NVM Express queue. Each device has at least two(one for admin
+ *commands and one for I/O commands).
+ */
+struct nvme_queue {
+ struct nvme_dev *dev;
+ struct nvme_command *sq_cmds;
+ struct nvme_completion *cqes;
+ wait_queue_head_t sq_full;
+ u32 __iomem *q_db;
+ u16 q_depth;
+ s16 cq_vector;
+ u16 sq_head;
+ u16 sq_tail;
+ u16 cq_head;
+ u16 qid;
+ u8 cq_phase;
+ u8 cqe_seen;
+ unsigned long cmdid_data[];
+};
+
+static int nvme_wait_ready(struct nvme_dev *dev, u64 cap, bool enabled)
+{
+ u32 bit = enabled ? NVME_CSTS_RDY : 0;
+ while ((readl(&dev->bar->csts) & NVME_CSTS_RDY) != bit)
+ udelay(10000);
+
+ return 0;
+}
+
+static int nvme_setup_prps(struct nvme_dev *dev, u64 *prp2,
+ int total_len, u64 dma_addr)
+{
+ u32 page_size = dev->page_size;
+ int offset = dma_addr & (page_size - 1);
+ u64 *prp_pool;
+ int length = total_len;
+ int i, nprps;
+ length -= (page_size - offset);
+
+ if (length <= 0) {
+ *prp2 = 0;
+ return 0;
+ }
+
+ if (length)
+ dma_addr += (page_size - offset);
+
+ if (length <= page_size) {
+ *prp2 = dma_addr;
+ return 0;
+ }
+
+ nprps = DIV_ROUND_UP(length, page_size);
+
+ if (nprps > dev->prp_entry_num) {
+ free(dev->prp_pool);
+ dev->prp_pool = malloc(nprps << 3);
+ if (!dev->prp_pool) {
+ printf("Error: malloc prp_pool fail\n");
+ return -ENOMEM;
+ }
+ dev->prp_entry_num = nprps;
+ }
+ prp_pool = dev->prp_pool;
+ i = 0;
+ while (nprps) {
+ if (i == ((page_size >> 3) - 1)) {
+ *(prp_pool + i) = cpu_to_le64((u64)prp_pool +
+ page_size);
+ i = 0;
+ prp_pool += page_size;
+ }
+ *(prp_pool + i++) = cpu_to_le64(dma_addr);
+ dma_addr += page_size;
+ nprps--;
+ }
+ *prp2 = (u64)dev->prp_pool;
+ return 0;
+}
+
+static __le16 get_cmdid(void)
+{
+ static unsigned short cmdid;
+ return cpu_to_le16((cmdid < USHRT_MAX) ? cmdid++ : 0);
+}
+
+static u16 read_completion_status(struct nvme_queue *nvmeq, u16 index)
+{
+ u64 start = (u64)&nvmeq->cqes[index];
+ u64 stop = start + sizeof(struct nvme_completion);
+ invalidate_dcache_range(start, stop);
+ return le16_to_cpu(readw(&(nvmeq->cqes[index].status)));
+}
+
+/**
+ * nvme_submit_cmd() - Copy a command into a queue and ring the doorbell
+ * @nvmeq: The queue to use
+ * @cmd: The command to send
+ *
+ * Safe to use from interrupt context
+ */
+static int nvme_submit_cmd(struct nvme_queue *nvmeq, struct nvme_command *cmd)
+{
+ u16 tail = nvmeq->sq_tail;
+ flush_dcache_all();
+ memcpy(&nvmeq->sq_cmds[tail], cmd, sizeof(*cmd));
+ flush_dcache_range((ulong)&nvmeq->sq_cmds[tail],
+ (ulong)&nvmeq->sq_cmds[tail] + sizeof(*cmd));
+ if (++tail == nvmeq->q_depth)
+ tail = 0;
+ writel(tail, nvmeq->q_db);
+ nvmeq->sq_tail = tail;
+
+ return 0;
+}
+
+static int nvme_submit_sync_cmd(struct nvme_queue *nvmeq,
+ struct nvme_command *cmd, u32 *result, unsigned timeout)
+{
+ u16 head = nvmeq->cq_head;
+ u16 phase = nvmeq->cq_phase;
+ u16 status;
+ ulong start_time;
+ ulong timeout_us = timeout * 100000;
+
+ cmd->common.command_id = get_cmdid();
+ nvme_submit_cmd(nvmeq, cmd);
+
+ start_time = timer_get_us();
+
+ for (;;) {
+ status = read_completion_status(nvmeq, head);
+ if ((status & 0x01) == phase)
+ break;
+ if (timeout_us > 0 && (timer_get_us() - start_time)
+ >= timeout_us)
+ return -ETIMEDOUT;
+ }
+ status >>= 1;
+ if (status) {
+ printf("ERROR: status = %d, phase = %d, head = %d\n",
+ status, phase, head);
+ status = 0;
+ if (++head == nvmeq->q_depth) {
+ head = 0;
+ phase = !phase;
+ }
+ writel(head, nvmeq->q_db + nvmeq->dev->db_stride);
+ nvmeq->cq_head = head;
+ nvmeq->cq_phase = phase;
+ return -1;
+ }
+
+ if (result)
+ *result = le32_to_cpu(readl(&(nvmeq->cqes[head].result)));
+
+ if (++head == nvmeq->q_depth) {
+ head = 0;
+ phase = !phase;
+ }
+ writel(head, nvmeq->q_db + nvmeq->dev->db_stride);
+ nvmeq->cq_head = head;
+ nvmeq->cq_phase = phase;
+
+ return status;
+}
+
+static int nvme_submit_admin_cmd(struct nvme_dev *dev,
+ struct nvme_command *cmd, u32 *result)
+{
+ return nvme_submit_sync_cmd(dev->queues[0], cmd, result, ADMIN_TIMEOUT);
+}
+
+static struct nvme_queue *nvme_alloc_queue(struct nvme_dev *dev,
+ int qid, int depth)
+{
+ struct nvme_queue *nvmeq = malloc(sizeof(*nvmeq));
+ if (!nvmeq)
+ return NULL;
+ memset(nvmeq, 0, sizeof(*nvmeq));
+
+ nvmeq->cqes = (void *)memalign(4096, CQ_SIZE(depth));
+ if (!nvmeq->cqes)
+ goto free_nvmeq;
+ memset((void *)nvmeq->cqes, 0, CQ_SIZE(depth));
+
+ nvmeq->sq_cmds = (void *)memalign(4096, SQ_SIZE(depth));
+ if (!nvmeq->sq_cmds)
+ goto free_queue;
+ memset((void *)nvmeq->sq_cmds, 0, SQ_SIZE(depth));
+
+ nvmeq->dev = dev;
+
+ nvmeq->cq_head = 0;
+ nvmeq->cq_phase = 1;
+ nvmeq->q_db = &dev->dbs[qid * 2 * dev->db_stride];
+ nvmeq->q_depth = depth;
+ nvmeq->qid = qid;
+ dev->queue_count++;
+ dev->queues[qid] = nvmeq;
+
+ return nvmeq;
+ free_queue:
+ free((void *)nvmeq->cqes);
+ free_nvmeq:
+ free(nvmeq);
+ return NULL;
+}
+
+static int adapter_delete_queue(struct nvme_dev *dev, u8 opcode, u16 id)
+{
+ struct nvme_command c;
+ memset(&c, 0, sizeof(c));
+ c.delete_queue.opcode = opcode;
+ c.delete_queue.qid = cpu_to_le16(id);
+ return nvme_submit_admin_cmd(dev, &c, NULL);
+}
+
+static int adapter_delete_sq(struct nvme_dev *dev, u16 sqid)
+{
+ return adapter_delete_queue(dev, nvme_admin_delete_sq, sqid);
+}
+
+static int adapter_delete_cq(struct nvme_dev *dev, u16 cqid)
+{
+ return adapter_delete_queue(dev, nvme_admin_delete_cq, cqid);
+}
+
+static int nvme_enable_ctrl(struct nvme_dev *dev, u64 cap)
+{
+ dev->ctrl_config &= ~NVME_CC_SHN_MASK;
+ dev->ctrl_config |= NVME_CC_ENABLE;
+ writel(cpu_to_le32(dev->ctrl_config), &dev->bar->cc);
+ return nvme_wait_ready(dev, cap, true);
+}
+
+static int nvme_disable_ctrl(struct nvme_dev *dev, u64 cap)
+{
+ dev->ctrl_config &= ~NVME_CC_SHN_MASK;
+ dev->ctrl_config &= ~NVME_CC_ENABLE;
+ writel(cpu_to_le32(dev->ctrl_config), &dev->bar->cc);
+ return nvme_wait_ready(dev, cap, false);
+}
+
+static void nvme_free_queue(struct nvme_queue *nvmeq)
+{
+ free((void *)nvmeq->cqes);
+ free(nvmeq->sq_cmds);
+ free(nvmeq);
+}
+
+static void nvme_free_queues(struct nvme_dev *dev, int lowest)
+{
+ int i;
+ for (i = dev->queue_count - 1; i >= lowest; i--) {
+ struct nvme_queue *nvmeq = dev->queues[i];
+ dev->queue_count--;
+ dev->queues[i] = NULL;
+ nvme_free_queue(nvmeq);
+ }
+}
+
+static void nvme_init_queue(struct nvme_queue *nvmeq, u16 qid)
+{
+ struct nvme_dev *dev = nvmeq->dev;
+ nvmeq->sq_tail = 0;
+ nvmeq->cq_head = 0;
+ nvmeq->cq_phase = 1;
+ nvmeq->q_db = &dev->dbs[qid * 2 * dev->db_stride];
+ memset((void *)nvmeq->cqes, 0, CQ_SIZE(nvmeq->q_depth));
+ flush_dcache_range((u64)nvmeq->cqes,
+ (u64)nvmeq->cqes + CQ_SIZE(nvmeq->q_depth));
+ dev->online_queues++;
+}
+
+static int nvme_configure_admin_queue(struct nvme_dev *dev)
+{
+ int result;
+ u32 aqa;
+ u64 cap = readq(&dev->bar->cap);
+ struct nvme_queue *nvmeq;
+ unsigned page_shift = PAGE_SHIFT;
+ unsigned dev_page_min = NVME_CAP_MPSMIN(cap) + 12;
+ unsigned dev_page_max = NVME_CAP_MPSMAX(cap) + 12;
+ if (page_shift < dev_page_min) {
+ dev_err(&dev->pci_dev->dev,
+ "Minimum device page size (%u) too large for host (%u)\n",
+ 1 << dev_page_min,
+ 1 << page_shift);
+ return -ENODEV;
+ }
+
+ if (page_shift > dev_page_max) {
+ dev_info(&dev->pci_dev->dev,
+ "Device maximum page size (%u) smaller than host (%u); enabling work-around\n",
+ 1 << dev_page_max,
+ 1 << page_shift);
+ page_shift = dev_page_max;
+ }
+
+ result = nvme_disable_ctrl(dev, cap);
+ if (result < 0)
+ return result;
+
+ nvmeq = dev->queues[0];
+ if (!nvmeq) {
+ nvmeq = nvme_alloc_queue(dev, 0, NVME_AQ_DEPTH);
+ if (!nvmeq)
+ return -ENOMEM;
+ }
+
+ aqa = nvmeq->q_depth - 1;
+ aqa |= aqa << 16;
+ aqa |= aqa << 16;
+
+ dev->page_size = 1 << page_shift;
+
+ dev->ctrl_config = NVME_CC_CSS_NVM;
+ dev->ctrl_config |= (page_shift - 12) << NVME_CC_MPS_SHIFT;
+ dev->ctrl_config |= NVME_CC_ARB_RR | NVME_CC_SHN_NONE;
+ dev->ctrl_config |= NVME_CC_IOSQES | NVME_CC_IOCQES;
+
+ writel(aqa, &dev->bar->aqa);
+ writeq((u64)nvmeq->sq_cmds, &dev->bar->asq);
+ writeq((u64)nvmeq->cqes, &dev->bar->acq);
+
+ result = nvme_enable_ctrl(dev, cap);
+ if (result)
+ goto free_nvmeq;
+
+ nvmeq->cq_vector = 0;
+
+ nvme_init_queue(dev->queues[0], 0);
+ return result;
+
+ free_nvmeq:
+ nvme_free_queues(dev, 0);
+ return result;
+}
+
+static int adapter_alloc_cq(struct nvme_dev *dev,
+ u16 qid, struct nvme_queue *nvmeq)
+{
+ struct nvme_command c;
+ int flags = NVME_QUEUE_PHYS_CONTIG | NVME_CQ_IRQ_ENABLED;
+ memset(&c, 0, sizeof(c));
+ c.create_cq.opcode = nvme_admin_create_cq;
+ c.create_cq.prp1 = cpu_to_le64(nvmeq->cqes);
+ c.create_cq.cqid = cpu_to_le16(qid);
+ c.create_cq.qsize = cpu_to_le16(nvmeq->q_depth - 1);
+ c.create_cq.cq_flags = cpu_to_le16(flags);
+ c.create_cq.irq_vector = cpu_to_le16(nvmeq->cq_vector);
+
+ return nvme_submit_admin_cmd(dev, &c, NULL);
+}
+
+static int adapter_alloc_sq(struct nvme_dev *dev,
+ u16 qid, struct nvme_queue *nvmeq)
+{
+ struct nvme_command c;
+ int flags = NVME_QUEUE_PHYS_CONTIG | NVME_SQ_PRIO_MEDIUM;
+ memset(&c, 0, sizeof(c));
+ c.create_sq.opcode = nvme_admin_create_sq;
+ c.create_sq.prp1 = cpu_to_le64(nvmeq->sq_cmds);
+ c.create_sq.sqid = cpu_to_le16(qid);
+ c.create_sq.qsize = cpu_to_le16(nvmeq->q_depth - 1);
+ c.create_sq.sq_flags = cpu_to_le16(flags);
+ c.create_sq.cqid = cpu_to_le16(qid);
+
+ return nvme_submit_admin_cmd(dev, &c, NULL);
+}
+
+static int nvme_identify(struct nvme_dev *dev, unsigned nsid,
+ unsigned cns, dma_addr_t dma_addr)
+{
+ struct nvme_command c;
+ memset(&c, 0, sizeof(c));
+ u32 page_size = dev->page_size;
+ int offset = dma_addr & (page_size - 1);
+ int length = sizeof(struct nvme_id_ctrl);
+
+ c.identify.opcode = nvme_admin_identify;
+ c.identify.nsid = cpu_to_le32(nsid);
+ c.identify.prp1 = cpu_to_le64(dma_addr);
+
+ length -= (page_size - offset);
+ if (length <= 0) {
+ c.identify.prp2 = 0;
+ } else {
+ dma_addr += (page_size - offset);
+ c.identify.prp2 = dma_addr;
+ }
+
+ c.identify.cns = cpu_to_le32(cns);
+
+ return nvme_submit_admin_cmd(dev, &c, NULL);
+}
+
+static __maybe_unused int nvme_get_features(struct nvme_dev *dev, unsigned fid,
+ unsigned nsid, dma_addr_t dma_addr, u32 *result)
+{
+ struct nvme_command c;
+ memset(&c, 0, sizeof(c));
+
+ c.features.opcode = nvme_admin_get_features;
+ c.features.nsid = cpu_to_le32(nsid);
+ c.features.prp1 = cpu_to_le64(dma_addr);
+ c.features.fid = cpu_to_le32(fid);
+
+ return nvme_submit_admin_cmd(dev, &c, result);
+}
+
+static __maybe_unused int nvme_set_features(struct nvme_dev *dev, unsigned fid,
+ unsigned dword11, dma_addr_t dma_addr, u32 *result)
+{
+ struct nvme_command c;
+ memset(&c, 0, sizeof(c));
+
+ c.features.opcode = nvme_admin_set_features;
+ c.features.prp1 = cpu_to_le64(dma_addr);
+ c.features.fid = cpu_to_le32(fid);
+ c.features.dword11 = cpu_to_le32(dword11);
+
+ return nvme_submit_admin_cmd(dev, &c, result);
+}
+
+static int nvme_create_queue(struct nvme_queue *nvmeq, int qid)
+{
+ struct nvme_dev *dev = nvmeq->dev;
+ int result;
+
+ nvmeq->cq_vector = qid - 1;
+ result = adapter_alloc_cq(dev, qid, nvmeq);
+ if (result < 0)
+ goto release_cq;
+
+ result = adapter_alloc_sq(dev, qid, nvmeq);
+ if (result < 0)
+ goto release_sq;
+
+ nvme_init_queue(nvmeq, qid);
+ return result;
+
+ release_sq:
+ adapter_delete_sq(dev, qid);
+ release_cq:
+ adapter_delete_cq(dev, qid);
+ return result;
+}
+
+static int set_queue_count(struct nvme_dev *dev, int count)
+{
+ int status;
+ u32 result;
+ u32 q_count = (count - 1) | ((count - 1) << 16);
+
+ status = nvme_set_features(dev, NVME_FEAT_NUM_QUEUES,
+ q_count, 0, &result);
+
+ if (status < 0)
+ return status;
+ if (status > 1)
+ return 0;
+
+ return min(result & 0xffff, result >> 16) + 1;
+}
+
+static void nvme_create_io_queues(struct nvme_dev *dev)
+{
+ unsigned int i;
+
+ for (i = dev->queue_count; i <= dev->max_qid; i++)
+ if (!nvme_alloc_queue(dev, i, dev->q_depth))
+ break;
+
+ for (i = dev->online_queues; i <= dev->queue_count - 1; i++)
+ if (nvme_create_queue(dev->queues[i], i))
+ break;
+}
+
+static int nvme_setup_io_queues(struct nvme_dev *dev)
+{
+ int nr_io_queues;
+ int result;
+ nr_io_queues = 1;
+ result = set_queue_count(dev, nr_io_queues);
+ if (result <= 0)
+ return result;
+
+ if (result < nr_io_queues)
+ nr_io_queues = result;
+
+ dev->max_qid = nr_io_queues;
+
+ /* Free previously allocated queues*/
+ nvme_free_queues(dev, nr_io_queues + 1);
+ nvme_create_io_queues(dev);
+
+ return 0;
+}
+
+static int nvme_get_info_from_identify(struct nvme_dev *dev)
+{
+ u16 vendor, device;
+ struct nvme_id_ctrl buf, *ctrl = &buf;
+ int ret;
+ int shift = NVME_CAP_MPSMIN(readq(&dev->bar->cap)) + 12;
+
+ ret = nvme_identify(dev, 0, 1, (dma_addr_t)ctrl);
+ if (ret) {
+ printf("Error: nvme%d get identify error\n", dev->instance);
+ return -EIO;
+ }
+
+ dev->nn = le32_to_cpu(ctrl->nn);
+ dev->vwc = ctrl->vwc;
+ memcpy(dev->serial, ctrl->sn, sizeof(ctrl->sn));
+ memcpy(dev->model, ctrl->mn, sizeof(ctrl->mn));
+ memcpy(dev->firmware_rev, ctrl->fr, sizeof(ctrl->fr));
+ if (ctrl->mdts)
+ dev->max_transfer_shift = (ctrl->mdts + shift);
+
+#ifdef CONFIG_BLK
+ dm_pci_read_config16(dev->pdev, PCI_VENDOR_ID, &vendor);
+ dm_pci_read_config16(dev->pdev, PCI_DEVICE_ID, &device);
+#else
+ pci_read_config_word(dev->pci_dev, PCI_VENDOR_ID, &vendor);
+ pci_read_config_word(dev->pci_dev, PCI_DEVICE_ID, &device);
+#endif
+ if ((vendor == PCI_VENDOR_ID_INTEL) &&
+ (device == 0x0953) && ctrl->vs[3]) {
+ unsigned int max_transfer_shift;
+ dev->stripe_size = (ctrl->vs[3] + shift);
+ max_transfer_shift = (ctrl->vs[3] + 18);
+ if (dev->max_transfer_shift) {
+ dev->max_transfer_shift = min(max_transfer_shift,
+ dev->max_transfer_shift);
+ } else {
+ dev->max_transfer_shift = max_transfer_shift;
+ }
+ }
+ return 0;
+}
+
+#ifdef CONFIG_BLK
+int init_nvme(struct udevice *udev)
+#else
+int init_nvme(int devnum)
+#endif
+{
+ static int init_done;
+ pci_dev_t pci_dev;
+ int ret;
+#ifdef CONFIG_BLK
+ struct nvme_ns *ns = dev_get_priv(udev);
+ struct nvme_dev *dev = ns->dev;
+ int devnum = trailing_strtol(udev->name);
+#else
+ struct nvme_dev *dev;
+#endif
+ u32 val;
+ u64 cap;
+
+ if (init_done == 1 && devnum < nvme_info.maxport) {
+ printf("devnum = %d\n", devnum);
+ return 0;
+ }
+
+ pci_dev = pci_find_devices(nvme_supported, nvme_info.idx++);
+ if (pci_dev == -1) {
+ printf("Error: can't find pci device \"nvme%d\"\n",
+ nvme_info.idx - 1);
+ return -ENODEV;
+ }
+
+ dev = malloc(sizeof(*dev));
+ if (dev == NULL) {
+ printf("Error: nvme%d: Out of Memory!\n", nvme_info.idx - 1);
+ return -ENOMEM;
+ }
+ memset(dev, 0, sizeof(*dev));
+
+ dev->instance = nvme_info.idx - 1;
+ INIT_LIST_HEAD(&dev->namespaces);
+#ifdef CONFIG_BLK
+ dev->pdev = udev;
+ dev->bar = dm_pci_map_bar(udev, PCI_BASE_ADDRESS_0,
+ PCI_REGION_MEM);
+#else
+ dev->pci_dev = pci_dev;
+ dev->bar = pci_map_bar(dev->pci_dev, PCI_BASE_ADDRESS_0,
+ PCI_REGION_MEM);
+#endif
+ if (readl(&dev->bar->csts) == -1) {
+ ret = -ENODEV;
+ printf("Error: nvme%d: Out of Memory!\n", nvme_info.idx - 1);
+ goto free_nvme;
+ }
+
+ dev->queues = malloc(2 * sizeof(struct nvme_queue));
+ if (!dev->queues) {
+ ret = -ENOMEM;
+ printf("Error: nvme%d: Out of Memory!\n", dev->instance);
+ goto free_nvme;
+ }
+ memset(dev->queues, 0, sizeof(2 * sizeof(struct nvme_queue)));
+
+ dev->prp_pool = malloc(MAX_PRP_POOL);
+ if (!dev->prp_pool) {
+ ret = -ENOMEM;
+ printf("Error: nvme%d: Out of Memory!\n", dev->instance);
+ goto free_nvme;
+ }
+ dev->prp_entry_num = MAX_PRP_POOL >> 3;
+
+ /* Try to enable I/O accesses and bus-mastering */
+ val = PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER;
+#ifdef CONFIG_BLK
+ dm_pci_write_config32(udev, PCI_COMMAND, val);
+#else
+ pci_write_config_dword(dev->pci_dev, PCI_COMMAND, val);
+#endif
+
+ /* Print a debug message with the IO base address */
+#ifdef CONFIG_BLK
+ dm_pci_read_config32(udev, PCI_BASE_ADDRESS_0, &val);
+#else
+ pci_read_config_dword(dev->pci_dev, PCI_BASE_ADDRESS_0, &val);
+#endif
+
+ /* Make sure it worked */
+#ifdef CONFIG_BLK
+ dm_pci_read_config32(udev, PCI_COMMAND, &val);
+#else
+ pci_read_config_dword(dev->pci_dev, PCI_COMMAND, &val);
+#endif
+ if (!(val & PCI_COMMAND_MEMORY)) {
+ printf("Can't enable I/O memory\n");
+ ret = -ENOSPC;
+ goto free_queue;
+ }
+ if (!(val & PCI_COMMAND_MASTER)) {
+ printf("Can't enable bus-mastering\n");
+ ret = -EPERM;
+ goto free_queue;
+ }
+ if (readl(&dev->bar->csts) == -1) {
+ ret = -ENODEV;
+ goto free_queue;
+ }
+
+ cap = readq(&dev->bar->cap);
+ dev->q_depth = min_t(int, NVME_CAP_MQES(cap) + 1, NVME_Q_DEPTH);
+ dev->db_stride = 1 << NVME_CAP_STRIDE(cap);
+ dev->dbs = ((void __iomem *)dev->bar) + 4096;
+
+ ret = nvme_configure_admin_queue(dev);
+ if (ret)
+ goto free_queue;
+
+ ret = nvme_setup_io_queues(dev);
+ if (ret)
+ goto free_queue;
+
+ nvme_get_info_from_identify(dev);
+ dev->blk_dev_start = nvme_info.maxport;
+ list_add(&dev->node, &nvme_info.dev_list);
+
+ nvme_info.maxport += dev->nn;
+ init_done = 1;
+ return 0;
+ free_queue:
+ free((void *)dev->queues);
+ free_nvme:
+ free((void *)dev);
+ return ret;
+}
+
+static struct nvme_dev *find_dev_by_devnum(int devnum)
+{
+ struct nvme_dev *dev;
+ list_for_each_entry(dev, &nvme_info.dev_list, node) {
+ if ((devnum >= dev->blk_dev_start) &&
+ (devnum < dev->blk_dev_start + dev->nn))
+ return dev;
+ }
+ return NULL;
+}
+
+static struct nvme_ns *find_ns_by_devnum(int devnum)
+{
+ struct nvme_dev *dev;
+ struct nvme_ns *ns;
+
+ dev = find_dev_by_devnum(devnum);
+ if (!dev)
+ return NULL;
+
+ list_for_each_entry(ns, &dev->namespaces, list) {
+ if (devnum == ns->devnum)
+ return ns;
+ }
+ return NULL;
+}
+
+#ifdef CONFIG_BLK
+int scan_nvme(struct udevice *udev)
+{
+ struct nvme_ns *ns = dev_get_priv(udev);
+ struct nvme_dev *dev = ns->dev;
+ int devnum = trailing_strtol(udev->name);
+#else
+int scan_nvme(int devnum)
+{
+ struct nvme_ns *ns;
+ struct nvme_dev *dev;
+#endif
+ int ret;
+ u8 flbas;
+ u16 vendor;
+ char vendor_c[8];
+ struct nvme_id_ns buf, *id = &buf;
+
+ if (devnum > nvme_info.maxport) {
+ printf("Error: devnum %d is not initialized\n", devnum);
+ return -ENODEV;
+ }
+
+ dev = find_dev_by_devnum(devnum);
+ if (!dev)
+ return -ENODEV;
+
+ ns = find_ns_by_devnum(devnum);
+ if (ns)
+ return 0;
+
+ ns = malloc(sizeof(*ns));
+ if (!ns)
+ return -ENOMEM;
+ memset(ns, 0, sizeof(*ns));
+ ns->dev = dev;
+ ns->ns_id = devnum - dev->blk_dev_start + 1;
+ ns->devnum = devnum;
+ if (nvme_identify(dev, ns->ns_id, 0, (dma_addr_t)id)) {
+ ret = -EIO;
+ goto free_ns;
+ }
+ flbas = id->flbas & NVME_NS_FLBAS_LBA_MASK;
+ ns->flbas = flbas;
+ ns->lba_shift = id->lbaf[flbas].ds;
+ ns->mode_select_num_blocks = le64_to_cpu(id->nuse);
+ ns->mode_select_block_len = 1 << ns->lba_shift;
+ list_add(&ns->list, &dev->namespaces);
+ nvme_dev_desc[devnum].lba = ns->mode_select_num_blocks;
+ nvme_dev_desc[devnum].log2blksz = ns->lba_shift;
+ nvme_dev_desc[devnum].blksz = 1 << ns->lba_shift;
+#ifdef CONFIG_BLK
+ nvme_dev_desc[devnum].bdev = dev->pdev;
+ dm_pci_read_config16(dev->pdev, PCI_VENDOR_ID, &vendor);
+ udev->priv = ns;
+ udev->uclass_platdata = (void *)&nvme_dev_desc[devnum];
+#else
+ nvme_dev_desc[devnum].priv = (void *)ns;
+ pci_read_config_word(dev->pci_dev, PCI_VENDOR_ID, &vendor);
+#endif
+ sprintf(vendor_c, "0x%.4x", vendor);
+ memcpy(nvme_dev_desc[devnum].product,
+ dev->serial, sizeof(dev->serial));
+ memcpy(nvme_dev_desc[devnum].vendor,
+ vendor_c, sizeof(vendor_c));
+ memcpy(nvme_dev_desc[devnum].revision,
+ dev->firmware_rev, sizeof(dev->firmware_rev));
+ return 0;
+ free_ns:
+ free(ns);
+ return ret;
+}
+
+static void print_optional_admin_cmd(u16 oacs, int devnum)
+{
+ printf("Blk device %d: Optional Admin Command Support:\n",
+ devnum);
+ printf("\tNamespace Management/Attachment: %s\n",
+ oacs & 0x08 ? "yes" : "no");
+ printf("\tFirmware Commit/Image download: %s\n",
+ oacs & 0x04 ? "yes" : "no");
+ printf("\tFormat NVM: %s\n",
+ oacs & 0x02 ? "yes" : "no");
+ printf("\tSecurity Send/Receive: %s\n",
+ oacs & 0x01 ? "yes" : "no");
+}
+
+static void print_optional_nvm_cmd(u16 oncs, int devnum)
+{
+ printf("Blk device %d: Optional NVM Command Support:\n",
+ devnum);
+ printf("\tReservation: %s\n",
+ oncs & 0x10 ? "yes" : "no");
+ printf("\tSave/Select field in the Set/Get features: %s\n",
+ oncs & 0x08 ? "yes" : "no");
+ printf("\tWrite Zeroes: %s\n",
+ oncs & 0x04 ? "yes" : "no");
+ printf("\tDataset Management: %s\n",
+ oncs & 0x02 ? "yes" : "no");
+ printf("\tWrite Uncorrectable: %s\n",
+ oncs & 0x01 ? "yes" : "no");
+}
+
+static void print_format_nvme_attributes(u8 fna, int devnum)
+{
+ printf("Blk device %d: Format NVM Attributes:\n", devnum);
+ printf("\tSupport Cryptographic Erase: %s\n",
+ fna & 0x04 ? "yes" : "No");
+ printf("\tSupport erase a particular namespace: %s\n",
+ fna & 0x02 ? "No" : "Yes");
+ printf("\tSupport format a particular namespace: %s\n",
+ fna & 0x01 ? "No" : "Yes");
+}
+
+static void print_format(struct nvme_lbaf *lbaf)
+{
+ u8 str[][10] = {"Best", "Better", "Good", "Degraded"};
+ printf("\t\tMetadata Size: %d\n", le16_to_cpu(lbaf->ms));
+ printf("\t\tLBA Data Size: %d\n", 1 << lbaf->ds);
+ printf("\t\tRelative Performance: %s\n", str[lbaf->rp & 0x03]);
+}
+
+static void print_formats(struct nvme_id_ns *id, struct nvme_ns *ns)
+{
+ int i;
+ printf("Blk device %d: LBA Format Support:\n", ns->devnum);
+ for (i = 0; i < id->nlbaf; i++) {
+ printf("\tLBA Foramt %d Support: ", i);
+ if (i == ns->flbas)
+ printf("(current)\n");
+ else
+ printf("\n");
+ print_format(id->lbaf + i);
+ }
+}
+
+static void print_data_protect_cap(u8 dpc, int devnum)
+{
+ printf("Blk device %d: End-to-End Data", devnum);
+ printf("Protect Capabilities:\n");
+ printf("\tAs last eight bytes: %s\n",
+ dpc & 0x10 ? "yes" : "No");
+ printf("\tAs first eight bytes: %s\n",
+ dpc & 0x08 ? "yes" : "No");
+ printf("\tSupport Type3: %s\n",
+ dpc & 0x04 ? "yes" : "No");
+ printf("\tSupport Type2: %s\n",
+ dpc & 0x02 ? "yes" : "No");
+ printf("\tSupport Type1: %s\n",
+ dpc & 0x01 ? "yes" : "No");
+}
+
+static void print_metadata_cap(u8 mc, int devnum)
+{
+ printf("Blk device %d: Metadata capabilities:\n", devnum);
+ printf("\tAs part of a separate buffer: %s\n",
+ mc & 0x02 ? "yes" : "No");
+ printf("\tAs part of an extended data LBA: %s\n",
+ mc & 0x01 ? "yes" : "No");
+}
+
+int nvme_print_info(int devnum)
+{
+#ifdef CONFIG_BLK
+ struct udevice *udev;
+ blk_get_device(IF_TYPE_NVME, devnum, &udev);
+ struct nvme_ns *ns = dev_get_priv(udev);
+#else
+ struct nvme_ns *ns = nvme_dev_desc[devnum].priv;
+#endif
+ if (!ns) {
+ printf("Can not find device %d\n", devnum);
+ return -EINVAL;
+ }
+
+ struct nvme_dev *dev = ns->dev;
+ struct nvme_id_ns buf_ns, *id = &buf_ns;
+ struct nvme_id_ctrl buf_ctrl, *ctrl = &buf_ctrl;
+
+ if (nvme_identify(dev, 0, 1, (dma_addr_t)ctrl))
+ return -EIO;
+
+ print_optional_admin_cmd(le16_to_cpu(ctrl->oacs), devnum);
+ print_optional_nvm_cmd(le16_to_cpu(ctrl->oncs), devnum);
+ print_format_nvme_attributes(ctrl->fna, devnum);
+
+ if (nvme_identify(dev, ns->ns_id, 0, (dma_addr_t)id))
+ return -EIO;
+
+ print_formats(id, ns);
+ print_data_protect_cap(id->dpc, devnum);
+ print_metadata_cap(id->mc, devnum);
+ return 0;
+}
+
+#ifdef CONFIG_BLK
+ulong nvme_write(struct udevice *udev, ulong blknr, lbaint_t blkcnt,
+ const void *buffer)
+{
+ struct nvme_ns *ns = dev_get_priv(udev);
+ struct nvme_dev *dev = ns->dev;
+ int devnum = ns->devnum;
+#else
+ulong nvme_write(int devnum, ulong blknr, lbaint_t blkcnt,
+ const void *buffer)
+{
+ struct nvme_ns *ns = nvme_dev_desc[devnum].priv;
+ struct nvme_dev *dev = ns->dev;
+#endif
+ struct nvme_command c;
+ int status;
+ u64 prp2;
+ u64 total_len = blkcnt << nvme_dev_desc[devnum].log2blksz;
+ u64 temp_len = total_len;
+
+ u64 slba = blknr;
+ u16 lbas = 1 << (dev->max_transfer_shift - ns->lba_shift);
+ u64 total_lbas = blkcnt;
+
+ c.rw.opcode = nvme_cmd_write;
+ c.rw.flags = 0;
+ c.rw.nsid = cpu_to_le32(ns->ns_id);
+ c.rw.control = 0;
+ c.rw.dsmgmt = 0;
+ c.rw.reftag = 0;
+ c.rw.apptag = 0;
+ c.rw.appmask = 0;
+ c.rw.metadata = 0;
+
+ while (total_lbas) {
+ if (total_lbas < lbas) {
+ lbas = (u16)total_lbas;
+ total_lbas = 0;
+ } else {
+ total_lbas -= lbas;
+ }
+
+ if (nvme_setup_prps
+ (dev, &prp2, lbas << ns->lba_shift, (u64)buffer))
+ return -EIO;
+ c.rw.slba = cpu_to_le64(slba);
+ slba += lbas;
+ c.rw.length = cpu_to_le16(lbas - 1);
+ c.rw.prp1 = cpu_to_le64(buffer);
+ c.rw.prp2 = cpu_to_le64(prp2);
+ status = nvme_submit_sync_cmd(dev->queues[1],
+ &c, NULL, NVME_IO_TIMEOUT);
+ if (status)
+ break;
+ temp_len -= lbas << ns->lba_shift;
+ buffer += lbas << ns->lba_shift;
+ }
+ return (total_len - temp_len) >> nvme_dev_desc[devnum].log2blksz;
+}
+
+#ifdef CONFIG_BLK
+ulong nvme_read(struct udevice *udev, ulong blknr, lbaint_t blkcnt,
+ void *buffer)
+{
+ struct nvme_ns *ns = dev_get_priv(udev);
+ struct nvme_dev *dev = ns->dev;
+ int devnum = ns->devnum;
+#else
+ulong nvme_read(int devnum, ulong blknr, lbaint_t blkcnt,
+ void *buffer)
+{
+ struct nvme_ns *ns = nvme_dev_desc[devnum].priv;
+ struct nvme_dev *dev = ns->dev;
+#endif
+ struct nvme_command c;
+ int status;
+ u64 prp2;
+ u64 total_len = blkcnt << nvme_dev_desc[devnum].log2blksz;
+ u64 temp_len = total_len;
+
+ u64 slba = blknr;
+ u16 lbas = 1 << (dev->max_transfer_shift - ns->lba_shift);
+ u64 total_lbas = blkcnt;
+
+ c.rw.opcode = nvme_cmd_read;
+ c.rw.flags = 0;
+ c.rw.nsid = cpu_to_le32(ns->ns_id);
+ c.rw.control = 0;
+ c.rw.dsmgmt = 0;
+ c.rw.reftag = 0;
+ c.rw.apptag = 0;
+ c.rw.appmask = 0;
+ c.rw.metadata = 0;
+
+ while (total_lbas) {
+ if (total_lbas < lbas) {
+ lbas = (u16)total_lbas;
+ total_lbas = 0;
+ } else {
+ total_lbas -= lbas;
+ }
+
+ if (nvme_setup_prps
+ (dev, &prp2, lbas << ns->lba_shift, (u64)buffer))
+ return -EIO;
+ c.rw.slba = cpu_to_le64(slba);
+ slba += lbas;
+ c.rw.length = cpu_to_le16(lbas - 1);
+ c.rw.prp1 = cpu_to_le64(buffer);
+ c.rw.prp2 = cpu_to_le64(prp2);
+ status = nvme_submit_sync_cmd(dev->queues[1],
+ &c, NULL, NVME_IO_TIMEOUT);
+ if (status)
+ break;
+ temp_len -= lbas << ns->lba_shift;
+ buffer += lbas << ns->lba_shift;
+ }
+ return (total_len - temp_len) >> nvme_dev_desc[devnum].log2blksz;
+}
diff --git a/drivers/block/nvme.h b/drivers/block/nvme.h
new file mode 100644
index 0000000..9345f90
--- /dev/null
+++ b/drivers/block/nvme.h
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2017 NXP Semiconductors
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <pci.h>
+#include <asm/io.h>
+#include "nvme_uapi.h"
+#include <linux/list.h>
+#include <nvme.h>
+
+struct nvme_bar {
+ __u64 cap; /* Controller Capabilities */
+ __u32 vs; /* Version */
+ __u32 intms; /* Interrupt Mask Set */
+ __u32 intmc; /* Interrupt Mask Clear */
+ __u32 cc; /* Controller Configuration */
+ __u32 rsvd1; /* Reserved */
+ __u32 csts; /* Controller Status */
+ __u32 rsvd2; /* Reserved */
+ __u32 aqa; /* Admin Queue Attributes */
+ __u64 asq; /* Admin SQ Base Address */
+ __u64 acq; /* Admin CQ Base Address */
+};
+
+#define NVME_CAP_MQES(cap) ((cap) & 0xffff)
+#define NVME_CAP_TIMEOUT(cap) (((cap) >> 24) & 0xff)
+#define NVME_CAP_STRIDE(cap) (((cap) >> 32) & 0xf)
+#define NVME_CAP_MPSMIN(cap) (((cap) >> 48) & 0xf)
+#define NVME_CAP_MPSMAX(cap) (((cap) >> 52) & 0xf)
+
+enum {
+ NVME_CC_ENABLE = 1 << 0,
+ NVME_CC_CSS_NVM = 0 << 4,
+ NVME_CC_MPS_SHIFT = 7,
+ NVME_CC_ARB_RR = 0 << 11,
+ NVME_CC_ARB_WRRU = 1 << 11,
+ NVME_CC_ARB_VS = 7 << 11,
+ NVME_CC_SHN_NONE = 0 << 14,
+ NVME_CC_SHN_NORMAL = 1 << 14,
+ NVME_CC_SHN_ABRUPT = 2 << 14,
+ NVME_CC_SHN_MASK = 3 << 14,
+ NVME_CC_IOSQES = 6 << 16,
+ NVME_CC_IOCQES = 4 << 20,
+ NVME_CSTS_RDY = 1 << 0,
+ NVME_CSTS_CFS = 1 << 1,
+ NVME_CSTS_SHST_NORMAL = 0 << 2,
+ NVME_CSTS_SHST_OCCUR = 1 << 2,
+ NVME_CSTS_SHST_CMPLT = 2 << 2,
+ NVME_CSTS_SHST_MASK = 3 << 2,
+};
+
+#define NVME_IO_TIMEOUT 30
+
+/*
+ * Represents an NVM Express device. Each nvme_dev is a PCI function.
+ */
+struct nvme_dev {
+ struct list_head node;
+ struct nvme_queue **queues;
+ u32 __iomem *dbs;
+ unsigned int cardnum;
+#ifdef CONFIG_BLK
+ struct udevice *pdev;
+#endif
+ pci_dev_t pci_dev;
+ int instance;
+ uint8_t *hw_addr;
+ unsigned queue_count;
+ unsigned online_queues;
+ unsigned max_qid;
+ int q_depth;
+ u32 db_stride;
+ u32 ctrl_config;
+ struct nvme_bar __iomem *bar;
+ struct list_head namespaces;
+ const char *name;
+ char serial[20];
+ char model[40];
+ char firmware_rev[8];
+ u32 max_transfer_shift;
+ u32 stripe_size;
+ u32 page_size;
+ u16 oncs;
+ u16 abort_limit;
+ u8 event_limit;
+ u8 vwc;
+ u64 *prp_pool;
+ u32 prp_entry_num;
+ u32 nn;
+ u32 blk_dev_start;
+};
+
+struct nvme_info {
+ int maxport;
+ int idx;
+ struct list_head dev_list;
+};
+
+/*
+ * The nvme_iod describes the data in an I/O, including the list of PRP
+ * entries. You can't see it in this data structure because C doesn't let
+ * me express that. Use nvme_alloc_iod to ensure there's enough space
+ * allocated to store the PRP list.
+ */
+struct nvme_iod {
+ unsigned long private; /* For the use of the submitter of the I/O */
+ int npages; /* In the PRP list. 0 means small pool in use */
+ int offset; /* Of PRP list */
+ int nents; /* Used in scatterlist */
+ int length; /* Of data, in bytes */
+ dma_addr_t first_dma;
+};
diff --git a/drivers/block/nvme_uapi.h b/drivers/block/nvme_uapi.h
new file mode 100644
index 0000000..c87d104
--- /dev/null
+++ b/drivers/block/nvme_uapi.h
@@ -0,0 +1,570 @@
+/*
+ * Copyright (C) 2017 NXP Semiconductors
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <linux/types.h>
+
+struct nvme_id_power_state {
+ __le16 max_power; /* centiwatts */
+ __u8 rsvd2;
+ __u8 flags;
+ __le32 entry_lat; /* microseconds */
+ __le32 exit_lat; /* microseconds */
+ __u8 read_tput;
+ __u8 read_lat;
+ __u8 write_tput;
+ __u8 write_lat;
+ __le16 idle_power;
+ __u8 idle_scale;
+ __u8 rsvd19;
+ __le16 active_power;
+ __u8 active_work_scale;
+ __u8 rsvd23[9];
+};
+
+enum {
+ NVME_PS_FLAGS_MAX_POWER_SCALE = 1 << 0,
+ NVME_PS_FLAGS_NON_OP_STATE = 1 << 1,
+};
+
+struct nvme_id_ctrl {
+ __le16 vid;
+ __le16 ssvid;
+ char sn[20];
+ char mn[40];
+ char fr[8];
+ __u8 rab;
+ __u8 ieee[3];
+ __u8 mic;
+ __u8 mdts;
+ __u16 cntlid;
+ __u32 ver;
+ __u8 rsvd84[172];
+ __le16 oacs;
+ __u8 acl;
+ __u8 aerl;
+ __u8 frmw;
+ __u8 lpa;
+ __u8 elpe;
+ __u8 npss;
+ __u8 avscc;
+ __u8 apsta;
+ __le16 wctemp;
+ __le16 cctemp;
+ __u8 rsvd270[242];
+ __u8 sqes;
+ __u8 cqes;
+ __u8 rsvd514[2];
+ __le32 nn;
+ __le16 oncs;
+ __le16 fuses;
+ __u8 fna;
+ __u8 vwc;
+ __le16 awun;
+ __le16 awupf;
+ __u8 nvscc;
+ __u8 rsvd531;
+ __le16 acwu;
+ __u8 rsvd534[2];
+ __le32 sgls;
+ __u8 rsvd540[1508];
+ struct nvme_id_power_state psd[32];
+ __u8 vs[1024];
+};
+
+enum {
+ NVME_CTRL_ONCS_COMPARE = 1 << 0,
+ NVME_CTRL_ONCS_WRITE_UNCORRECTABLE = 1 << 1,
+ NVME_CTRL_ONCS_DSM = 1 << 2,
+ NVME_CTRL_VWC_PRESENT = 1 << 0,
+};
+
+struct nvme_lbaf {
+ __le16 ms;
+ __u8 ds;
+ __u8 rp;
+};
+
+struct nvme_id_ns {
+ __le64 nsze;
+ __le64 ncap;
+ __le64 nuse;
+ __u8 nsfeat;
+ __u8 nlbaf;
+ __u8 flbas;
+ __u8 mc;
+ __u8 dpc;
+ __u8 dps;
+ __u8 nmic;
+ __u8 rescap;
+ __u8 fpi;
+ __u8 rsvd33;
+ __le16 nawun;
+ __le16 nawupf;
+ __le16 nacwu;
+ __le16 nabsn;
+ __le16 nabo;
+ __le16 nabspf;
+ __u16 rsvd46;
+ __le64 nvmcap[2];
+ __u8 rsvd64[40];
+ __u8 nguid[16];
+ __u8 eui64[8];
+ struct nvme_lbaf lbaf[16];
+ __u8 rsvd192[192];
+ __u8 vs[3712];
+};
+
+enum {
+ NVME_NS_FEAT_THIN = 1 << 0,
+ NVME_NS_FLBAS_LBA_MASK = 0xf,
+ NVME_NS_FLBAS_META_EXT = 0x10,
+ NVME_LBAF_RP_BEST = 0,
+ NVME_LBAF_RP_BETTER = 1,
+ NVME_LBAF_RP_GOOD = 2,
+ NVME_LBAF_RP_DEGRADED = 3,
+ NVME_NS_DPC_PI_LAST = 1 << 4,
+ NVME_NS_DPC_PI_FIRST = 1 << 3,
+ NVME_NS_DPC_PI_TYPE3 = 1 << 2,
+ NVME_NS_DPC_PI_TYPE2 = 1 << 1,
+ NVME_NS_DPC_PI_TYPE1 = 1 << 0,
+ NVME_NS_DPS_PI_FIRST = 1 << 3,
+ NVME_NS_DPS_PI_MASK = 0x7,
+ NVME_NS_DPS_PI_TYPE1 = 1,
+ NVME_NS_DPS_PI_TYPE2 = 2,
+ NVME_NS_DPS_PI_TYPE3 = 3,
+};
+
+struct nvme_smart_log {
+ __u8 critical_warning;
+ __u8 temperature[2];
+ __u8 avail_spare;
+ __u8 spare_thresh;
+ __u8 percent_used;
+ __u8 rsvd6[26];
+ __u8 data_units_read[16];
+ __u8 data_units_written[16];
+ __u8 host_reads[16];
+ __u8 host_writes[16];
+ __u8 ctrl_busy_time[16];
+ __u8 power_cycles[16];
+ __u8 power_on_hours[16];
+ __u8 unsafe_shutdowns[16];
+ __u8 media_errors[16];
+ __u8 num_err_log_entries[16];
+ __le32 warning_temp_time;
+ __le32 critical_comp_time;
+ __le16 temp_sensor[8];
+ __u8 rsvd216[296];
+};
+
+enum {
+ NVME_SMART_CRIT_SPARE = 1 << 0,
+ NVME_SMART_CRIT_TEMPERATURE = 1 << 1,
+ NVME_SMART_CRIT_RELIABILITY = 1 << 2,
+ NVME_SMART_CRIT_MEDIA = 1 << 3,
+ NVME_SMART_CRIT_VOLATILE_MEMORY = 1 << 4,
+};
+
+struct nvme_lba_range_type {
+ __u8 type;
+ __u8 attributes;
+ __u8 rsvd2[14];
+ __u64 slba;
+ __u64 nlb;
+ __u8 guid[16];
+ __u8 rsvd48[16];
+};
+
+enum {
+ NVME_LBART_TYPE_FS = 0x01,
+ NVME_LBART_TYPE_RAID = 0x02,
+ NVME_LBART_TYPE_CACHE = 0x03,
+ NVME_LBART_TYPE_SWAP = 0x04,
+
+ NVME_LBART_ATTRIB_TEMP = 1 << 0,
+ NVME_LBART_ATTRIB_HIDE = 1 << 1,
+};
+
+struct nvme_reservation_status {
+ __le32 gen;
+ __u8 rtype;
+ __u8 regctl[2];
+ __u8 resv5[2];
+ __u8 ptpls;
+ __u8 resv10[13];
+ struct {
+ __le16 cntlid;
+ __u8 rcsts;
+ __u8 resv3[5];
+ __le64 hostid;
+ __le64 rkey;
+ } regctl_ds[];
+};
+
+/* I/O commands */
+
+enum nvme_opcode {
+ nvme_cmd_flush = 0x00,
+ nvme_cmd_write = 0x01,
+ nvme_cmd_read = 0x02,
+ nvme_cmd_write_uncor = 0x04,
+ nvme_cmd_compare = 0x05,
+ nvme_cmd_write_zeroes = 0x08,
+ nvme_cmd_dsm = 0x09,
+ nvme_cmd_resv_register = 0x0d,
+ nvme_cmd_resv_report = 0x0e,
+ nvme_cmd_resv_acquire = 0x11,
+ nvme_cmd_resv_release = 0x15,
+};
+
+struct nvme_common_command {
+ __u8 opcode;
+ __u8 flags;
+ __u16 command_id;
+ __le32 nsid;
+ __le32 cdw2[2];
+ __le64 metadata;
+ __le64 prp1;
+ __le64 prp2;
+ __le32 cdw10[6];
+};
+
+struct nvme_rw_command {
+ __u8 opcode;
+ __u8 flags;
+ __u16 command_id;
+ __le32 nsid;
+ __u64 rsvd2;
+ __le64 metadata;
+ __le64 prp1;
+ __le64 prp2;
+ __le64 slba;
+ __le16 length;
+ __le16 control;
+ __le32 dsmgmt;
+ __le32 reftag;
+ __le16 apptag;
+ __le16 appmask;
+};
+
+enum {
+ NVME_RW_LR = 1 << 15,
+ NVME_RW_FUA = 1 << 14,
+ NVME_RW_DSM_FREQ_UNSPEC = 0,
+ NVME_RW_DSM_FREQ_TYPICAL = 1,
+ NVME_RW_DSM_FREQ_RARE = 2,
+ NVME_RW_DSM_FREQ_READS = 3,
+ NVME_RW_DSM_FREQ_WRITES = 4,
+ NVME_RW_DSM_FREQ_RW = 5,
+ NVME_RW_DSM_FREQ_ONCE = 6,
+ NVME_RW_DSM_FREQ_PREFETCH = 7,
+ NVME_RW_DSM_FREQ_TEMP = 8,
+ NVME_RW_DSM_LATENCY_NONE = 0 << 4,
+ NVME_RW_DSM_LATENCY_IDLE = 1 << 4,
+ NVME_RW_DSM_LATENCY_NORM = 2 << 4,
+ NVME_RW_DSM_LATENCY_LOW = 3 << 4,
+ NVME_RW_DSM_SEQ_REQ = 1 << 6,
+ NVME_RW_DSM_COMPRESSED = 1 << 7,
+ NVME_RW_PRINFO_PRCHK_REF = 1 << 10,
+ NVME_RW_PRINFO_PRCHK_APP = 1 << 11,
+ NVME_RW_PRINFO_PRCHK_GUARD = 1 << 12,
+ NVME_RW_PRINFO_PRACT = 1 << 13,
+};
+
+struct nvme_dsm_cmd {
+ __u8 opcode;
+ __u8 flags;
+ __u16 command_id;
+ __le32 nsid;
+ __u64 rsvd2[2];
+ __le64 prp1;
+ __le64 prp2;
+ __le32 nr;
+ __le32 attributes;
+ __u32 rsvd12[4];
+};
+
+enum {
+ NVME_DSMGMT_IDR = 1 << 0,
+ NVME_DSMGMT_IDW = 1 << 1,
+ NVME_DSMGMT_AD = 1 << 2,
+};
+
+struct nvme_dsm_range {
+ __le32 cattr;
+ __le32 nlb;
+ __le64 slba;
+};
+
+/* Admin commands */
+
+enum nvme_admin_opcode {
+ nvme_admin_delete_sq = 0x00,
+ nvme_admin_create_sq = 0x01,
+ nvme_admin_get_log_page = 0x02,
+ nvme_admin_delete_cq = 0x04,
+ nvme_admin_create_cq = 0x05,
+ nvme_admin_identify = 0x06,
+ nvme_admin_abort_cmd = 0x08,
+ nvme_admin_set_features = 0x09,
+ nvme_admin_get_features = 0x0a,
+ nvme_admin_async_event = 0x0c,
+ nvme_admin_activate_fw = 0x10,
+ nvme_admin_download_fw = 0x11,
+ nvme_admin_format_nvm = 0x80,
+ nvme_admin_security_send = 0x81,
+ nvme_admin_security_recv = 0x82,
+};
+
+enum {
+ NVME_QUEUE_PHYS_CONTIG = (1 << 0),
+ NVME_CQ_IRQ_ENABLED = (1 << 1),
+ NVME_SQ_PRIO_URGENT = (0 << 1),
+ NVME_SQ_PRIO_HIGH = (1 << 1),
+ NVME_SQ_PRIO_MEDIUM = (2 << 1),
+ NVME_SQ_PRIO_LOW = (3 << 1),
+ NVME_FEAT_ARBITRATION = 0x01,
+ NVME_FEAT_POWER_MGMT = 0x02,
+ NVME_FEAT_LBA_RANGE = 0x03,
+ NVME_FEAT_TEMP_THRESH = 0x04,
+ NVME_FEAT_ERR_RECOVERY = 0x05,
+ NVME_FEAT_VOLATILE_WC = 0x06,
+ NVME_FEAT_NUM_QUEUES = 0x07,
+ NVME_FEAT_IRQ_COALESCE = 0x08,
+ NVME_FEAT_IRQ_CONFIG = 0x09,
+ NVME_FEAT_WRITE_ATOMIC = 0x0a,
+ NVME_FEAT_ASYNC_EVENT = 0x0b,
+ NVME_FEAT_AUTO_PST = 0x0c,
+ NVME_FEAT_SW_PROGRESS = 0x80,
+ NVME_FEAT_HOST_ID = 0x81,
+ NVME_FEAT_RESV_MASK = 0x82,
+ NVME_FEAT_RESV_PERSIST = 0x83,
+ NVME_LOG_ERROR = 0x01,
+ NVME_LOG_SMART = 0x02,
+ NVME_LOG_FW_SLOT = 0x03,
+ NVME_LOG_RESERVATION = 0x80,
+ NVME_FWACT_REPL = (0 << 3),
+ NVME_FWACT_REPL_ACTV = (1 << 3),
+ NVME_FWACT_ACTV = (2 << 3),
+};
+
+struct nvme_identify {
+ __u8 opcode;
+ __u8 flags;
+ __u16 command_id;
+ __le32 nsid;
+ __u64 rsvd2[2];
+ __le64 prp1;
+ __le64 prp2;
+ __le32 cns;
+ __u32 rsvd11[5];
+};
+
+struct nvme_features {
+ __u8 opcode;
+ __u8 flags;
+ __u16 command_id;
+ __le32 nsid;
+ __u64 rsvd2[2];
+ __le64 prp1;
+ __le64 prp2;
+ __le32 fid;
+ __le32 dword11;
+ __u32 rsvd12[4];
+};
+
+struct nvme_create_cq {
+ __u8 opcode;
+ __u8 flags;
+ __u16 command_id;
+ __u32 rsvd1[5];
+ __le64 prp1;
+ __u64 rsvd8;
+ __le16 cqid;
+ __le16 qsize;
+ __le16 cq_flags;
+ __le16 irq_vector;
+ __u32 rsvd12[4];
+};
+
+struct nvme_create_sq {
+ __u8 opcode;
+ __u8 flags;
+ __u16 command_id;
+ __u32 rsvd1[5];
+ __le64 prp1;
+ __u64 rsvd8;
+ __le16 sqid;
+ __le16 qsize;
+ __le16 sq_flags;
+ __le16 cqid;
+ __u32 rsvd12[4];
+};
+
+struct nvme_delete_queue {
+ __u8 opcode;
+ __u8 flags;
+ __u16 command_id;
+ __u32 rsvd1[9];
+ __le16 qid;
+ __u16 rsvd10;
+ __u32 rsvd11[5];
+};
+
+struct nvme_abort_cmd {
+ __u8 opcode;
+ __u8 flags;
+ __u16 command_id;
+ __u32 rsvd1[9];
+ __le16 sqid;
+ __u16 cid;
+ __u32 rsvd11[5];
+};
+
+struct nvme_download_firmware {
+ __u8 opcode;
+ __u8 flags;
+ __u16 command_id;
+ __u32 rsvd1[5];
+ __le64 prp1;
+ __le64 prp2;
+ __le32 numd;
+ __le32 offset;
+ __u32 rsvd12[4];
+};
+
+struct nvme_format_cmd {
+ __u8 opcode;
+ __u8 flags;
+ __u16 command_id;
+ __le32 nsid;
+ __u64 rsvd2[4];
+ __le32 cdw10;
+ __u32 rsvd11[5];
+};
+
+struct nvme_command {
+ union {
+ struct nvme_common_command common;
+ struct nvme_rw_command rw;
+ struct nvme_identify identify;
+ struct nvme_features features;
+ struct nvme_create_cq create_cq;
+ struct nvme_create_sq create_sq;
+ struct nvme_delete_queue delete_queue;
+ struct nvme_download_firmware dlfw;
+ struct nvme_format_cmd format;
+ struct nvme_dsm_cmd dsm;
+ struct nvme_abort_cmd abort;
+ };
+};
+
+enum {
+ NVME_SC_SUCCESS = 0x0,
+ NVME_SC_INVALID_OPCODE = 0x1,
+ NVME_SC_INVALID_FIELD = 0x2,
+ NVME_SC_CMDID_CONFLICT = 0x3,
+ NVME_SC_DATA_XFER_ERROR = 0x4,
+ NVME_SC_POWER_LOSS = 0x5,
+ NVME_SC_INTERNAL = 0x6,
+ NVME_SC_ABORT_REQ = 0x7,
+ NVME_SC_ABORT_QUEUE = 0x8,
+ NVME_SC_FUSED_FAIL = 0x9,
+ NVME_SC_FUSED_MISSING = 0xa,
+ NVME_SC_INVALID_NS = 0xb,
+ NVME_SC_CMD_SEQ_ERROR = 0xc,
+ NVME_SC_SGL_INVALID_LAST = 0xd,
+ NVME_SC_SGL_INVALID_COUNT = 0xe,
+ NVME_SC_SGL_INVALID_DATA = 0xf,
+ NVME_SC_SGL_INVALID_METADATA = 0x10,
+ NVME_SC_SGL_INVALID_TYPE = 0x11,
+ NVME_SC_LBA_RANGE = 0x80,
+ NVME_SC_CAP_EXCEEDED = 0x81,
+ NVME_SC_NS_NOT_READY = 0x82,
+ NVME_SC_RESERVATION_CONFLICT = 0x83,
+ NVME_SC_CQ_INVALID = 0x100,
+ NVME_SC_QID_INVALID = 0x101,
+ NVME_SC_QUEUE_SIZE = 0x102,
+ NVME_SC_ABORT_LIMIT = 0x103,
+ NVME_SC_ABORT_MISSING = 0x104,
+ NVME_SC_ASYNC_LIMIT = 0x105,
+ NVME_SC_FIRMWARE_SLOT = 0x106,
+ NVME_SC_FIRMWARE_IMAGE = 0x107,
+ NVME_SC_INVALID_VECTOR = 0x108,
+ NVME_SC_INVALID_LOG_PAGE = 0x109,
+ NVME_SC_INVALID_FORMAT = 0x10a,
+ NVME_SC_FIRMWARE_NEEDS_RESET = 0x10b,
+ NVME_SC_INVALID_QUEUE = 0x10c,
+ NVME_SC_FEATURE_NOT_SAVEABLE = 0x10d,
+ NVME_SC_FEATURE_NOT_CHANGEABLE = 0x10e,
+ NVME_SC_FEATURE_NOT_PER_NS = 0x10f,
+ NVME_SC_FW_NEEDS_RESET_SUBSYS = 0x110,
+ NVME_SC_BAD_ATTRIBUTES = 0x180,
+ NVME_SC_INVALID_PI = 0x181,
+ NVME_SC_READ_ONLY = 0x182,
+ NVME_SC_WRITE_FAULT = 0x280,
+ NVME_SC_READ_ERROR = 0x281,
+ NVME_SC_GUARD_CHECK = 0x282,
+ NVME_SC_APPTAG_CHECK = 0x283,
+ NVME_SC_REFTAG_CHECK = 0x284,
+ NVME_SC_COMPARE_FAILED = 0x285,
+ NVME_SC_ACCESS_DENIED = 0x286,
+ NVME_SC_DNR = 0x4000,
+};
+
+struct nvme_completion {
+ __le32 result; /* Used by admin commands to return data */
+ __u32 rsvd;
+ __le16 sq_head; /* how much of this queue may be reclaimed */
+ __le16 sq_id; /* submission queue that generated this entry */
+ __u16 command_id; /* of the command which completed */
+ __le16 status; /* did the command fail, and if so, why? */
+};
+
+struct nvme_user_io {
+ __u8 opcode;
+ __u8 flags;
+ __u16 control;
+ __u16 nblocks;
+ __u16 rsvd;
+ __u64 metadata;
+ __u64 addr;
+ __u64 slba;
+ __u32 dsmgmt;
+ __u32 reftag;
+ __u16 apptag;
+ __u16 appmask;
+};
+
+struct nvme_passthru_cmd {
+ __u8 opcode;
+ __u8 flags;
+ __u16 rsvd1;
+ __u32 nsid;
+ __u32 cdw2;
+ __u32 cdw3;
+ __u64 metadata;
+ __u64 addr;
+ __u32 metadata_len;
+ __u32 data_len;
+ __u32 cdw10;
+ __u32 cdw11;
+ __u32 cdw12;
+ __u32 cdw13;
+ __u32 cdw14;
+ __u32 cdw15;
+ __u32 timeout_ms;
+ __u32 result;
+};
+
+#define NVME_VS(major, minor) (((major) << 16) | ((minor) << 8))
+
+#define nvme_admin_cmd nvme_passthru_cmd
+
+#define NVME_IOCTL_ID _IO('N', 0x40)
+#define NVME_IOCTL_ADMIN_CMD _IOWR('N', 0x41, struct nvme_admin_cmd)
+#define NVME_IOCTL_SUBMIT_IO _IOW('N', 0x42, struct nvme_user_io)
+#define NVME_IOCTL_IO_CMD _IOWR('N', 0x43, struct nvme_passthru_cmd)
diff --git a/include/blk.h b/include/blk.h
index 66a1c55..7f1e573 100644
--- a/include/blk.h
+++ b/include/blk.h
@@ -31,6 +31,7 @@ enum if_type {
IF_TYPE_SATA,
IF_TYPE_HOST,
IF_TYPE_SYSTEMACE,
+ IF_TYPE_NVME,
IF_TYPE_COUNT, /* Number of interface types */
};
diff --git a/include/nvme.h b/include/nvme.h
new file mode 100644
index 0000000..3f8f94f
--- /dev/null
+++ b/include/nvme.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2017 NXP Semiconductors
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef __NVME_H__
+#define __NVME_H__
+#include <part.h>
+
+#ifdef CONFIG_BLK
+int init_nvme(struct udevice *udev);
+int scan_nvme(struct udevice *udev);
+ulong nvme_read(struct udevice *udev, ulong blknr, lbaint_t blkcnt,
+ void *buffer);
+ulong nvme_write(struct udevice *udev, ulong blknr, lbaint_t blkcnt,
+ const void *buffer);
+#else
+int init_nvme(int devnum);
+int scan_nvme(int devnum);
+ulong nvme_read(int devnum, ulong blknr, lbaint_t blkcnt,
+ void *buffer);
+ulong nvme_write(int devnum, ulong blknr, lbaint_t blkcnt,
+ const void *buffer);
+#endif
+int nvme_print_info(int devnum);
+int nvme_initialize(void);
+int __nvme_initialize(void);
+
+extern struct blk_desc nvme_dev_desc[];
+
+/*
+ * An NVM Express namespace is equivalent to a SCSI LUN
+ * Each namespace is operated as an independent "device".
+ */
+struct nvme_ns {
+ struct list_head list;
+ struct nvme_dev *dev;
+ unsigned ns_id;
+ int devnum;
+ int lba_shift;
+ u16 ms;
+ u8 flbas;
+ u8 pi_type;
+ u64 mode_select_num_blocks;
+ u32 mode_select_block_len;
+};
+
+extern struct pci_device_id nvme_supported[];
+#endif
--
2.1.0.27.g96db324
3
6

13 Apr '17
The purpose of patch set is to convert the board to support device
tree and driver model, and enable the early debug UART as well.
It is based on the patch set:
[PATCH v8 0/2] pinctrl: at91: Add pinctrl driver
https://lists.denx.de/pipermail/u-boot/2017-March/284577.html
Changes in v4:
- Convert the macb to support DM and clean up macb init code.
- Remain the SPI speed macros.
- Update the config options for SPL.
- Update the commit log.
- Remove the unneeded dbgu init during board_early_init_f stage.
- Use CONFIG_DEBUG_UART_CLOCK as the input clock for the early
debug uart.
- Drop [PATCH] configs: sama5d4: move CONFIG_SYS_NO_FLASH to *defconfig
- Rebase on v2017.03.
Changes in v3:
- add the Reviewed-by tags.
- rebase on the patch:
[PATCH v2] ARM: dts: at91: add device tree files for at91sam9x5ek
http://lists.denx.de/pipermail/u-boot/2017-February/280504.html
Changes in v2:
- Restore the wrong removal #define CONFIG_USB_ETHER.
- Update the commit log.
- Restore the wrong removal of USB related code.
- Update the commit log.
- Restore wrong removal of #define CONFIG_USB_ETHER.
- Update the commit log.
- Restore the wrong removal USB related code.
- Update the commit log.
Wenyou Yang (7):
configs: at91-sama5_common: fix for CONFIG_AT91_GPIO
board: sama5d4_xplained: update to support DM/DT
board: sama5d4_xplained: clean up code
board: sama5d4_xplained: enable early debug UART
board: sama5d4ek: update to support DM/DT
board: sama5d4ek: clean up code
board: sama5d4ek: enable early debug UART
board/atmel/sama5d4_xplained/sama5d4_xplained.c | 145 +++---------------------
board/atmel/sama5d4ek/sama5d4ek.c | 145 +++---------------------
configs/sama5d4_xplained_mmc_defconfig | 37 +++++-
configs/sama5d4_xplained_nandflash_defconfig | 36 +++++-
configs/sama5d4_xplained_spiflash_defconfig | 37 +++++-
configs/sama5d4ek_mmc_defconfig | 37 ++++++
configs/sama5d4ek_nandflash_defconfig | 38 ++++++-
configs/sama5d4ek_spiflash_defconfig | 38 ++++++-
include/configs/at91-sama5_common.h | 2 +
include/configs/sama5d4_xplained.h | 45 +-------
include/configs/sama5d4ek.h | 45 +-------
11 files changed, 253 insertions(+), 352 deletions(-)
--
2.11.0
3
14

[U-Boot] [PATCH v6 1/3] arm: dts: update Meson GXBB / Odroid-C2 DT with latest Linux version
by Heiner Kallweit 13 Apr '17
by Heiner Kallweit 13 Apr '17
13 Apr '17
As a prerequisite for adding a Meson GX MMC driver update the
Meson GXBB / Odroid-C2 device tree in Uboot with the latest
version from Linux.
Signed-off-by: Neil Armstrong <narmstrong(a)baylibre.com>
Signed-off-by: Carlo Caione <carlo(a)endlessm.com>
Signed-off-by: Andreas Färber <afaerber(a)suse.de>
Signed-off-by: Heiner Kallweit <hkallweit1(a)gmail.com>
---
v4:
- Added SoB of original authors
v5:
- no changes
v6:
- changed prefix in subject
---
arch/arm/dts/meson-gx.dtsi | 447 ++++++++++++++++++++
arch/arm/dts/meson-gxbb-odroidc2.dts | 147 ++++++-
arch/arm/dts/meson-gxbb.dtsi | 718 ++++++++++++++++++++------------
include/dt-bindings/clock/gxbb-aoclkc.h | 66 +++
include/dt-bindings/clock/gxbb-clkc.h | 34 ++
include/dt-bindings/reset/gxbb-aoclkc.h | 66 +++
6 files changed, 1203 insertions(+), 275 deletions(-)
create mode 100644 arch/arm/dts/meson-gx.dtsi
create mode 100644 include/dt-bindings/clock/gxbb-aoclkc.h
create mode 100644 include/dt-bindings/clock/gxbb-clkc.h
create mode 100644 include/dt-bindings/reset/gxbb-aoclkc.h
diff --git a/arch/arm/dts/meson-gx.dtsi b/arch/arm/dts/meson-gx.dtsi
new file mode 100644
index 0000000..c129100
--- /dev/null
+++ b/arch/arm/dts/meson-gx.dtsi
@@ -0,0 +1,447 @@
+/*
+ * Copyright (c) 2016 Andreas Färber
+ *
+ * Copyright (c) 2016 BayLibre, SAS.
+ * Author: Neil Armstrong <narmstrong(a)baylibre.com>
+ *
+ * Copyright (c) 2016 Endless Computers, Inc.
+ * Author: Carlo Caione <carlo(a)endlessm.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) This library 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 library 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.
+ *
+ * Or, alternatively,
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+/ {
+ interrupt-parent = <&gic>;
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ reserved-memory {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ /* 16 MiB reserved for Hardware ROM Firmware */
+ hwrom_reserved: hwrom@0 {
+ reg = <0x0 0x0 0x0 0x1000000>;
+ no-map;
+ };
+
+ /* 2 MiB reserved for ARM Trusted Firmware (BL31) */
+ secmon_reserved: secmon@10000000 {
+ reg = <0x0 0x10000000 0x0 0x200000>;
+ no-map;
+ };
+ };
+
+ cpus {
+ #address-cells = <0x2>;
+ #size-cells = <0x0>;
+
+ cpu0: cpu@0 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a53", "arm,armv8";
+ reg = <0x0 0x0>;
+ enable-method = "psci";
+ next-level-cache = <&l2>;
+ clocks = <&scpi_dvfs 0>;
+ };
+
+ cpu1: cpu@1 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a53", "arm,armv8";
+ reg = <0x0 0x1>;
+ enable-method = "psci";
+ next-level-cache = <&l2>;
+ clocks = <&scpi_dvfs 0>;
+ };
+
+ cpu2: cpu@2 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a53", "arm,armv8";
+ reg = <0x0 0x2>;
+ enable-method = "psci";
+ next-level-cache = <&l2>;
+ clocks = <&scpi_dvfs 0>;
+ };
+
+ cpu3: cpu@3 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a53", "arm,armv8";
+ reg = <0x0 0x3>;
+ enable-method = "psci";
+ next-level-cache = <&l2>;
+ clocks = <&scpi_dvfs 0>;
+ };
+
+ l2: l2-cache0 {
+ compatible = "cache";
+ };
+ };
+
+ arm-pmu {
+ compatible = "arm,cortex-a53-pmu";
+ interrupts = <GIC_SPI 137 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 138 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 153 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 154 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-affinity = <&cpu0>, <&cpu1>, <&cpu2>, <&cpu3>;
+ };
+
+ psci {
+ compatible = "arm,psci-0.2";
+ method = "smc";
+ };
+
+ timer {
+ compatible = "arm,armv8-timer";
+ interrupts = <GIC_PPI 13
+ (GIC_CPU_MASK_RAW(0xff) | IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 14
+ (GIC_CPU_MASK_RAW(0xff) | IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 11
+ (GIC_CPU_MASK_RAW(0xff) | IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 10
+ (GIC_CPU_MASK_RAW(0xff) | IRQ_TYPE_LEVEL_LOW)>;
+ };
+
+ xtal: xtal-clk {
+ compatible = "fixed-clock";
+ clock-frequency = <24000000>;
+ clock-output-names = "xtal";
+ #clock-cells = <0>;
+ };
+
+ firmware {
+ sm: secure-monitor {
+ compatible = "amlogic,meson-gx-sm", "amlogic,meson-gxbb-sm";
+ };
+ };
+
+ efuse: efuse {
+ compatible = "amlogic,meson-gx-efuse", "amlogic,meson-gxbb-efuse";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ sn: sn@14 {
+ reg = <0x14 0x10>;
+ };
+
+ eth_mac: eth_mac@34 {
+ reg = <0x34 0x10>;
+ };
+
+ bid: bid@46 {
+ reg = <0x46 0x30>;
+ };
+ };
+
+ scpi {
+ compatible = "amlogic,meson-gxbb-scpi", "arm,scpi-pre-1.0";
+ mboxes = <&mailbox 1 &mailbox 2>;
+ shmem = <&cpu_scp_lpri &cpu_scp_hpri>;
+
+ scpi_clocks: clocks {
+ compatible = "arm,scpi-clocks";
+
+ scpi_dvfs: scpi_clocks@0 {
+ compatible = "arm,scpi-dvfs-clocks";
+ #clock-cells = <1>;
+ clock-indices = <0>;
+ clock-output-names = "vcpu";
+ };
+ };
+
+ scpi_sensors: sensors {
+ compatible = "arm,scpi-sensors";
+ #thermal-sensor-cells = <1>;
+ };
+ };
+
+ soc {
+ compatible = "simple-bus";
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ cbus: cbus@c1100000 {
+ compatible = "simple-bus";
+ reg = <0x0 0xc1100000 0x0 0x100000>;
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges = <0x0 0x0 0x0 0xc1100000 0x0 0x100000>;
+
+ reset: reset-controller@4404 {
+ compatible = "amlogic,meson-gx-reset", "amlogic,meson-gxbb-reset";
+ reg = <0x0 0x04404 0x0 0x20>;
+ #reset-cells = <1>;
+ };
+
+ uart_A: serial@84c0 {
+ compatible = "amlogic,meson-uart";
+ reg = <0x0 0x84c0 0x0 0x14>;
+ interrupts = <GIC_SPI 26 IRQ_TYPE_EDGE_RISING>;
+ clocks = <&xtal>;
+ status = "disabled";
+ };
+
+ uart_B: serial@84dc {
+ compatible = "amlogic,meson-uart";
+ reg = <0x0 0x84dc 0x0 0x14>;
+ interrupts = <GIC_SPI 75 IRQ_TYPE_EDGE_RISING>;
+ clocks = <&xtal>;
+ status = "disabled";
+ };
+
+ i2c_A: i2c@8500 {
+ compatible = "amlogic,meson-gxbb-i2c";
+ reg = <0x0 0x08500 0x0 0x20>;
+ interrupts = <GIC_SPI 21 IRQ_TYPE_EDGE_RISING>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ pwm_ab: pwm@8550 {
+ compatible = "amlogic,meson-gx-pwm", "amlogic,meson-gxbb-pwm";
+ reg = <0x0 0x08550 0x0 0x10>;
+ #pwm-cells = <3>;
+ status = "disabled";
+ };
+
+ pwm_cd: pwm@8650 {
+ compatible = "amlogic,meson-gx-pwm", "amlogic,meson-gxbb-pwm";
+ reg = <0x0 0x08650 0x0 0x10>;
+ #pwm-cells = <3>;
+ status = "disabled";
+ };
+
+ pwm_ef: pwm@86c0 {
+ compatible = "amlogic,meson-gx-pwm", "amlogic,meson-gxbb-pwm";
+ reg = <0x0 0x086c0 0x0 0x10>;
+ #pwm-cells = <3>;
+ status = "disabled";
+ };
+
+ uart_C: serial@8700 {
+ compatible = "amlogic,meson-uart";
+ reg = <0x0 0x8700 0x0 0x14>;
+ interrupts = <GIC_SPI 93 IRQ_TYPE_EDGE_RISING>;
+ clocks = <&xtal>;
+ status = "disabled";
+ };
+
+ i2c_B: i2c@87c0 {
+ compatible = "amlogic,meson-gxbb-i2c";
+ reg = <0x0 0x087c0 0x0 0x20>;
+ interrupts = <GIC_SPI 214 IRQ_TYPE_EDGE_RISING>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ i2c_C: i2c@87e0 {
+ compatible = "amlogic,meson-gxbb-i2c";
+ reg = <0x0 0x087e0 0x0 0x20>;
+ interrupts = <GIC_SPI 215 IRQ_TYPE_EDGE_RISING>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ watchdog@98d0 {
+ compatible = "amlogic,meson-gx-wdt", "amlogic,meson-gxbb-wdt";
+ reg = <0x0 0x098d0 0x0 0x10>;
+ clocks = <&xtal>;
+ };
+ };
+
+ gic: interrupt-controller@c4301000 {
+ compatible = "arm,gic-400";
+ reg = <0x0 0xc4301000 0 0x1000>,
+ <0x0 0xc4302000 0 0x2000>,
+ <0x0 0xc4304000 0 0x2000>,
+ <0x0 0xc4306000 0 0x2000>;
+ interrupt-controller;
+ interrupts = <GIC_PPI 9
+ (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_HIGH)>;
+ #interrupt-cells = <3>;
+ #address-cells = <0>;
+ };
+
+ sram: sram@c8000000 {
+ compatible = "amlogic,meson-gxbb-sram", "mmio-sram";
+ reg = <0x0 0xc8000000 0x0 0x14000>;
+
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0 0x0 0xc8000000 0x14000>;
+
+ cpu_scp_lpri: scp-shmem@0 {
+ compatible = "amlogic,meson-gxbb-scp-shmem";
+ reg = <0x13000 0x400>;
+ };
+
+ cpu_scp_hpri: scp-shmem@200 {
+ compatible = "amlogic,meson-gxbb-scp-shmem";
+ reg = <0x13400 0x400>;
+ };
+ };
+
+ aobus: aobus@c8100000 {
+ compatible = "simple-bus";
+ reg = <0x0 0xc8100000 0x0 0x100000>;
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges = <0x0 0x0 0x0 0xc8100000 0x0 0x100000>;
+
+ uart_AO: serial@4c0 {
+ compatible = "amlogic,meson-uart";
+ reg = <0x0 0x004c0 0x0 0x14>;
+ interrupts = <GIC_SPI 193 IRQ_TYPE_EDGE_RISING>;
+ clocks = <&xtal>;
+ status = "disabled";
+ };
+
+ uart_AO_B: serial@4e0 {
+ compatible = "amlogic,meson-uart";
+ reg = <0x0 0x004e0 0x0 0x14>;
+ interrupts = <GIC_SPI 197 IRQ_TYPE_EDGE_RISING>;
+ clocks = <&xtal>;
+ status = "disabled";
+ };
+
+ ir: ir@580 {
+ compatible = "amlogic,meson-gxbb-ir";
+ reg = <0x0 0x00580 0x0 0x40>;
+ interrupts = <GIC_SPI 196 IRQ_TYPE_EDGE_RISING>;
+ status = "disabled";
+ };
+ };
+
+ periphs: periphs@c8834000 {
+ compatible = "simple-bus";
+ reg = <0x0 0xc8834000 0x0 0x2000>;
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges = <0x0 0x0 0x0 0xc8834000 0x0 0x2000>;
+
+ rng {
+ compatible = "amlogic,meson-rng";
+ reg = <0x0 0x0 0x0 0x4>;
+ };
+ };
+
+
+ hiubus: hiubus@c883c000 {
+ compatible = "simple-bus";
+ reg = <0x0 0xc883c000 0x0 0x2000>;
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges = <0x0 0x0 0x0 0xc883c000 0x0 0x2000>;
+
+ mailbox: mailbox@404 {
+ compatible = "amlogic,meson-gx-mhu", "amlogic,meson-gxbb-mhu";
+ reg = <0 0x404 0 0x4c>;
+ interrupts = <0 208 IRQ_TYPE_EDGE_RISING>,
+ <0 209 IRQ_TYPE_EDGE_RISING>,
+ <0 210 IRQ_TYPE_EDGE_RISING>;
+ #mbox-cells = <1>;
+ };
+ };
+
+ ethmac: ethernet@c9410000 {
+ compatible = "amlogic,meson-gx-dwmac", "amlogic,meson-gxbb-dwmac", "snps,dwmac";
+ reg = <0x0 0xc9410000 0x0 0x10000
+ 0x0 0xc8834540 0x0 0x4>;
+ interrupts = <0 8 1>;
+ interrupt-names = "macirq";
+ phy-mode = "rgmii";
+ status = "disabled";
+ };
+
+ apb: apb@d0000000 {
+ compatible = "simple-bus";
+ reg = <0x0 0xd0000000 0x0 0x200000>;
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges = <0x0 0x0 0x0 0xd0000000 0x0 0x200000>;
+
+ sd_emmc_a: mmc@70000 {
+ compatible = "amlogic,meson-gx-mmc", "amlogic,meson-gxbb-mmc";
+ reg = <0x0 0x70000 0x0 0x2000>;
+ interrupts = <GIC_SPI 216 IRQ_TYPE_EDGE_RISING>;
+ status = "disabled";
+ };
+
+ sd_emmc_b: mmc@72000 {
+ compatible = "amlogic,meson-gx-mmc", "amlogic,meson-gxbb-mmc";
+ reg = <0x0 0x72000 0x0 0x2000>;
+ interrupts = <GIC_SPI 217 IRQ_TYPE_EDGE_RISING>;
+ status = "disabled";
+ };
+
+ sd_emmc_c: mmc@74000 {
+ compatible = "amlogic,meson-gx-mmc", "amlogic,meson-gxbb-mmc";
+ reg = <0x0 0x74000 0x0 0x2000>;
+ interrupts = <GIC_SPI 218 IRQ_TYPE_EDGE_RISING>;
+ status = "disabled";
+ };
+ };
+
+ vpu: vpu@d0100000 {
+ compatible = "amlogic,meson-gx-vpu";
+ reg = <0x0 0xd0100000 0x0 0x100000>,
+ <0x0 0xc883c000 0x0 0x1000>,
+ <0x0 0xc8838000 0x0 0x1000>;
+ reg-names = "vpu", "hhi", "dmc";
+ interrupts = <GIC_SPI 3 IRQ_TYPE_EDGE_RISING>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ /* CVBS VDAC output port */
+ cvbs_vdac_port: port@0 {
+ reg = <0>;
+ };
+ };
+ };
+};
diff --git a/arch/arm/dts/meson-gxbb-odroidc2.dts b/arch/arm/dts/meson-gxbb-odroidc2.dts
index 79bee64..c737183 100644
--- a/arch/arm/dts/meson-gxbb-odroidc2.dts
+++ b/arch/arm/dts/meson-gxbb-odroidc2.dts
@@ -64,6 +64,18 @@
reg = <0x0 0x0 0x0 0x80000000>;
};
+ usb_otg_pwr: regulator-usb-pwrs {
+ compatible = "regulator-fixed";
+
+ regulator-name = "USB_OTG_PWR";
+
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+
+ gpio = <&gpio_ao GPIOAO_5 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
leds {
compatible = "gpio-leds";
blue {
@@ -73,6 +85,60 @@
default-state = "off";
};
};
+
+ tflash_vdd: regulator-tflash_vdd {
+ /*
+ * signal name from schematics: TFLASH_VDD_EN
+ */
+ compatible = "regulator-fixed";
+
+ regulator-name = "TFLASH_VDD";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+
+ gpio = <&gpio_ao GPIOAO_12 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
+ tf_io: gpio-regulator-tf_io {
+ compatible = "regulator-gpio";
+
+ regulator-name = "TF_IO";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+
+ /*
+ * signal name from schematics: TF_3V3N_1V8_EN
+ */
+ gpios = <&gpio_ao GPIOAO_3 GPIO_ACTIVE_HIGH>;
+ gpios-states = <0>;
+
+ states = <3300000 0
+ 1800000 1>;
+ };
+
+ vcc1v8: regulator-vcc1v8 {
+ compatible = "regulator-fixed";
+ regulator-name = "VCC1V8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ vcc3v3: regulator-vcc3v3 {
+ compatible = "regulator-fixed";
+ regulator-name = "VCC3V3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ emmc_pwrseq: emmc-pwrseq {
+ compatible = "mmc-pwrseq-emmc";
+ reset-gpios = <&gpio BOOT_9 GPIO_ACTIVE_LOW>;
+ };
+};
+
+&scpi_clocks {
+ status = "disabled";
};
&uart_AO {
@@ -83,6 +149,85 @@
ðmac {
status = "okay";
- pinctrl-0 = <ð_pins>;
+ pinctrl-0 = <ð_rgmii_pins>;
+ pinctrl-names = "default";
+ phy-handle = <ð_phy0>;
+
+ mdio {
+ compatible = "snps,dwmac-mdio";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ eth_phy0: ethernet-phy@0 {
+ reg = <0>;
+ eee-broken-1000t;
+ };
+ };
+};
+
+&ir {
+ status = "okay";
+ pinctrl-0 = <&remote_input_ao_pins>;
pinctrl-names = "default";
};
+
+&i2c_A {
+ status = "okay";
+ pinctrl-0 = <&i2c_a_pins>;
+ pinctrl-names = "default";
+};
+
+&usb0_phy {
+ status = "okay";
+ phy-supply = <&usb_otg_pwr>;
+};
+
+&usb1_phy {
+ status = "okay";
+};
+
+&usb0 {
+ status = "okay";
+};
+
+&usb1 {
+ status = "okay";
+};
+
+/* SD */
+&sd_emmc_b {
+ status = "okay";
+ pinctrl-0 = <&sdcard_pins>;
+ pinctrl-names = "default";
+
+ bus-width = <4>;
+ cap-sd-highspeed;
+ max-frequency = <100000000>;
+ disable-wp;
+
+ cd-gpios = <&gpio CARD_6 GPIO_ACTIVE_HIGH>;
+ cd-inverted;
+
+ vmmc-supply = <&tflash_vdd>;
+ vqmmc-supply = <&tf_io>;
+};
+
+/* eMMC */
+&sd_emmc_c {
+ status = "okay";
+ pinctrl-0 = <&emmc_pins>;
+ pinctrl-names = "default";
+
+ bus-width = <8>;
+ cap-sd-highspeed;
+ max-frequency = <200000000>;
+ non-removable;
+ disable-wp;
+ cap-mmc-highspeed;
+ mmc-ddr-1_8v;
+ mmc-hs200-1_8v;
+
+ mmc-pwrseq = <&emmc_pwrseq>;
+ vmmc-supply = <&vcc3v3>;
+ vqmmc-supply = <&vcc1v8>;
+};
diff --git a/arch/arm/dts/meson-gxbb.dtsi b/arch/arm/dts/meson-gxbb.dtsi
index e502c24..39a774a 100644
--- a/arch/arm/dts/meson-gxbb.dtsi
+++ b/arch/arm/dts/meson-gxbb.dtsi
@@ -40,307 +40,477 @@
* OTHER DEALINGS IN THE SOFTWARE.
*/
-#include <dt-bindings/gpio/gpio.h>
-#include <dt-bindings/interrupt-controller/irq.h>
-#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include "meson-gx.dtsi"
#include <dt-bindings/gpio/meson-gxbb-gpio.h>
#include <dt-bindings/reset/amlogic,meson-gxbb-reset.h>
+#include <dt-bindings/clock/gxbb-clkc.h>
+#include <dt-bindings/clock/gxbb-aoclkc.h>
+#include <dt-bindings/reset/gxbb-aoclkc.h>
/ {
compatible = "amlogic,meson-gxbb";
- interrupt-parent = <&gic>;
- #address-cells = <2>;
- #size-cells = <2>;
- cpus {
- #address-cells = <0x2>;
- #size-cells = <0x0>;
-
- cpu0: cpu@0 {
- device_type = "cpu";
- compatible = "arm,cortex-a53", "arm,armv8";
- reg = <0x0 0x0>;
- enable-method = "psci";
+ soc {
+ usb0_phy: phy@c0000000 {
+ compatible = "amlogic,meson-gxbb-usb2-phy";
+ #phy-cells = <0>;
+ reg = <0x0 0xc0000000 0x0 0x20>;
+ resets = <&reset RESET_USB_OTG>;
+ clocks = <&clkc CLKID_USB>, <&clkc CLKID_USB0>;
+ clock-names = "usb_general", "usb";
+ status = "disabled";
};
- cpu1: cpu@1 {
- device_type = "cpu";
- compatible = "arm,cortex-a53", "arm,armv8";
- reg = <0x0 0x1>;
- enable-method = "psci";
+ usb1_phy: phy@c0000020 {
+ compatible = "amlogic,meson-gxbb-usb2-phy";
+ #phy-cells = <0>;
+ reg = <0x0 0xc0000020 0x0 0x20>;
+ resets = <&reset RESET_USB_OTG>;
+ clocks = <&clkc CLKID_USB>, <&clkc CLKID_USB1>;
+ clock-names = "usb_general", "usb";
+ status = "disabled";
};
- cpu2: cpu@2 {
- device_type = "cpu";
- compatible = "arm,cortex-a53", "arm,armv8";
- reg = <0x0 0x2>;
- enable-method = "psci";
+ usb0: usb@c9000000 {
+ compatible = "amlogic,meson-gxbb-usb", "snps,dwc2";
+ reg = <0x0 0xc9000000 0x0 0x40000>;
+ interrupts = <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clkc CLKID_USB0_DDR_BRIDGE>;
+ clock-names = "otg";
+ phys = <&usb0_phy>;
+ phy-names = "usb2-phy";
+ dr_mode = "host";
+ status = "disabled";
};
- cpu3: cpu@3 {
- device_type = "cpu";
- compatible = "arm,cortex-a53", "arm,armv8";
- reg = <0x0 0x3>;
- enable-method = "psci";
+ usb1: usb@c9100000 {
+ compatible = "amlogic,meson-gxbb-usb", "snps,dwc2";
+ reg = <0x0 0xc9100000 0x0 0x40000>;
+ interrupts = <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clkc CLKID_USB1_DDR_BRIDGE>;
+ clock-names = "otg";
+ phys = <&usb1_phy>;
+ phy-names = "usb2-phy";
+ dr_mode = "host";
+ status = "disabled";
};
};
+};
- arm-pmu {
- compatible = "arm,cortex-a53-pmu";
- interrupts = <GIC_SPI 137 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 138 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 153 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 154 IRQ_TYPE_LEVEL_HIGH>;
- interrupt-affinity = <&cpu0>, <&cpu1>, <&cpu2>, <&cpu3>;
+&cbus {
+ spifc: spi@8c80 {
+ compatible = "amlogic,meson-gxbb-spifc";
+ reg = <0x0 0x08c80 0x0 0x80>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&clkc CLKID_SPI>;
+ status = "disabled";
};
+};
+
+ðmac {
+ clocks = <&clkc CLKID_ETH>,
+ <&clkc CLKID_FCLK_DIV2>,
+ <&clkc CLKID_MPLL2>;
+ clock-names = "stmmaceth", "clkin0", "clkin1";
+};
+
+&aobus {
+ pinctrl_aobus: pinctrl@14 {
+ compatible = "amlogic,meson-gxbb-aobus-pinctrl";
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ gpio_ao: bank@14 {
+ reg = <0x0 0x00014 0x0 0x8>,
+ <0x0 0x0002c 0x0 0x4>,
+ <0x0 0x00024 0x0 0x8>;
+ reg-names = "mux", "pull", "gpio";
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ uart_ao_a_pins: uart_ao_a {
+ mux {
+ groups = "uart_tx_ao_a", "uart_rx_ao_a";
+ function = "uart_ao";
+ };
+ };
+
+ uart_ao_a_cts_rts_pins: uart_ao_a_cts_rts {
+ mux {
+ groups = "uart_cts_ao_a",
+ "uart_rts_ao_a";
+ function = "uart_ao";
+ };
+ };
+
+ uart_ao_b_pins: uart_ao_b {
+ mux {
+ groups = "uart_tx_ao_b", "uart_rx_ao_b";
+ function = "uart_ao_b";
+ };
+ };
+
+ uart_ao_b_cts_rts_pins: uart_ao_b_cts_rts {
+ mux {
+ groups = "uart_cts_ao_b",
+ "uart_rts_ao_b";
+ function = "uart_ao_b";
+ };
+ };
- psci {
- compatible = "arm,psci-0.2";
- method = "smc";
+ remote_input_ao_pins: remote_input_ao {
+ mux {
+ groups = "remote_input_ao";
+ function = "remote_input_ao";
+ };
+ };
+
+ i2c_ao_pins: i2c_ao {
+ mux {
+ groups = "i2c_sck_ao",
+ "i2c_sda_ao";
+ function = "i2c_ao";
+ };
+ };
+
+ pwm_ao_a_3_pins: pwm_ao_a_3 {
+ mux {
+ groups = "pwm_ao_a_3";
+ function = "pwm_ao_a_3";
+ };
+ };
+
+ pwm_ao_a_6_pins: pwm_ao_a_6 {
+ mux {
+ groups = "pwm_ao_a_6";
+ function = "pwm_ao_a_6";
+ };
+ };
+
+ pwm_ao_a_12_pins: pwm_ao_a_12 {
+ mux {
+ groups = "pwm_ao_a_12";
+ function = "pwm_ao_a_12";
+ };
+ };
+
+ pwm_ao_b_pins: pwm_ao_b {
+ mux {
+ groups = "pwm_ao_b";
+ function = "pwm_ao_b";
+ };
+ };
};
- timer {
- compatible = "arm,armv8-timer";
- interrupts = <GIC_PPI 13
- (GIC_CPU_MASK_RAW(0xff) | IRQ_TYPE_EDGE_RISING)>,
- <GIC_PPI 14
- (GIC_CPU_MASK_RAW(0xff) | IRQ_TYPE_EDGE_RISING)>,
- <GIC_PPI 11
- (GIC_CPU_MASK_RAW(0xff) | IRQ_TYPE_EDGE_RISING)>,
- <GIC_PPI 10
- (GIC_CPU_MASK_RAW(0xff) | IRQ_TYPE_EDGE_RISING)>;
+ clkc_AO: clock-controller@040 {
+ compatible = "amlogic,gxbb-aoclkc";
+ reg = <0x0 0x00040 0x0 0x4>;
+ #clock-cells = <1>;
+ #reset-cells = <1>;
};
- xtal: xtal-clk {
- compatible = "fixed-clock";
- clock-frequency = <24000000>;
- clock-output-names = "xtal";
- #clock-cells = <0>;
+ pwm_ab_AO: pwm@550 {
+ compatible = "amlogic,meson-gxbb-pwm";
+ reg = <0x0 0x0550 0x0 0x10>;
+ #pwm-cells = <3>;
+ status = "disabled";
};
- soc {
- compatible = "simple-bus";
+ i2c_AO: i2c@500 {
+ compatible = "amlogic,meson-gxbb-i2c";
+ reg = <0x0 0x500 0x0 0x20>;
+ interrupts = <GIC_SPI 195 IRQ_TYPE_EDGE_RISING>;
+ clocks = <&clkc CLKID_AO_I2C>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+};
+
+&periphs {
+ pinctrl_periphs: pinctrl@4b0 {
+ compatible = "amlogic,meson-gxbb-periphs-pinctrl";
#address-cells = <2>;
#size-cells = <2>;
ranges;
- cbus: cbus@c1100000 {
- compatible = "simple-bus";
- reg = <0x0 0xc1100000 0x0 0x100000>;
- #address-cells = <2>;
- #size-cells = <2>;
- ranges = <0x0 0x0 0x0 0xc1100000 0x0 0x100000>;
-
- reset: reset-controller@4404 {
- compatible = "amlogic,meson-gxbb-reset";
- reg = <0x0 0x04404 0x0 0x20>;
- #reset-cells = <1>;
- };
-
- uart_A: serial@84c0 {
- compatible = "amlogic,meson-uart";
- reg = <0x0 0x84c0 0x0 0x14>;
- interrupts = <GIC_SPI 26 IRQ_TYPE_EDGE_RISING>;
- clocks = <&xtal>;
- status = "disabled";
- };
-
- uart_B: serial@84dc {
- compatible = "amlogic,meson-uart";
- reg = <0x0 0x84dc 0x0 0x14>;
- interrupts = <GIC_SPI 75 IRQ_TYPE_EDGE_RISING>;
- clocks = <&xtal>;
- status = "disabled";
- };
-
- uart_C: serial@8700 {
- compatible = "amlogic,meson-uart";
- reg = <0x0 0x8700 0x0 0x14>;
- interrupts = <GIC_SPI 93 IRQ_TYPE_EDGE_RISING>;
- clocks = <&xtal>;
- status = "disabled";
- };
- };
-
- gic: interrupt-controller@c4301000 {
- compatible = "arm,gic-400";
- reg = <0x0 0xc4301000 0 0x1000>,
- <0x0 0xc4302000 0 0x2000>,
- <0x0 0xc4304000 0 0x2000>,
- <0x0 0xc4306000 0 0x2000>;
- interrupt-controller;
- interrupts = <GIC_PPI 9
- (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_HIGH)>;
- #interrupt-cells = <3>;
- #address-cells = <0>;
- };
-
- aobus: aobus@c8100000 {
- compatible = "simple-bus";
- reg = <0x0 0xc8100000 0x0 0x100000>;
- #address-cells = <2>;
- #size-cells = <2>;
- ranges = <0x0 0x0 0x0 0xc8100000 0x0 0x100000>;
-
- pinctrl_aobus: pinctrl@14 {
- compatible = "amlogic,meson-gxbb-aobus-pinctrl";
- #address-cells = <2>;
- #size-cells = <2>;
- ranges;
-
- gpio_ao: bank@14 {
- reg = <0x0 0x00014 0x0 0x8>,
- <0x0 0x0002c 0x0 0x4>,
- <0x0 0x00024 0x0 0x8>;
- reg-names = "mux", "pull", "gpio";
- gpio-controller;
- #gpio-cells = <2>;
- };
-
- uart_ao_a_pins: uart_ao_a {
- mux {
- groups = "uart_tx_ao_a", "uart_rx_ao_a";
- function = "uart_ao";
- };
- };
- };
-
- uart_AO: serial@4c0 {
- compatible = "amlogic,meson-uart";
- reg = <0x0 0x004c0 0x0 0x14>;
- interrupts = <GIC_SPI 193 IRQ_TYPE_EDGE_RISING>;
- clocks = <&xtal>;
- status = "disabled";
- };
- };
-
- periphs: periphs@c8834000 {
- compatible = "simple-bus";
- reg = <0x0 0xc8834000 0x0 0x2000>;
- #address-cells = <2>;
- #size-cells = <2>;
- ranges = <0x0 0x0 0x0 0xc8834000 0x0 0x2000>;
-
- rng {
- compatible = "amlogic,meson-rng";
- reg = <0x0 0x0 0x0 0x4>;
- };
-
- pinctrl_periphs: pinctrl@4b0 {
- compatible = "amlogic,meson-gxbb-periphs-pinctrl";
- #address-cells = <2>;
- #size-cells = <2>;
- ranges;
-
- gpio: bank@4b0 {
- reg = <0x0 0x004b0 0x0 0x28>,
- <0x0 0x004e8 0x0 0x14>,
- <0x0 0x00120 0x0 0x14>,
- <0x0 0x00430 0x0 0x40>;
- reg-names = "mux", "pull", "pull-enable", "gpio";
- gpio-controller;
- #gpio-cells = <2>;
- };
-
- emmc_pins: emmc {
- mux {
- groups = "emmc_nand_d07",
- "emmc_cmd",
- "emmc_clk";
- function = "emmc";
- };
- };
-
- sdcard_pins: sdcard {
- mux {
- groups = "sdcard_d0",
- "sdcard_d1",
- "sdcard_d2",
- "sdcard_d3",
- "sdcard_cmd",
- "sdcard_clk";
- function = "sdcard";
- };
- };
-
- uart_a_pins: uart_a {
- mux {
- groups = "uart_tx_a",
- "uart_rx_a";
- function = "uart_a";
- };
- };
-
- uart_b_pins: uart_b {
- mux {
- groups = "uart_tx_b",
- "uart_rx_b";
- function = "uart_b";
- };
- };
-
- uart_c_pins: uart_c {
- mux {
- groups = "uart_tx_c",
- "uart_rx_c";
- function = "uart_c";
- };
- };
-
- eth_pins: eth_c {
- mux {
- groups = "eth_mdio",
- "eth_mdc",
- "eth_clk_rx_clk",
- "eth_rx_dv",
- "eth_rxd0",
- "eth_rxd1",
- "eth_rxd2",
- "eth_rxd3",
- "eth_rgmii_tx_clk",
- "eth_tx_en",
- "eth_txd0",
- "eth_txd1",
- "eth_txd2",
- "eth_txd3";
- function = "eth";
- };
- };
- };
- };
-
- hiubus: hiubus@c883c000 {
- compatible = "simple-bus";
- reg = <0x0 0xc883c000 0x0 0x2000>;
- #address-cells = <2>;
- #size-cells = <2>;
- ranges = <0x0 0x0 0x0 0xc883c000 0x0 0x2000>;
-
- clkc: clock-controller@0 {
- compatible = "amlogic,gxbb-clkc";
- #clock-cells = <1>;
- reg = <0x0 0x0 0x0 0x3db>;
- };
- };
-
- apb: apb@d0000000 {
- compatible = "simple-bus";
- reg = <0x0 0xd0000000 0x0 0x200000>;
- #address-cells = <2>;
- #size-cells = <2>;
- ranges = <0x0 0x0 0x0 0xd0000000 0x0 0x200000>;
- };
-
- ethmac: ethernet@c9410000 {
- compatible = "amlogic,meson6-dwmac", "snps,dwmac";
- reg = <0x0 0xc9410000 0x0 0x10000
- 0x0 0xc8834540 0x0 0x4>;
- interrupts = <0 8 1>;
- interrupt-names = "macirq";
- clocks = <&xtal>;
- clock-names = "stmmaceth";
- phy-mode = "rgmii";
- status = "disabled";
+ gpio: bank@4b0 {
+ reg = <0x0 0x004b0 0x0 0x28>,
+ <0x0 0x004e8 0x0 0x14>,
+ <0x0 0x00120 0x0 0x14>,
+ <0x0 0x00430 0x0 0x40>;
+ reg-names = "mux", "pull", "pull-enable", "gpio";
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ emmc_pins: emmc {
+ mux {
+ groups = "emmc_nand_d07",
+ "emmc_cmd",
+ "emmc_clk",
+ "emmc_ds";
+ function = "emmc";
+ };
+ };
+
+ nor_pins: nor {
+ mux {
+ groups = "nor_d",
+ "nor_q",
+ "nor_c",
+ "nor_cs";
+ function = "nor";
+ };
+ };
+
+ sdcard_pins: sdcard {
+ mux {
+ groups = "sdcard_d0",
+ "sdcard_d1",
+ "sdcard_d2",
+ "sdcard_d3",
+ "sdcard_cmd",
+ "sdcard_clk";
+ function = "sdcard";
+ };
+ };
+
+ sdio_pins: sdio {
+ mux {
+ groups = "sdio_d0",
+ "sdio_d1",
+ "sdio_d2",
+ "sdio_d3",
+ "sdio_cmd",
+ "sdio_clk";
+ function = "sdio";
+ };
+ };
+
+ sdio_irq_pins: sdio_irq {
+ mux {
+ groups = "sdio_irq";
+ function = "sdio";
+ };
+ };
+
+ uart_a_pins: uart_a {
+ mux {
+ groups = "uart_tx_a",
+ "uart_rx_a";
+ function = "uart_a";
+ };
+ };
+
+ uart_a_cts_rts_pins: uart_a_cts_rts {
+ mux {
+ groups = "uart_cts_a",
+ "uart_rts_a";
+ function = "uart_a";
+ };
+ };
+
+ uart_b_pins: uart_b {
+ mux {
+ groups = "uart_tx_b",
+ "uart_rx_b";
+ function = "uart_b";
+ };
+ };
+
+ uart_b_cts_rts_pins: uart_b_cts_rts {
+ mux {
+ groups = "uart_cts_b",
+ "uart_rts_b";
+ function = "uart_b";
+ };
+ };
+
+ uart_c_pins: uart_c {
+ mux {
+ groups = "uart_tx_c",
+ "uart_rx_c";
+ function = "uart_c";
+ };
+ };
+
+ uart_c_cts_rts_pins: uart_c_cts_rts {
+ mux {
+ groups = "uart_cts_c",
+ "uart_rts_c";
+ function = "uart_c";
+ };
+ };
+
+ i2c_a_pins: i2c_a {
+ mux {
+ groups = "i2c_sck_a",
+ "i2c_sda_a";
+ function = "i2c_a";
+ };
+ };
+
+ i2c_b_pins: i2c_b {
+ mux {
+ groups = "i2c_sck_b",
+ "i2c_sda_b";
+ function = "i2c_b";
+ };
+ };
+
+ i2c_c_pins: i2c_c {
+ mux {
+ groups = "i2c_sck_c",
+ "i2c_sda_c";
+ function = "i2c_c";
+ };
+ };
+
+ eth_rgmii_pins: eth-rgmii {
+ mux {
+ groups = "eth_mdio",
+ "eth_mdc",
+ "eth_clk_rx_clk",
+ "eth_rx_dv",
+ "eth_rxd0",
+ "eth_rxd1",
+ "eth_rxd2",
+ "eth_rxd3",
+ "eth_rgmii_tx_clk",
+ "eth_tx_en",
+ "eth_txd0",
+ "eth_txd1",
+ "eth_txd2",
+ "eth_txd3";
+ function = "eth";
+ };
+ };
+
+ eth_rmii_pins: eth-rmii {
+ mux {
+ groups = "eth_mdio",
+ "eth_mdc",
+ "eth_clk_rx_clk",
+ "eth_rx_dv",
+ "eth_rxd0",
+ "eth_rxd1",
+ "eth_tx_en",
+ "eth_txd0",
+ "eth_txd1";
+ function = "eth";
+ };
+ };
+
+ pwm_a_x_pins: pwm_a_x {
+ mux {
+ groups = "pwm_a_x";
+ function = "pwm_a_x";
+ };
+ };
+
+ pwm_a_y_pins: pwm_a_y {
+ mux {
+ groups = "pwm_a_y";
+ function = "pwm_a_y";
+ };
+ };
+
+ pwm_b_pins: pwm_b {
+ mux {
+ groups = "pwm_b";
+ function = "pwm_b";
+ };
+ };
+
+ pwm_d_pins: pwm_d {
+ mux {
+ groups = "pwm_d";
+ function = "pwm_d";
+ };
+ };
+
+ pwm_e_pins: pwm_e {
+ mux {
+ groups = "pwm_e";
+ function = "pwm_e";
+ };
+ };
+
+ pwm_f_x_pins: pwm_f_x {
+ mux {
+ groups = "pwm_f_x";
+ function = "pwm_f_x";
+ };
+ };
+
+ pwm_f_y_pins: pwm_f_y {
+ mux {
+ groups = "pwm_f_y";
+ function = "pwm_f_y";
+ };
+ };
+
+ hdmi_hpd_pins: hdmi_hpd {
+ mux {
+ groups = "hdmi_hpd";
+ function = "hdmi_hpd";
+ };
+ };
+
+ hdmi_i2c_pins: hdmi_i2c {
+ mux {
+ groups = "hdmi_sda", "hdmi_scl";
+ function = "hdmi_i2c";
+ };
};
};
};
+
+&hiubus {
+ clkc: clock-controller@0 {
+ compatible = "amlogic,gxbb-clkc";
+ #clock-cells = <1>;
+ reg = <0x0 0x0 0x0 0x3db>;
+ };
+};
+
+&i2c_A {
+ clocks = <&clkc CLKID_I2C>;
+};
+
+&i2c_B {
+ clocks = <&clkc CLKID_I2C>;
+};
+
+&i2c_C {
+ clocks = <&clkc CLKID_I2C>;
+};
+
+&sd_emmc_a {
+ clocks = <&clkc CLKID_SD_EMMC_A>,
+ <&xtal>,
+ <&clkc CLKID_FCLK_DIV2>;
+ clock-names = "core", "clkin0", "clkin1";
+};
+
+&sd_emmc_b {
+ clocks = <&clkc CLKID_SD_EMMC_B>,
+ <&xtal>,
+ <&clkc CLKID_FCLK_DIV2>;
+ clock-names = "core", "clkin0", "clkin1";
+};
+
+&sd_emmc_c {
+ clocks = <&clkc CLKID_SD_EMMC_C>,
+ <&xtal>,
+ <&clkc CLKID_FCLK_DIV2>;
+ clock-names = "core", "clkin0", "clkin1";
+};
+
+&vpu {
+ compatible = "amlogic,meson-gxbb-vpu", "amlogic,meson-gx-vpu";
+};
diff --git a/include/dt-bindings/clock/gxbb-aoclkc.h b/include/dt-bindings/clock/gxbb-aoclkc.h
new file mode 100644
index 0000000..3175148
--- /dev/null
+++ b/include/dt-bindings/clock/gxbb-aoclkc.h
@@ -0,0 +1,66 @@
+/*
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * Copyright (c) 2016 BayLibre, SAS.
+ * Author: Neil Armstrong <narmstrong(a)baylibre.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ * The full GNU General Public License is included in this distribution
+ * in the file called COPYING.
+ *
+ * BSD LICENSE
+ *
+ * Copyright (c) 2016 BayLibre, SAS.
+ * Author: Neil Armstrong <narmstrong(a)baylibre.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef DT_BINDINGS_CLOCK_AMLOGIC_MESON_GXBB_AOCLK
+#define DT_BINDINGS_CLOCK_AMLOGIC_MESON_GXBB_AOCLK
+
+#define CLKID_AO_REMOTE 0
+#define CLKID_AO_I2C_MASTER 1
+#define CLKID_AO_I2C_SLAVE 2
+#define CLKID_AO_UART1 3
+#define CLKID_AO_UART2 4
+#define CLKID_AO_IR_BLASTER 5
+
+#endif
diff --git a/include/dt-bindings/clock/gxbb-clkc.h b/include/dt-bindings/clock/gxbb-clkc.h
new file mode 100644
index 0000000..692846c
--- /dev/null
+++ b/include/dt-bindings/clock/gxbb-clkc.h
@@ -0,0 +1,34 @@
+/*
+ * GXBB clock tree IDs
+ */
+
+#ifndef __GXBB_CLKC_H
+#define __GXBB_CLKC_H
+
+#define CLKID_CPUCLK 1
+#define CLKID_HDMI_PLL 2
+#define CLKID_FCLK_DIV2 4
+#define CLKID_FCLK_DIV3 5
+#define CLKID_FCLK_DIV4 6
+#define CLKID_CLK81 12
+#define CLKID_MPLL2 15
+#define CLKID_SPI 34
+#define CLKID_I2C 22
+#define CLKID_SAR_ADC 23
+#define CLKID_ETH 36
+#define CLKID_USB0 50
+#define CLKID_USB1 51
+#define CLKID_USB 55
+#define CLKID_HDMI_PCLK 63
+#define CLKID_USB1_DDR_BRIDGE 64
+#define CLKID_USB0_DDR_BRIDGE 65
+#define CLKID_SANA 69
+#define CLKID_GCLK_VENCI_INT0 77
+#define CLKID_AO_I2C 93
+#define CLKID_SD_EMMC_A 94
+#define CLKID_SD_EMMC_B 95
+#define CLKID_SD_EMMC_C 96
+#define CLKID_SAR_ADC_CLK 97
+#define CLKID_SAR_ADC_SEL 98
+
+#endif /* __GXBB_CLKC_H */
diff --git a/include/dt-bindings/reset/gxbb-aoclkc.h b/include/dt-bindings/reset/gxbb-aoclkc.h
new file mode 100644
index 0000000..9e3fd60
--- /dev/null
+++ b/include/dt-bindings/reset/gxbb-aoclkc.h
@@ -0,0 +1,66 @@
+/*
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * Copyright (c) 2016 BayLibre, SAS.
+ * Author: Neil Armstrong <narmstrong(a)baylibre.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ * The full GNU General Public License is included in this distribution
+ * in the file called COPYING.
+ *
+ * BSD LICENSE
+ *
+ * Copyright (c) 2016 BayLibre, SAS.
+ * Author: Neil Armstrong <narmstrong(a)baylibre.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef DT_BINDINGS_RESET_AMLOGIC_MESON_GXBB_AOCLK
+#define DT_BINDINGS_RESET_AMLOGIC_MESON_GXBB_AOCLK
+
+#define RESET_AO_REMOTE 0
+#define RESET_AO_I2C_MASTER 1
+#define RESET_AO_I2C_SLAVE 2
+#define RESET_AO_UART1 3
+#define RESET_AO_UART2 4
+#define RESET_AO_IR_BLASTER 5
+
+#endif
--
2.11.1
3
11

[U-Boot] [PATCH] ARM: DT: STM32F746: add u-boot, dm-pre-reloc property to sub nodes
by Vikas Manocha 12 Apr '17
by Vikas Manocha 12 Apr '17
12 Apr '17
This patch is required for correct SPL device tree creation by fdtgrep
as fdtgrep looks for u-boot,dm-pre-reloc property of the node to include
it in the spl device tree.
Not adding it in these subnodes ignores the pin muxing of peripherals
which is almost always in the subnodes.
Signed-off-by: Vikas Manocha <vikas.manocha(a)st.com>
---
arch/arm/dts/stm32f746-disco.dts | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/arch/arm/dts/stm32f746-disco.dts b/arch/arm/dts/stm32f746-disco.dts
index 2c7fa79..30c92ef 100644
--- a/arch/arm/dts/stm32f746-disco.dts
+++ b/arch/arm/dts/stm32f746-disco.dts
@@ -96,15 +96,18 @@
&pinctrl {
usart1_pins_a: usart1@0 {
+ u-boot,dm-pre-reloc;
pins1 {
- pinmux = <STM32F746_PA9_FUNC_USART1_TX>;
+ pinmux = <STM32F746_PA9_FUNC_USART1_TX>;
bias-disable;
drive-push-pull;
slew-rate = <2>;
+ u-boot,dm-pre-reloc;
};
pins2 {
pinmux = <STM32F746_PB7_FUNC_USART1_RX>;
bias-disable;
+ u-boot,dm-pre-reloc;
};
};
@@ -136,7 +139,9 @@
};
fmc_pins: fmc@0 {
+ u-boot,dm-pre-reloc;
pins {
+ u-boot,dm-pre-reloc;
pinmux = <STM32F746_PD10_FUNC_FMC_D15>,
<STM32F746_PD9_FUNC_FMC_D14>,
<STM32F746_PD8_FUNC_FMC_D13>,
@@ -198,6 +203,7 @@
mr-nbanks = <1>;
/* Memory configuration from sdram datasheet MT48LC_4M32_B2B5-6A */
bank1: bank@0 {
+ u-boot,dm-pre-reloc;
st,sdram-control = /bits/ 8 <NO_COL_8 NO_ROW_12 MWIDTH_16 BANKS_4
CAS_3 SDCLK_2 RD_BURST_EN
RD_PIPE_DL_0>;
--
1.9.1
3
2

[U-Boot] [PATCH 0/8] drivers: i2c: davinci_i2c: Convert driver to DM
by Franklin S Cooper Jr 12 Apr '17
by Franklin S Cooper Jr 12 Apr '17
12 Apr '17
This patch series converts the davinci i2c driver to use device model.
This updated driver has been verified on both Keystone K2G and Keystone
K2L evms by performing several i2c operations in U-boot prompt.
Some additional work was required to get things working on K2G due to
the code that reads the on board EEPROM. DM I2C sets the default address
length to a default value of 1 when the on EEPROM requires an address
length of 2. Therefore, an additional function and minor changes were
required to get things working properly.
Franklin S Cooper Jr (8):
i2c: davinci: Split functions into two parts for future DM support
drivers: i2c: davinci_i2c: Update davinci i2c driver to driver model
ti: common: board_detect: Introduce function to set the address
length.
ti: common: board_detect: Set alen to expected value before i2c read
ARM: dts: k2g: Add I2C nodes to 66AK2Gx
ARM: dts: keystone2: add I2C aliases for davinci I2C nodes
ARM: dts: keystone-k2g-evm: Enable I2C0 and I2C1
defconfig: keystone: Enable DM I2C
arch/arm/dts/keystone-k2g-evm.dts | 8 ++
arch/arm/dts/keystone-k2g.dtsi | 32 +++++
arch/arm/dts/keystone.dtsi | 3 +
board/ti/common/board_detect.c | 61 ++++++++-
configs/k2e_evm_defconfig | 1 +
configs/k2g_evm_defconfig | 1 +
configs/k2hk_evm_defconfig | 1 +
configs/k2l_evm_defconfig | 1 +
drivers/i2c/davinci_i2c.c | 277 +++++++++++++++++++++++++++-----------
9 files changed, 306 insertions(+), 79 deletions(-)
--
2.10.0
3
19

[U-Boot] [PATCH 7/7] omap3_logic: Add Device Tree Support and more DM drivers
by Adam Ford 12 Apr '17
by Adam Ford 12 Apr '17
12 Apr '17
The previous version of omap3_logic_defconfig supported either
Torpedo or SOM-LV. Now with the device tree, there are two
different defconfig files:
omap3_logic_defconfig = torpedo
omap3_logic_somlv_defconfig = SOM-LV
This patch also removes all the excessive code in trying to
determine the differences between these boards as well as removing
the some of the unnecessary NS16550 intiailization as the device
tree can do that now. This also adds DM_I2C and DM_MMC since
the overlying drivers have the built-in support already. The
corresponding include/config/omap3_logic.h also reduced in size
due to the new device tree support.
The device trees were sync'd with 4.9.y stable with two changes:
disable mmc2 and stdout-path = &uart1. Both of those two changes
will be submitted to the linux-omap list.
Signed-off-by: Adam Ford <aford173(a)gmail.com>
Reviewed-by: Lokesh Vutla <lokeshvutla(a)ti.com>
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
index 7378c88..44c586d 100644
--- a/arch/arm/dts/Makefile
+++ b/arch/arm/dts/Makefile
@@ -341,6 +341,10 @@ dtb-$(CONFIG_SOC_KEYSTONE) += keystone-k2hk-evm.dtb \
keystone-k2e-evm.dtb \
keystone-k2g-evm.dtb
+dtb-$(CONFIG_TARGET_OMAP3_LOGIC) += \
+ logicpd-torpedo-37xx-devkit.dtb \
+ logicpd-som-lv-37xx-devkit.dts
+
dtb-$(CONFIG_TARGET_SAMA5D2_XPLAINED) += \
at91-sama5d2_xplained.dtb
diff --git a/arch/arm/dts/logicpd-som-lv-37xx-devkit.dts b/arch/arm/dts/logicpd-som-lv-37xx-devkit.dts
new file mode 100644
index 0000000..31ecfdc
--- /dev/null
+++ b/arch/arm/dts/logicpd-som-lv-37xx-devkit.dts
@@ -0,0 +1,271 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/dts-v1/;
+
+#include "omap36xx.dtsi"
+#include "logicpd-som-lv.dtsi"
+#include "omap-gpmc-smsc9221.dtsi"
+
+/ {
+ model = "LogicPD Zoom DM3730 SOM-LV Development Kit";
+ compatible = "logicpd,dm3730-som-lv-devkit", "ti,omap3630", "ti,omap3";
+
+ chosen {
+ stdout-path = &uart1;
+ };
+
+ gpio_keys {
+ compatible = "gpio-keys";
+ pinctrl-names = "default";
+ pinctrl-0 = <&gpio_key_pins>;
+
+ sysboot2 {
+ label = "gpio3";
+ gpios = <&gpio4 15 GPIO_ACTIVE_LOW>; /* gpio_111 / uP_GPIO_3 */
+ linux,code = <BTN_0>;
+ wakeup-source;
+ };
+ };
+
+ sound {
+ compatible = "ti,omap-twl4030";
+ ti,model = "omap3logic";
+ ti,mcbsp = <&mcbsp2>;
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 = <&led_pins &led_pins_wkup>;
+
+ led1 {
+ label = "led1";
+ gpios = <&gpio5 5 GPIO_ACTIVE_LOW>; /* gpio133 */
+ linux,default-trigger = "cpu0";
+ };
+
+ led2 {
+ label = "led2";
+ gpios = <&gpio1 11 GPIO_ACTIVE_LOW>; /* gpio11 */
+ linux,default-trigger = "none";
+ };
+ };
+};
+
+&vaux1 {
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3000000>;
+};
+
+&vaux4 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+};
+
+&mcbsp2 {
+ status = "okay";
+};
+
+&charger {
+ ti,bb-uvolt = <3200000>;
+ ti,bb-uamp = <150>;
+};
+
+&gpmc {
+ ranges = <1 0 0x08000000 0x1000000>; /* CS1: 16MB for LAN9221 */
+
+ ethernet@gpmc {
+ pinctrl-names = "default";
+ pinctrl-0 = <&lan9221_pins>;
+ interrupt-parent = <&gpio5>;
+ interrupts = <24 IRQ_TYPE_LEVEL_LOW>; /* gpio_152 */
+ reg = <1 0 0xff>;
+ };
+};
+
+&vpll2 {
+ regulator-always-on;
+};
+
+&dss {
+ status = "ok";
+ vdds_dsi-supply = <&vpll2>;
+ vdda_video-supply = <&video_reg>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&dss_dpi_pins1>;
+ port {
+ dpi_out: endpoint {
+ remote-endpoint = <&lcd_in>;
+ data-lines = <16>;
+ };
+ };
+};
+
+/ {
+ aliases {
+ display0 = &lcd0;
+ };
+
+ video_reg: video_reg {
+ compatible = "regulator-fixed";
+ regulator-name = "fixed-supply";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ lcd0: display@0 {
+ compatible = "panel-dpi";
+ label = "28";
+ status = "okay";
+ /* default-on; */
+ pinctrl-names = "default";
+ pinctrl-0 = <&lcd_enable_pin>;
+ enable-gpios = <&gpio5 27 GPIO_ACTIVE_HIGH>; /* gpio155, lcd INI */
+ port {
+ lcd_in: endpoint {
+ remote-endpoint = <&dpi_out>;
+ };
+ };
+
+ panel-timing {
+ clock-frequency = <9000000>;
+ hactive = <480>;
+ vactive = <272>;
+ hfront-porch = <3>;
+ hback-porch = <2>;
+ hsync-len = <42>;
+ vback-porch = <3>;
+ vfront-porch = <2>;
+ vsync-len = <11>;
+ hsync-active = <1>;
+ vsync-active = <1>;
+ de-active = <1>;
+ pixelclk-active = <0>;
+ };
+ };
+
+ bl: backlight {
+ compatible = "pwm-backlight";
+ pinctrl-names = "default";
+ pinctrl-0 = <&backlight_pins>;
+ pwms = <&twl_pwm 0 5000000>;
+ brightness-levels = <0 10 20 30 40 50 60 70 80 90 100>;
+ default-brightness-level = <7>;
+ enable-gpios = <&gpio1 8 GPIO_ACTIVE_HIGH>; /* gpio_8 */
+ };
+};
+
+&mmc1 {
+ interrupts-extended = <&intc 83 &omap3_pmx_core 0x11a>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc1_pins>;
+ wp-gpios = <&gpio4 30 GPIO_ACTIVE_HIGH>; /* gpio_126 */
+ cd-gpios = <&gpio4 14 IRQ_TYPE_LEVEL_LOW>; /* gpio_110 */
+ vmmc-supply = <&vmmc1>;
+ bus-width = <4>;
+ cap-power-off-card;
+};
+
+&mmc2 {
+ status = "disabled";
+};
+
+&omap3_pmx_core {
+ gpio_key_pins: pinmux_gpio_key_pins {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x212e, PIN_INPUT_PULLUP | MUX_MODE4) /* cam_xclkb.gpio_111 / uP_GPIO_3*/
+ >;
+ };
+
+ led_pins: pinmux_led_pins {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x215e, PIN_OUTPUT_PULLUP | MUX_MODE4) /* sdmmc2_dat1.gpio_133 / uP_GPIO_0 */
+ >;
+ };
+
+ lan9221_pins: pinmux_lan9221_pins {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x2184, PIN_INPUT_PULLUP | MUX_MODE4) /* mcbsp4_clkx.gpio_152 */
+ >;
+ };
+
+ mmc1_pins: pinmux_mmc1_pins {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x2144, PIN_OUTPUT | MUX_MODE0) /* sdmmc1_clk.sdmmc1_clk */
+ OMAP3_CORE1_IOPAD(0x2146, PIN_INPUT | MUX_MODE0) /* sdmmc1_cmd.sdmmc1_cmd */
+ OMAP3_CORE1_IOPAD(0x2148, PIN_INPUT | MUX_MODE0) /* sdmmc1_dat0.sdmmc1_dat0 */
+ OMAP3_CORE1_IOPAD(0x214a, PIN_INPUT | MUX_MODE0) /* sdmmc1_dat1.sdmmc1_dat1 */
+ OMAP3_CORE1_IOPAD(0x214c, PIN_INPUT | MUX_MODE0) /* sdmmc1_dat2.sdmmc1_dat2 */
+ OMAP3_CORE1_IOPAD(0x214e, PIN_INPUT | MUX_MODE0) /* sdmmc1_dat3.sdmmc1_dat3 */
+ OMAP3_CORE1_IOPAD(0x2132, PIN_INPUT_PULLUP | MUX_MODE4) /* cam_strobe.gpio_126 */
+ OMAP3_CORE1_IOPAD(0x212c, PIN_INPUT_PULLUP | MUX_MODE4) /* cam_d11.gpio_110 */
+ >;
+ };
+
+ lcd_enable_pin: pinmux_lcd_enable_pin {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x218a, PIN_OUTPUT | PIN_OFF_OUTPUT_LOW | MUX_MODE4) /* mcbsp4_fs.gpio_155 */
+ >;
+ };
+
+ dss_dpi_pins1: pinmux_dss_dpi_pins1 {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x20d4, PIN_OUTPUT_PULLDOWN | PIN_OFF_OUTPUT_LOW | MUX_MODE0) /* dss_pclk.dss_pclk */
+ OMAP3_CORE1_IOPAD(0x20d6, PIN_OUTPUT_PULLDOWN | PIN_OFF_OUTPUT_LOW | MUX_MODE0) /* dss_hsync.dss_hsync */
+ OMAP3_CORE1_IOPAD(0x20d8, PIN_OUTPUT_PULLDOWN | PIN_OFF_OUTPUT_LOW | MUX_MODE0) /* dss_vsync.dss_vsync */
+ OMAP3_CORE1_IOPAD(0x20da, PIN_OUTPUT_PULLDOWN | PIN_OFF_OUTPUT_LOW | MUX_MODE0) /* dss_acbias.dss_acbias */
+
+ OMAP3_CORE1_IOPAD(0x20dc, PIN_OUTPUT_PULLDOWN | PIN_OFF_OUTPUT_LOW | MUX_MODE0) /* dss_data0.dss_data0 */
+ OMAP3_CORE1_IOPAD(0x20de, PIN_OUTPUT_PULLDOWN | PIN_OFF_OUTPUT_LOW | MUX_MODE0) /* dss_data1.dss_data1 */
+ OMAP3_CORE1_IOPAD(0x20e0, PIN_OUTPUT_PULLDOWN | PIN_OFF_OUTPUT_LOW | MUX_MODE0) /* dss_data2.dss_data2 */
+ OMAP3_CORE1_IOPAD(0x20e2, PIN_OUTPUT_PULLDOWN | PIN_OFF_OUTPUT_LOW | MUX_MODE0) /* dss_data3.dss_data3 */
+ OMAP3_CORE1_IOPAD(0x20e4, PIN_OUTPUT_PULLDOWN | PIN_OFF_OUTPUT_LOW | MUX_MODE0) /* dss_data4.dss_data4 */
+ OMAP3_CORE1_IOPAD(0x20e6, PIN_OUTPUT_PULLDOWN | PIN_OFF_OUTPUT_LOW | MUX_MODE0) /* dss_data5.dss_data5 */
+ OMAP3_CORE1_IOPAD(0x20e8, PIN_OUTPUT_PULLDOWN | PIN_OFF_OUTPUT_LOW | MUX_MODE0) /* dss_data6.dss_data6 */
+ OMAP3_CORE1_IOPAD(0x20ea, PIN_OUTPUT_PULLDOWN | PIN_OFF_OUTPUT_LOW | MUX_MODE0) /* dss_data7.dss_data7 */
+ OMAP3_CORE1_IOPAD(0x20ec, PIN_OUTPUT_PULLDOWN | PIN_OFF_OUTPUT_LOW | MUX_MODE0) /* dss_data8.dss_data8 */
+ OMAP3_CORE1_IOPAD(0x20ee, PIN_OUTPUT_PULLDOWN | PIN_OFF_OUTPUT_LOW | MUX_MODE0) /* dss_data9.dss_data9 */
+ OMAP3_CORE1_IOPAD(0x20f0, PIN_OUTPUT_PULLDOWN | PIN_OFF_OUTPUT_LOW | MUX_MODE0) /* dss_data10.dss_data10 */
+ OMAP3_CORE1_IOPAD(0x20f2, PIN_OUTPUT_PULLDOWN | PIN_OFF_OUTPUT_LOW | MUX_MODE0) /* dss_data11.dss_data11 */
+ OMAP3_CORE1_IOPAD(0x20f4, PIN_OUTPUT_PULLDOWN | PIN_OFF_OUTPUT_LOW | MUX_MODE0) /* dss_data12.dss_data12 */
+ OMAP3_CORE1_IOPAD(0x20f6, PIN_OUTPUT_PULLDOWN | PIN_OFF_OUTPUT_LOW | MUX_MODE0) /* dss_data13.dss_data13 */
+ OMAP3_CORE1_IOPAD(0x20f8, PIN_OUTPUT_PULLDOWN | PIN_OFF_OUTPUT_LOW | MUX_MODE0) /* dss_data14.dss_data14 */
+ OMAP3_CORE1_IOPAD(0x20fa, PIN_OUTPUT_PULLDOWN | PIN_OFF_OUTPUT_LOW | MUX_MODE0) /* dss_data15.dss_data15 */
+ >;
+ };
+};
+
+&omap3_pmx_wkup {
+ led_pins_wkup: pinmux_led_pins_wkup {
+ pinctrl-single,pins = <
+ OMAP3_WKUP_IOPAD(0x2a24, PIN_OUTPUT_PULLUP | MUX_MODE4) /* jtag_emu0.gpio_11 / uP_GPIO_1 */
+ >;
+ };
+
+ backlight_pins: pinmux_backlight_pins {
+ pinctrl-single,pins = <
+ OMAP3_WKUP_IOPAD(0x2a16, PIN_OUTPUT | PIN_OFF_OUTPUT_LOW | MUX_MODE4) /* sys_boot6.gpio_8 */
+ >;
+ };
+};
+
+
+&uart1 {
+ interrupts-extended = <&intc 72 &omap3_pmx_core OMAP3_UART1_RX>;
+};
+
+/* Wired to the tps65950 on the SOM, only the USB connector is on the devkit */
+&usb_otg_hs {
+ pinctrl-names = "default";
+ pinctrl-0 = <&hsusb_otg_pins>;
+ interface-type = <0>;
+ usb-phy = <&usb2_phy>;
+ phys = <&usb2_phy>;
+ phy-names = "usb2-phy";
+ mode = <3>;
+ power = <50>;
+};
diff --git a/arch/arm/dts/logicpd-som-lv.dtsi b/arch/arm/dts/logicpd-som-lv.dtsi
new file mode 100644
index 0000000..46dae55
--- /dev/null
+++ b/arch/arm/dts/logicpd-som-lv.dtsi
@@ -0,0 +1,271 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <dt-bindings/input/input.h>
+
+/ {
+ cpus {
+ cpu@0 {
+ cpu0-supply = <&vcc>;
+ };
+ };
+
+ memory@80000000 {
+ device_type = "memory";
+ reg = <0x80000000 0>;
+ };
+
+ wl12xx_vmmc: wl12xx_vmmc {
+ compatible = "regulator-fixed";
+ regulator-name = "vwl1271";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ gpio = <&gpio1 3 0>; /* gpio_3 */
+ startup-delay-us = <70000>;
+ enable-active-high;
+ vin-supply = <&vmmc2>;
+ };
+
+ /* HS USB Host PHY on PORT 1 */
+ hsusb2_phy: hsusb2_phy {
+ compatible = "usb-nop-xceiv";
+ reset-gpios = <&gpio1 4 GPIO_ACTIVE_LOW>; /* gpio_4 */
+ };
+};
+
+&gpmc {
+ ranges = <0 0 0x00000000 0x1000000>; /* CS0: 16MB for NAND */
+
+ nand@0,0 {
+ compatible = "ti,omap2-nand";
+ reg = <0 0 4>; /* CS0, offset 0, IO size 4 */
+ interrupt-parent = <&gpmc>;
+ interrupts = <0 IRQ_TYPE_NONE>, /* fifoevent */
+ <1 IRQ_TYPE_NONE>; /* termcount */
+ linux,mtd-name = "micron,mt29f4g16abbda3w";
+ nand-bus-width = <16>;
+ ti,nand-ecc-opt = "bch8";
+ rb-gpios = <&gpmc 0 GPIO_ACTIVE_HIGH>; /* gpmc_wait0 */
+ gpmc,sync-clk-ps = <0>;
+ gpmc,cs-on-ns = <0>;
+ gpmc,cs-rd-off-ns = <44>;
+ gpmc,cs-wr-off-ns = <44>;
+ gpmc,adv-on-ns = <6>;
+ gpmc,adv-rd-off-ns = <34>;
+ gpmc,adv-wr-off-ns = <44>;
+ gpmc,we-off-ns = <40>;
+ gpmc,oe-off-ns = <54>;
+ gpmc,access-ns = <64>;
+ gpmc,rd-cycle-ns = <82>;
+ gpmc,wr-cycle-ns = <82>;
+ gpmc,wr-access-ns = <40>;
+ gpmc,wr-data-mux-bus-ns = <0>;
+ gpmc,device-width = <2>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ /* u-boot uses mtdparts=omap2-nand.0:512k(x-loader),1920k(u-boot),128k(u-boot-env),4m(kernel),-(fs) */
+
+ x-loader@0 {
+ label = "x-loader";
+ reg = <0 0x80000>;
+ };
+
+ bootloaders@80000 {
+ label = "u-boot";
+ reg = <0x80000 0x1e0000>;
+ };
+
+ bootloaders_env@260000 {
+ label = "u-boot-env";
+ reg = <0x260000 0x20000>;
+ };
+
+ kernel@280000 {
+ label = "kernel";
+ reg = <0x280000 0x400000>;
+ };
+
+ filesystem@680000 {
+ label = "fs";
+ reg = <0x680000 0>; /* 0 = MTDPART_SIZ_FULL */
+ };
+ };
+};
+
+&i2c1 {
+ clock-frequency = <400000>;
+
+ twl: twl@48 {
+ reg = <0x48>;
+ interrupts = <7>; /* SYS_NIRQ cascaded to intc */
+ interrupt-parent = <&intc>;
+ twl_audio: audio {
+ compatible = "ti,twl4030-audio";
+ codec {
+ };
+ };
+ };
+};
+
+&i2c2 {
+ clock-frequency = <400000>;
+};
+
+&i2c3 {
+ clock-frequency = <400000>;
+};
+
+&mmc3 {
+ interrupts-extended = <&intc 94 &omap3_pmx_core2 0x46>;
+ pinctrl-0 = <&mmc3_pins>;
+ pinctrl-names = "default";
+ vmmc-supply = <&wl12xx_vmmc>;
+ non-removable;
+ bus-width = <4>;
+ cap-power-off-card;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ wlcore: wlcore@2 {
+ compatible = "ti,wl1273";
+ reg = <2>;
+ interrupt-parent = <&gpio5>;
+ interrupts = <24 IRQ_TYPE_LEVEL_HIGH>; /* gpio 152 */
+ ref-clock-frequency = <26000000>;
+ };
+};
+
+&usbhshost {
+ port2-mode = "ehci-phy";
+};
+
+&usbhsehci {
+ phys = <0 &hsusb2_phy>;
+};
+
+
+&omap3_pmx_core {
+ pinctrl-names = "default";
+ pinctrl-0 = <&hsusb2_pins>;
+
+ mmc3_pins: pinmux_mm3_pins {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x2164, PIN_INPUT_PULLUP | MUX_MODE3) /* sdmmc2_dat4.sdmmc3_dat0 */
+ OMAP3_CORE1_IOPAD(0x2166, PIN_INPUT_PULLUP | MUX_MODE3) /* sdmmc2_dat5.sdmmc3_dat1 */
+ OMAP3_CORE1_IOPAD(0x2168, PIN_INPUT_PULLUP | MUX_MODE3) /* sdmmc2_dat6.sdmmc3_dat2 */
+ OMAP3_CORE1_IOPAD(0x216a, PIN_INPUT_PULLUP | MUX_MODE3) /* sdmmc2_dat6.sdmmc3_dat3 */
+ OMAP3_CORE1_IOPAD(0x2184, PIN_INPUT_PULLUP | MUX_MODE4) /* mcbsp4_clkx.gpio_152 */
+ OMAP3_CORE1_IOPAD(0x2a0c, PIN_OUTPUT | MUX_MODE4) /* sys_boot1.gpio_3 */
+ OMAP3_CORE1_IOPAD(0x21d0, PIN_INPUT_PULLUP | MUX_MODE3) /* mcspi1_cs1.sdmmc3_cmd */
+ OMAP3_CORE1_IOPAD(0x21d2, PIN_INPUT_PULLUP | MUX_MODE3) /* mcspi1_cs2.sdmmc_clk */
+ >;
+ };
+ mcbsp2_pins: pinmux_mcbsp2_pins {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x213c, PIN_INPUT | MUX_MODE0) /* mcbsp2_fsx */
+ OMAP3_CORE1_IOPAD(0x213e, PIN_INPUT | MUX_MODE0) /* mcbsp2_clkx */
+ OMAP3_CORE1_IOPAD(0x2140, PIN_INPUT | MUX_MODE0) /* mcbsp2_dr */
+ OMAP3_CORE1_IOPAD(0x2142, PIN_OUTPUT | MUX_MODE0) /* mcbsp2_dx */
+ >;
+ };
+ uart2_pins: pinmux_uart2_pins {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x2174, PIN_INPUT | MUX_MODE0) /* uart2_cts.uart2_cts */
+ OMAP3_CORE1_IOPAD(0x2176, PIN_OUTPUT | MUX_MODE0) /* uart2_rts .uart2_rts*/
+ OMAP3_CORE1_IOPAD(0x2178, PIN_OUTPUT | MUX_MODE0) /* uart2_tx.uart2_tx */
+ OMAP3_CORE1_IOPAD(0x217a, PIN_INPUT | MUX_MODE0) /* uart2_rx.uart2_rx */
+ OMAP3_CORE1_IOPAD(0x2198, PIN_OUTPUT | MUX_MODE4) /* GPIO_162,BT_EN */
+ >;
+ };
+ mcspi1_pins: pinmux_mcspi1_pins {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x21c8, PIN_INPUT | MUX_MODE0) /* mcspi1_clk.mcspi1_clk */
+ OMAP3_CORE1_IOPAD(0x21ca, PIN_OUTPUT | MUX_MODE0) /* mcspi1_simo.mcspi1_simo */
+ OMAP3_CORE1_IOPAD(0x21cc, PIN_INPUT_PULLUP | MUX_MODE0) /* mcspi1_somi.mcspi1_somi */
+ OMAP3_CORE1_IOPAD(0x21ce, PIN_OUTPUT | MUX_MODE0) /* mcspi1_cs0.mcspi1_cs0 */
+ >;
+ };
+
+ hsusb2_pins: pinmux_hsusb2_pins {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x21d4, PIN_INPUT_PULLDOWN | MUX_MODE3) /* mcspi1_cs3.hsusb2_data2 */
+ OMAP3_CORE1_IOPAD(0x21d6, PIN_INPUT_PULLDOWN | MUX_MODE3) /* mcspi2_clk.hsusb2_data7 */
+ OMAP3_CORE1_IOPAD(0x21d8, PIN_INPUT_PULLDOWN | MUX_MODE3) /* mcspi2_simo.hsusb2_data4 */
+ OMAP3_CORE1_IOPAD(0x21da, PIN_INPUT_PULLDOWN | MUX_MODE3) /* mcspi2_somi.hsusb2_data5 */
+ OMAP3_CORE1_IOPAD(0x21dc, PIN_INPUT_PULLDOWN | MUX_MODE3) /* mcspi2_cs0.hsusb2_data6 */
+ OMAP3_CORE1_IOPAD(0x21de, PIN_INPUT_PULLDOWN | MUX_MODE3) /* mcspi2_cs1.hsusb2_data3 */
+ >;
+ };
+
+ hsusb_otg_pins: pinmux_hsusb_otg_pins {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x21a2, PIN_INPUT | MUX_MODE0) /* hsusb0_clk.hsusb0_clk */
+ OMAP3_CORE1_IOPAD(0x21a4, PIN_OUTPUT | MUX_MODE0) /* hsusb0_stp.hsusb0_stp */
+ OMAP3_CORE1_IOPAD(0x21a6, PIN_INPUT | MUX_MODE0) /* hsusb0_dir.hsusb0_dir */
+ OMAP3_CORE1_IOPAD(0x21a8, PIN_INPUT | MUX_MODE0) /* hsusb0_nxt.hsusb0_nxt */
+ OMAP3_CORE1_IOPAD(0x21aa, PIN_INPUT | MUX_MODE0) /* hsusb0_data0.hsusb0_data0 */
+ OMAP3_CORE1_IOPAD(0x21ac, PIN_INPUT | MUX_MODE0) /* hsusb0_data1.hsusb0_data1 */
+ OMAP3_CORE1_IOPAD(0x21ae, PIN_INPUT | MUX_MODE0) /* hsusb0_data2.hsusb0_data2 */
+ OMAP3_CORE1_IOPAD(0x21b0, PIN_INPUT | MUX_MODE0) /* hsusb0_data3.hsusb0_data3 */
+ OMAP3_CORE1_IOPAD(0x21b2, PIN_INPUT | MUX_MODE0) /* hsusb0_data4.hsusb0_data4 */
+ OMAP3_CORE1_IOPAD(0x21b4, PIN_INPUT | MUX_MODE0) /* hsusb0_data5.hsusb0_data5 */
+ OMAP3_CORE1_IOPAD(0x21b6, PIN_INPUT | MUX_MODE0) /* hsusb0_data6.hsusb0_data6 */
+ OMAP3_CORE1_IOPAD(0x21b8, PIN_INPUT | MUX_MODE0) /* hsusb0_data7.hsusb0_data7 */
+ >;
+ };
+
+
+};
+
+&omap3_pmx_wkup {
+ pinctrl-names = "default";
+ pinctrl-0 = <&hsusb2_reset_pin>;
+ hsusb2_reset_pin: pinmux_hsusb1_reset_pin {
+ pinctrl-single,pins = <
+ OMAP3_WKUP_IOPAD(0x2a0e, PIN_OUTPUT | MUX_MODE4) /* sys_boot2.gpio_4 */
+ >;
+ };
+};
+
+&omap3_pmx_core2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&hsusb2_2_pins>;
+ hsusb2_2_pins: pinmux_hsusb2_2_pins {
+ pinctrl-single,pins = <
+ OMAP3630_CORE2_IOPAD(0x25f0, PIN_OUTPUT | MUX_MODE3) /* etk_d10.hsusb2_clk */
+ OMAP3630_CORE2_IOPAD(0x25f2, PIN_OUTPUT | MUX_MODE3) /* etk_d11.hsusb2_stp */
+ OMAP3630_CORE2_IOPAD(0x25f4, PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d12.hsusb2_dir */
+ OMAP3630_CORE2_IOPAD(0x25f6, PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d13.hsusb2_nxt */
+ OMAP3630_CORE2_IOPAD(0x25f8, PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d14.hsusb2_data0 */
+ OMAP3630_CORE2_IOPAD(0x25fa, PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d15.hsusb2_data1 */
+ >;
+ };
+};
+
+&uart2 {
+ interrupts-extended = <&intc 73 &omap3_pmx_core OMAP3_UART2_RX>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart2_pins>;
+};
+
+&mcspi1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mcspi1_pins>;
+};
+
+#include "twl4030.dtsi"
+#include "twl4030_omap3.dtsi"
+
+&twl {
+ twl_power: power {
+ compatible = "ti,twl4030-power-idle-osc-off", "ti,twl4030-power-idle";
+ ti,use_poweroff;
+ };
+};
+
+&twl_gpio {
+ ti,use-leds;
+};
diff --git a/arch/arm/dts/logicpd-torpedo-37xx-devkit.dts b/arch/arm/dts/logicpd-torpedo-37xx-devkit.dts
new file mode 100644
index 0000000..b6838ce
--- /dev/null
+++ b/arch/arm/dts/logicpd-torpedo-37xx-devkit.dts
@@ -0,0 +1,412 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/dts-v1/;
+
+#include "omap36xx.dtsi"
+#include "logicpd-torpedo-som.dtsi"
+#include "omap-gpmc-smsc9221.dtsi"
+
+/ {
+ model = "LogicPD Zoom DM3730 Torpedo + Wireless Development Kit";
+ compatible = "logicpd,dm3730-torpedo-devkit", "ti,omap3630", "ti,omap3";
+
+ chosen {
+ stdout-path = &uart1;
+ };
+
+ gpio_keys {
+ compatible = "gpio-keys";
+ pinctrl-names = "default";
+ pinctrl-0 = <&gpio_key_pins &gpio_key_pins_wkup>;
+
+ sysboot2 {
+ label = "sysboot2";
+ gpios = <&gpio1 2 GPIO_ACTIVE_LOW>; /* gpio2 */
+ linux,code = <BTN_0>;
+ wakeup-source;
+ };
+
+ sysboot5 {
+ label = "sysboot5";
+ gpios = <&gpio1 7 GPIO_ACTIVE_LOW>; /* gpio7 */
+ linux,code = <BTN_1>;
+ wakeup-source;
+ };
+
+ gpio1 {
+ label = "gpio1";
+ gpios = <&gpio6 21 GPIO_ACTIVE_LOW>; /* gpio181 */
+ linux,code = <BTN_2>;
+ wakeup-source;
+ };
+
+ gpio2 {
+ label = "gpio2";
+ gpios = <&gpio6 18 GPIO_ACTIVE_LOW>; /* gpio178 */
+ linux,code = <BTN_3>;
+ wakeup-source;
+ };
+ };
+
+ sound {
+ compatible = "ti,omap-twl4030";
+ ti,model = "omap3logic";
+ ti,mcbsp = <&mcbsp2>;
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 = <&led_pins>;
+
+ led1 {
+ label = "led1";
+ gpios = <&gpio6 20 GPIO_ACTIVE_HIGH>; /* gpio180 */
+ linux,default-trigger = "cpu0";
+ };
+
+ led2 {
+ label = "led2";
+ gpios = <&gpio6 19 GPIO_ACTIVE_HIGH>; /* gpio179 */
+ linux,default-trigger = "none";
+ };
+ };
+
+ pwm10: dmtimer-pwm {
+ compatible = "ti,omap-dmtimer-pwm";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pwm_pins>;
+ ti,timers = <&timer10>;
+ #pwm-cells = <3>;
+ };
+
+};
+
+&vaux1 {
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3000000>;
+};
+
+&vaux4 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+};
+
+&mcbsp2 {
+ status = "okay";
+};
+
+&charger {
+ ti,bb-uvolt = <3200000>;
+ ti,bb-uamp = <150>;
+};
+
+&gpmc {
+ ranges = <0 0 0x30000000 0x1000000 /* CS0: 16MB for NAND */
+ 1 0 0x2c000000 0x1000000>; /* CS1: 16MB for LAN9221 */
+
+ ethernet@gpmc {
+ pinctrl-names = "default";
+ pinctrl-0 = <&lan9221_pins>;
+ interrupt-parent = <&gpio5>;
+ interrupts = <1 IRQ_TYPE_LEVEL_LOW>; /* gpio129 */
+ reg = <1 0 0xff>;
+ };
+};
+
+&vpll2 {
+ regulator-always-on;
+};
+
+&dss {
+ status = "ok";
+ vdds_dsi-supply = <&vpll2>;
+ vdda_video-supply = <&video_reg>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&dss_dpi_pins1>;
+ port {
+ dpi_out: endpoint {
+ remote-endpoint = <&lcd_in>;
+ data-lines = <16>;
+ };
+ };
+};
+
+/ {
+ aliases {
+ display0 = &lcd0;
+ };
+
+ video_reg: video_reg {
+ pinctrl-names = "default";
+ pinctrl-0 = <&panel_pwr_pins>;
+ compatible = "regulator-fixed";
+ regulator-name = "fixed-supply";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&gpio5 27 GPIO_ACTIVE_HIGH>; /* gpio155, lcd INI */
+ };
+
+ lcd0: display {
+ compatible = "panel-dpi";
+ label = "15";
+ status = "okay";
+ /* default-on; */
+ pinctrl-names = "default";
+
+ port {
+ lcd_in: endpoint {
+ remote-endpoint = <&dpi_out>;
+ };
+ };
+
+ panel-timing {
+ clock-frequency = <9000000>;
+ hactive = <480>;
+ vactive = <272>;
+ hfront-porch = <3>;
+ hback-porch = <2>;
+ hsync-len = <42>;
+ vback-porch = <3>;
+ vfront-porch = <4>;
+ vsync-len = <11>;
+ hsync-active = <0>;
+ vsync-active = <0>;
+ de-active = <1>;
+ pixelclk-active = <1>;
+ };
+ };
+
+ bl: backlight {
+ compatible = "pwm-backlight";
+ pinctrl-names = "default";
+ pinctrl-0 = <&backlight_pins>;
+ pwms = <&pwm10 0 5000000 0>;
+ brightness-levels = <0 10 20 30 40 50 60 70 80 90 100>;
+ default-brightness-level = <7>;
+ enable-gpios = <&gpio5 26 GPIO_ACTIVE_HIGH>; /* gpio_154 */
+ };
+};
+
+&mmc1 {
+ interrupts-extended = <&intc 83 &omap3_pmx_core 0x11a>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc1_pins &mmc1_cd>;
+ cd-gpios = <&gpio4 31 IRQ_TYPE_LEVEL_LOW>; /* gpio127 */
+ vmmc-supply = <&vmmc1>;
+ bus-width = <4>;
+ cap-power-off-card;
+};
+
+&mmc2 {
+ status = "disabled";
+};
+
+&omap3_pmx_core {
+ gpio_key_pins: pinmux_gpio_key_pins {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x21d6, PIN_INPUT_PULLUP | MUX_MODE4) /* mcspi2_clk.gpio_178 */
+ OMAP3_CORE1_IOPAD(0x21dc, PIN_INPUT_PULLUP | MUX_MODE4) /* mcspi2_cs0.gpio_181 */
+ >;
+ };
+
+ pwm_pins: pinmux_pwm_pins {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x20B8, PIN_OUTPUT | PIN_OFF_OUTPUT_LOW | MUX_MODE3) /* gpmc_ncs5.gpt_10_pwm_evt */
+ >;
+ };
+
+ led_pins: pinmux_led_pins {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x21d8, PIN_OUTPUT | MUX_MODE4) /* gpio_179 */
+ OMAP3_CORE1_IOPAD(0x21da, PIN_OUTPUT | MUX_MODE4) /* gpio_180 */
+ >;
+ };
+
+ mmc1_pins: pinmux_mmc1_pins {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x2144, PIN_OUTPUT | MUX_MODE0) /* sdmmc1_clk.sdmmc1_clk */
+ OMAP3_CORE1_IOPAD(0x2146, PIN_INPUT | MUX_MODE0) /* sdmmc1_cmd.sdmmc1_cmd */
+ OMAP3_CORE1_IOPAD(0x2148, PIN_INPUT | MUX_MODE0) /* sdmmc1_dat0.sdmmc1_dat0 */
+ OMAP3_CORE1_IOPAD(0x214a, PIN_INPUT | MUX_MODE0) /* sdmmc1_dat1.sdmmc1_dat1 */
+ OMAP3_CORE1_IOPAD(0x214c, PIN_INPUT | MUX_MODE0) /* sdmmc1_dat2.sdmmc1_dat2 */
+ OMAP3_CORE1_IOPAD(0x214e, PIN_INPUT | MUX_MODE0) /* sdmmc1_dat3.sdmmc1_dat3 */
+ >;
+ };
+
+ tsc2004_pins: pinmux_tsc2004_pins {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x2186, PIN_INPUT | MUX_MODE4) /* mcbsp4_dr.gpio_153 */
+ >;
+ };
+
+ backlight_pins: pinmux_backlight_pins {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x2188, PIN_OUTPUT | PIN_OFF_OUTPUT_LOW | MUX_MODE4) /* mcbsp4_dx.gpio_154 */
+ >;
+ };
+
+ isp_pins: pinmux_isp_pins {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x210c, PIN_INPUT | MUX_MODE0) /* cam_hs.cam_hs */
+ OMAP3_CORE1_IOPAD(0x210e, PIN_INPUT | MUX_MODE0) /* cam_vs.cam_vs */
+ OMAP3_CORE1_IOPAD(0x2110, PIN_INPUT | MUX_MODE0) /* cam_xclka.cam_xclka */
+ OMAP3_CORE1_IOPAD(0x2112, PIN_INPUT | MUX_MODE0) /* cam_pclk.cam_pclk */
+
+ OMAP3_CORE1_IOPAD(0x2114, PIN_INPUT | MUX_MODE0) /* cam_d0.cam_d0 */
+ OMAP3_CORE1_IOPAD(0x2116, PIN_INPUT | MUX_MODE0) /* cam_d1.cam_d1 */
+ OMAP3_CORE1_IOPAD(0x2118, PIN_INPUT | MUX_MODE0) /* cam_d2.cam_d2 */
+ OMAP3_CORE1_IOPAD(0x211c, PIN_INPUT | MUX_MODE0) /* cam_d3.cam_d3 */
+ OMAP3_CORE1_IOPAD(0x211e, PIN_INPUT | MUX_MODE0) /* cam_d4.cam_d4 */
+ OMAP3_CORE1_IOPAD(0x2120, PIN_INPUT | MUX_MODE0) /* cam_d5.cam_d5 */
+ OMAP3_CORE1_IOPAD(0x2122, PIN_INPUT | MUX_MODE0) /* cam_d6.cam_d6 */
+ OMAP3_CORE1_IOPAD(0x2124, PIN_INPUT | MUX_MODE0) /* cam_d7.cam_d7 */
+ >;
+ };
+
+ panel_pwr_pins: pinmux_panel_pwr_pins {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x218a, PIN_OUTPUT | PIN_OFF_OUTPUT_LOW | MUX_MODE4) /* mcbsp4_fs.gpio_155 */
+ >;
+ };
+
+ dss_dpi_pins1: pinmux_dss_dpi_pins1 {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x20d4, PIN_OUTPUT_PULLDOWN | PIN_OFF_OUTPUT_LOW | MUX_MODE0) /* dss_pclk.dss_pclk */
+ OMAP3_CORE1_IOPAD(0x20d6, PIN_OUTPUT_PULLDOWN | PIN_OFF_OUTPUT_LOW | MUX_MODE0) /* dss_hsync.dss_hsync */
+ OMAP3_CORE1_IOPAD(0x20d8, PIN_OUTPUT_PULLDOWN | PIN_OFF_OUTPUT_LOW | MUX_MODE0) /* dss_vsync.dss_vsync */
+ OMAP3_CORE1_IOPAD(0x20da, PIN_OUTPUT_PULLDOWN | PIN_OFF_OUTPUT_LOW | MUX_MODE0) /* dss_acbias.dss_acbias */
+
+ OMAP3_CORE1_IOPAD(0x20e8, PIN_OUTPUT_PULLDOWN | PIN_OFF_OUTPUT_LOW | MUX_MODE0) /* dss_data6.dss_data6 */
+ OMAP3_CORE1_IOPAD(0x20ea, PIN_OUTPUT_PULLDOWN | PIN_OFF_OUTPUT_LOW | MUX_MODE0) /* dss_data7.dss_data7 */
+ OMAP3_CORE1_IOPAD(0x20ec, PIN_OUTPUT_PULLDOWN | PIN_OFF_OUTPUT_LOW | MUX_MODE0) /* dss_data8.dss_data8 */
+ OMAP3_CORE1_IOPAD(0x20ee, PIN_OUTPUT_PULLDOWN | PIN_OFF_OUTPUT_LOW | MUX_MODE0) /* dss_data9.dss_data9 */
+ OMAP3_CORE1_IOPAD(0x20f0, PIN_OUTPUT_PULLDOWN | PIN_OFF_OUTPUT_LOW | MUX_MODE0) /* dss_data10.dss_data10 */
+ OMAP3_CORE1_IOPAD(0x20f2, PIN_OUTPUT_PULLDOWN | PIN_OFF_OUTPUT_LOW | MUX_MODE0) /* dss_data11.dss_data11 */
+ OMAP3_CORE1_IOPAD(0x20f4, PIN_OUTPUT_PULLDOWN | PIN_OFF_OUTPUT_LOW | MUX_MODE0) /* dss_data12.dss_data12 */
+ OMAP3_CORE1_IOPAD(0x20f6, PIN_OUTPUT_PULLDOWN | PIN_OFF_OUTPUT_LOW | MUX_MODE0) /* dss_data13.dss_data13 */
+ OMAP3_CORE1_IOPAD(0x20f8, PIN_OUTPUT_PULLDOWN | PIN_OFF_OUTPUT_LOW | MUX_MODE0) /* dss_data14.dss_data14 */
+ OMAP3_CORE1_IOPAD(0x20fa, PIN_OUTPUT_PULLDOWN | PIN_OFF_OUTPUT_LOW | MUX_MODE0) /* dss_data15.dss_data15 */
+ OMAP3_CORE1_IOPAD(0x20fc, PIN_OUTPUT_PULLDOWN | PIN_OFF_OUTPUT_LOW | MUX_MODE0) /* dss_data16.dss_data16 */
+ OMAP3_CORE1_IOPAD(0x20fe, PIN_OUTPUT_PULLDOWN | PIN_OFF_OUTPUT_LOW | MUX_MODE0) /* dss_data17.dss_data17 */
+
+ OMAP3_CORE1_IOPAD(0x2100, PIN_OUTPUT_PULLDOWN | PIN_OFF_OUTPUT_LOW | MUX_MODE3) /* dss_data18.dss_data0 */
+ OMAP3_CORE1_IOPAD(0x2102, PIN_OUTPUT_PULLDOWN | PIN_OFF_OUTPUT_LOW | MUX_MODE3) /* dss_data19.dss_data1 */
+ OMAP3_CORE1_IOPAD(0x2104, PIN_OUTPUT_PULLDOWN | PIN_OFF_OUTPUT_LOW | MUX_MODE3) /* dss_data20.dss_data2 */
+ OMAP3_CORE1_IOPAD(0x2106, PIN_OUTPUT_PULLDOWN | PIN_OFF_OUTPUT_LOW | MUX_MODE3) /* dss_data21.dss_data3 */
+ OMAP3_CORE1_IOPAD(0x2108, PIN_OUTPUT_PULLDOWN | PIN_OFF_OUTPUT_LOW | MUX_MODE3) /* dss_data22.dss_data4 */
+ OMAP3_CORE1_IOPAD(0x210a, PIN_OUTPUT_PULLDOWN | PIN_OFF_OUTPUT_LOW | MUX_MODE3) /* dss_data23.dss_data5 */
+ >;
+ };
+};
+
+&omap3_pmx_wkup {
+ gpio_key_pins_wkup: pinmux_gpio_key_pins_wkup {
+ pinctrl-single,pins = <
+ OMAP3_WKUP_IOPAD(0x2a0a, PIN_INPUT_PULLUP | MUX_MODE4) /* sys_boot0.gpio_2 */
+ OMAP3_WKUP_IOPAD(0x2a14, PIN_INPUT_PULLUP | MUX_MODE4) /* sys_boot5.gpio_7 */
+ >;
+ };
+
+ lan9221_pins: pinmux_lan9221_pins {
+ pinctrl-single,pins = <
+ OMAP3_WKUP_IOPAD(0x2a5a, PIN_INPUT | MUX_MODE4) /* reserved.gpio_129 */
+ >;
+ };
+
+ mmc1_cd: pinmux_mmc1_cd {
+ pinctrl-single,pins = <
+ OMAP3_WKUP_IOPAD(0x2a54, PIN_INPUT_PULLUP | MUX_MODE4) /* reserved.gpio_127 */
+ >;
+ };
+};
+
+&i2c2 {
+ mt9p031@48 {
+ compatible = "aptina,mt9p031";
+ reg = <0x48>;
+ clocks = <&isp 0>;
+ vaa-supply = <&vaux4>;
+ vdd-supply = <&vaux4>;
+ vdd_io-supply = <&vaux4>;
+ port {
+ mt9p031_out: endpoint {
+ input-clock-frequency = <24000000>;
+ pixel-clock-frequency = <72000000>;
+ remote-endpoint = <&ccdc_ep>;
+ };
+ };
+ };
+};
+
+&i2c3 {
+ touchscreen: tsc2004@48 {
+ compatible = "ti,tsc2004";
+ reg = <0x48>;
+ vio-supply = <&vaux1>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&tsc2004_pins>;
+ interrupts-extended = <&gpio5 25 IRQ_TYPE_EDGE_RISING>; /* gpio 153 */
+
+ touchscreen-fuzz-x = <4>;
+ touchscreen-fuzz-y = <7>;
+ touchscreen-fuzz-pressure = <2>;
+ touchscreen-size-x = <4096>;
+ touchscreen-size-y = <4096>;
+ touchscreen-max-pressure = <2048>;
+
+ ti,x-plate-ohms = <280>;
+ ti,esd-recovery-timeout-ms = <8000>;
+ };
+};
+
+&mcspi1 {
+ at25@0 {
+ compatible = "atmel,at25";
+ reg = <0>;
+ spi-max-frequency = <5000000>;
+ spi-cpha;
+ spi-cpol;
+
+ pagesize = <64>;
+ size = <32768>;
+ address-width = <16>;
+ };
+};
+
+&isp {
+ pinctrl-names = "default";
+ pinctrl-0 = <&isp_pins>;
+ ports {
+ port@0 {
+ reg = <0>;
+ ccdc_ep: endpoint {
+ remote-endpoint = <&mt9p031_out>;
+ bus-width = <8>;
+ hsync-active = <1>;
+ vsync-active = <1>;
+ pclk-sample = <0>;
+ };
+ };
+ };
+};
+
+&uart1 {
+ interrupts-extended = <&intc 72 &omap3_pmx_core OMAP3_UART1_RX>;
+};
+
+/* Wired to the tps65950 on the SOM, only the USB connector is on the devkit */
+&usb_otg_hs {
+ pinctrl-names = "default";
+ pinctrl-0 = <&hsusb_otg_pins>;
+ interface-type = <0>;
+ usb-phy = <&usb2_phy>;
+ phys = <&usb2_phy>;
+ phy-names = "usb2-phy";
+ mode = <3>;
+ power = <50>;
+};
diff --git a/arch/arm/dts/logicpd-torpedo-som.dtsi b/arch/arm/dts/logicpd-torpedo-som.dtsi
new file mode 100644
index 0000000..23c9228
--- /dev/null
+++ b/arch/arm/dts/logicpd-torpedo-som.dtsi
@@ -0,0 +1,217 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <dt-bindings/input/input.h>
+
+/ {
+ cpus {
+ cpu@0 {
+ cpu0-supply = <&vcc>;
+ };
+ };
+
+ memory@80000000 {
+ device_type = "memory";
+ reg = <0x80000000 0>;
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ user0 {
+ label = "user0";
+ gpios = <&twl_gpio 18 GPIO_ACTIVE_LOW>; /* LEDA */
+ linux,default-trigger = "none";
+ };
+ };
+
+ wl12xx_vmmc: wl12xx_vmmc {
+ compatible = "regulator-fixed";
+ regulator-name = "vwl1271";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ gpio = <&gpio5 29 0>; /* gpio157 */
+ startup-delay-us = <70000>;
+ enable-active-high;
+ vin-supply = <&vmmc2>;
+ };
+};
+
+&gpmc {
+ ranges = <0 0 0x30000000 0x1000000>; /* CS0: 16MB for NAND */
+
+ nand@0,0 {
+ compatible = "ti,omap2-nand";
+ reg = <0 0 4>; /* CS0, offset 0, IO size 4 */
+ interrupt-parent = <&gpmc>;
+ interrupts = <0 IRQ_TYPE_NONE>, /* fifoevent */
+ <1 IRQ_TYPE_NONE>; /* termcount */
+ linux,mtd-name = "micron,mt29f4g16abbda3w";
+ nand-bus-width = <16>;
+ ti,nand-ecc-opt = "bch8";
+ rb-gpios = <&gpmc 0 GPIO_ACTIVE_HIGH>; /* gpmc_wait0 */
+ gpmc,sync-clk-ps = <0>;
+ gpmc,cs-on-ns = <0>;
+ gpmc,cs-rd-off-ns = <44>;
+ gpmc,cs-wr-off-ns = <44>;
+ gpmc,adv-on-ns = <6>;
+ gpmc,adv-rd-off-ns = <34>;
+ gpmc,adv-wr-off-ns = <44>;
+ gpmc,we-off-ns = <40>;
+ gpmc,oe-off-ns = <54>;
+ gpmc,access-ns = <64>;
+ gpmc,rd-cycle-ns = <82>;
+ gpmc,wr-cycle-ns = <82>;
+ gpmc,wr-access-ns = <40>;
+ gpmc,wr-data-mux-bus-ns = <0>;
+ gpmc,device-width = <2>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ };
+};
+
+&i2c1 {
+ clock-frequency = <400000>;
+
+ twl: twl@48 {
+ reg = <0x48>;
+ interrupts = <7>; /* SYS_NIRQ cascaded to intc */
+ interrupt-parent = <&intc>;
+ twl_audio: audio {
+ compatible = "ti,twl4030-audio";
+ codec {
+ };
+ };
+ };
+};
+
+&i2c2 {
+ clock-frequency = <400000>;
+};
+
+&i2c3 {
+ clock-frequency = <400000>;
+ at24@50 {
+ compatible = "at24,24c02";
+ readonly;
+ reg = <0x50>;
+ };
+};
+
+/*
+ * Only found on the wireless SOM. For the SOM without wireless, the pins for
+ * MMC3 can be routed with jumpers to the second MMC slot on the devkit and
+ * gpio157 is not connected. So this should be OK to keep common for now,
+ * probably device tree overlays is the way to go with the various SOM and
+ * jumpering combinations for the long run.
+ */
+&mmc3 {
+ interrupts-extended = <&intc 94 &omap3_pmx_core2 0x46>;
+ pinctrl-0 = <&mmc3_pins &mmc3_core2_pins>;
+ pinctrl-names = "default";
+ vmmc-supply = <&wl12xx_vmmc>;
+ non-removable;
+ bus-width = <4>;
+ cap-power-off-card;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ wlcore: wlcore@2 {
+ compatible = "ti,wl1283";
+ reg = <2>;
+ interrupt-parent = <&gpio5>;
+ interrupts = <24 IRQ_TYPE_LEVEL_HIGH>; /* gpio 152 */
+ ref-clock-frequency = <26000000>;
+ tcxo-clock-frequency = <26000000>;
+ };
+};
+
+&omap3_pmx_core {
+ mmc3_pins: pinmux_mm3_pins {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x2164, PIN_INPUT_PULLUP | MUX_MODE3) /* sdmmc2_dat4.sdmmc3_dat0 */
+ OMAP3_CORE1_IOPAD(0x2166, PIN_INPUT_PULLUP | MUX_MODE3) /* sdmmc2_dat5.sdmmc3_dat1 */
+ OMAP3_CORE1_IOPAD(0x2168, PIN_INPUT_PULLUP | MUX_MODE3) /* sdmmc2_dat6.sdmmc3_dat2 */
+ OMAP3_CORE1_IOPAD(0x216a, PIN_INPUT_PULLUP | MUX_MODE3) /* sdmmc2_dat6.sdmmc3_dat3 */
+ OMAP3_CORE1_IOPAD(0x2184, PIN_INPUT_PULLUP | MUX_MODE4) /* mcbsp4_clkx.gpio_152 */
+ OMAP3_CORE1_IOPAD(0x218e, PIN_OUTPUT | MUX_MODE4) /* mcbsp1_fsr.gpio_157 */
+ >;
+ };
+ mcbsp2_pins: pinmux_mcbsp2_pins {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x213c, PIN_INPUT | MUX_MODE0) /* mcbsp2_fsx */
+ OMAP3_CORE1_IOPAD(0x213e, PIN_INPUT | MUX_MODE0) /* mcbsp2_clkx */
+ OMAP3_CORE1_IOPAD(0x2140, PIN_INPUT | MUX_MODE0) /* mcbsp2_dr */
+ OMAP3_CORE1_IOPAD(0x2142, PIN_OUTPUT | MUX_MODE0) /* mcbsp2_dx */
+ >;
+ };
+ uart2_pins: pinmux_uart2_pins {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x2174, PIN_INPUT | MUX_MODE0) /* uart2_cts.uart2_cts */
+ OMAP3_CORE1_IOPAD(0x2176, PIN_OUTPUT | MUX_MODE0) /* uart2_rts .uart2_rts*/
+ OMAP3_CORE1_IOPAD(0x2178, PIN_OUTPUT | MUX_MODE0) /* uart2_tx.uart2_tx */
+ OMAP3_CORE1_IOPAD(0x217a, PIN_INPUT | MUX_MODE0) /* uart2_rx.uart2_rx */
+ OMAP3_CORE1_IOPAD(0x2198, PIN_OUTPUT | MUX_MODE4) /* GPIO_162,BT_EN */
+ >;
+ };
+ mcspi1_pins: pinmux_mcspi1_pins {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x21c8, PIN_INPUT | MUX_MODE0) /* mcspi1_clk.mcspi1_clk */
+ OMAP3_CORE1_IOPAD(0x21ca, PIN_OUTPUT | MUX_MODE0) /* mcspi1_simo.mcspi1_simo */
+ OMAP3_CORE1_IOPAD(0x21cc, PIN_INPUT_PULLUP | MUX_MODE0) /* mcspi1_somi.mcspi1_somi */
+ OMAP3_CORE1_IOPAD(0x21ce, PIN_OUTPUT | MUX_MODE0) /* mcspi1_cs0.mcspi1_cs0 */
+ >;
+ };
+ hsusb_otg_pins: pinmux_hsusb_otg_pins {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x21a2, PIN_INPUT | MUX_MODE0) /* hsusb0_clk.hsusb0_clk */
+ OMAP3_CORE1_IOPAD(0x21a4, PIN_OUTPUT | MUX_MODE0) /* hsusb0_stp.hsusb0_stp */
+ OMAP3_CORE1_IOPAD(0x21a6, PIN_INPUT | MUX_MODE0) /* hsusb0_dir.hsusb0_dir */
+ OMAP3_CORE1_IOPAD(0x21a8, PIN_INPUT | MUX_MODE0) /* hsusb0_nxt.hsusb0_nxt */
+
+ OMAP3_CORE1_IOPAD(0x21aa, PIN_INPUT | MUX_MODE0) /* hsusb0_data0.hsusb0_data0 */
+ OMAP3_CORE1_IOPAD(0x21ac, PIN_INPUT | MUX_MODE0) /* hsusb0_data1.hsusb0_data1 */
+ OMAP3_CORE1_IOPAD(0x21ae, PIN_INPUT | MUX_MODE0) /* hsusb0_data2.hsusb0_data2 */
+ OMAP3_CORE1_IOPAD(0x21b0, PIN_INPUT | MUX_MODE0) /* hsusb0_data3.hsusb0_data3 */
+ OMAP3_CORE1_IOPAD(0x21b2, PIN_INPUT | MUX_MODE0) /* hsusb0_data4.hsusb0_data4 */
+ OMAP3_CORE1_IOPAD(0x21b4, PIN_INPUT | MUX_MODE0) /* hsusb0_data5.hsusb0_data5 */
+ OMAP3_CORE1_IOPAD(0x21b6, PIN_INPUT | MUX_MODE0) /* hsusb0_data6.hsusb0_data6 */
+ OMAP3_CORE1_IOPAD(0x21b8, PIN_INPUT | MUX_MODE0) /* hsusb0_data7.hsusb0_data7 */
+ >;
+ };
+};
+
+&uart2 {
+ interrupts-extended = <&intc 73 &omap3_pmx_core OMAP3_UART2_RX>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart2_pins>;
+};
+
+&mcspi1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mcspi1_pins>;
+};
+
+&omap3_pmx_core2 {
+ mmc3_core2_pins: pinmux_mmc3_core2_pins {
+ pinctrl-single,pins = <
+ OMAP3630_CORE2_IOPAD(0x25d8, PIN_INPUT_PULLUP | MUX_MODE2) /* etk_clk.sdmmc3_clk */
+ OMAP3630_CORE2_IOPAD(0x25da, PIN_INPUT_PULLUP | MUX_MODE2) /* etk_ctl.sdmmc3_cmd */
+ >;
+ };
+};
+
+#include "twl4030.dtsi"
+#include "twl4030_omap3.dtsi"
+
+&twl {
+ twl_power: power {
+ compatible = "ti,twl4030-power-idle-osc-off", "ti,twl4030-power-idle";
+ ti,use_poweroff;
+ };
+};
+
+&twl_gpio {
+ ti,use-leds;
+};
diff --git a/arch/arm/mach-omap2/omap3/Kconfig b/arch/arm/mach-omap2/omap3/Kconfig
index 933fcba..a9d7e29 100644
--- a/arch/arm/mach-omap2/omap3/Kconfig
+++ b/arch/arm/mach-omap2/omap3/Kconfig
@@ -67,7 +67,6 @@ config TARGET_MCX
config TARGET_OMAP3_LOGIC
bool "OMAP3 Logic"
- select BOARD_LATE_INIT
select DM
select DM_SERIAL
select DM_GPIO
diff --git a/board/logicpd/omap3som/omap3logic.c b/board/logicpd/omap3som/omap3logic.c
index 4ad496e..495bc73 100644
--- a/board/logicpd/omap3som/omap3logic.c
+++ b/board/logicpd/omap3som/omap3logic.c
@@ -40,53 +40,6 @@ DECLARE_GLOBAL_DATA_PTR;
#define GPIO_IO_PWRDNZ (1 << 6)
#define PBIASLITEVMODE1 (1 << 8)
-/*
- * two dimensional array of strucures containining board name and Linux
- * machine IDs; row it selected based on CPU column is slected based
- * on hsusb0_data5 pin having a pulldown resistor
- */
-
-static const struct ns16550_platdata omap3logic_serial = {
- .base = OMAP34XX_UART1,
- .reg_shift = 2,
- .clock = V_NS16550_CLK,
- .fcr = UART_FCR_DEFVAL,
-};
-
-U_BOOT_DEVICE(omap3logic_uart) = {
- "ns16550_serial",
- &omap3logic_serial
-};
-
-static struct board_id {
- char *name;
- int machine_id;
- char *fdtfile;
-} boards[2][2] = {
- {
- {
- .name = "OMAP35xx SOM LV",
- .machine_id = MACH_TYPE_OMAP3530_LV_SOM,
- .fdtfile = "logicpd-som-lv-35xx-devkit.dtb",
- },
- {
- .name = "OMAP35xx Torpedo",
- .machine_id = MACH_TYPE_OMAP3_TORPEDO,
- .fdtfile = "logicpd-torpedo-35xx-devkit.dtb",
- },
- },
- {
- {
- .name = "DM37xx SOM LV",
- .fdtfile = "logicpd-som-lv-37xx-devkit.dtb",
- },
- {
- .name = "DM37xx Torpedo",
- .fdtfile = "logicpd-torpedo-37xx-devkit.dtb",
- },
- },
-};
-
#ifdef CONFIG_SPL_OS_BOOT
int spl_start_uboot(void)
{
@@ -159,11 +112,6 @@ int misc_init_r(void)
}
/*
- * BOARD_ID_GPIO - GPIO of pin with optional pulldown resistor on SOM LV
- */
-#define BOARD_ID_GPIO 189 /* hsusb0_data5 pin */
-
-/*
* Routine: board_init
* Description: Early hardware init.
*/
@@ -177,60 +125,6 @@ int board_init(void)
return 0;
}
-#ifdef CONFIG_BOARD_LATE_INIT
-int board_late_init(void)
-{
- struct board_id *board;
- unsigned int val;
-
- /*
- * To identify between a SOM LV and Torpedo module,
- * a pulldown resistor is on hsusb0_data5 for the SOM LV module.
- * Drive the pin (and let it soak), then read it back.
- * If the pin is still high its a Torpedo. If low its a SOM LV
- */
-
- /* Mux hsusb0_data5 as a GPIO */
- MUX_VAL(CP(HSUSB0_DATA5), (IEN | PTD | DIS | M4));
-
- if (gpio_request(BOARD_ID_GPIO, "husb0_data5.gpio_189") == 0) {
-
- /*
- * Drive BOARD_ID_GPIO - the pulldown resistor on the SOM LV
- * will drain the voltage.
- */
- gpio_direction_output(BOARD_ID_GPIO, 0);
- gpio_set_value(BOARD_ID_GPIO, 1);
-
- /* Let it soak for a bit */
- sdelay(0x100);
-
- /*
- * Read state of BOARD_ID_GPIO as an input and if its set.
- * If so the board is a Torpedo
- */
- gpio_direction_input(BOARD_ID_GPIO);
- val = gpio_get_value(BOARD_ID_GPIO);
- gpio_free(BOARD_ID_GPIO);
-
- board = &boards[!!(get_cpu_family() == CPU_OMAP36XX)][!!val];
- printf("Board: %s\n", board->name);
-
- /* Set the machine_id passed to Linux */
- if (board->machine_id)
- gd->bd->bi_arch_number = board->machine_id;
-
- /* If the user has not set fdtimage, set the default */
- if (!getenv("fdtimage"))
- setenv("fdtimage", board->fdtfile);
- }
-
- /* restore hsusb0_data5 pin as hsusb0_data5 */
- MUX_VAL(CP(HSUSB0_DATA5), (IEN | PTD | DIS | M0));
- return 0;
-}
-#endif
-
#if defined(CONFIG_GENERIC_MMC)
int board_mmc_init(bd_t *bis)
{
@@ -598,3 +492,18 @@ void set_muxconf_regs(void)
MUX_VAL(CP(D2D_MBUSFLAG), (IEN | PTD | DIS | M0)); /*d2d_mbusflag*/
MUX_VAL(CP(D2D_SBUSFLAG), (IEN | PTD | DIS | M0)); /*d2d_sbusflag*/
}
+
+/* This is only needed until SPL gets OF support */
+#ifdef CONFIG_SPL_BUILD
+static const struct ns16550_platdata omap3logic_serial = {
+ .base = OMAP34XX_UART1,
+ .reg_shift = 2,
+ .clock = V_NS16550_CLK,
+ .fcr = UART_FCR_DEFVAL,
+};
+
+U_BOOT_DEVICE(omap3logic_uart) = {
+ "ns16550_serial",
+ &omap3logic_serial
+};
+#endif
diff --git a/configs/omap3_logic_defconfig b/configs/omap3_logic_defconfig
index 89bf38f..13c996d 100644
--- a/configs/omap3_logic_defconfig
+++ b/configs/omap3_logic_defconfig
@@ -3,6 +3,7 @@ CONFIG_OMAP34XX=y
CONFIG_SYS_MALLOC_F_LEN=0x2000
CONFIG_TARGET_OMAP3_LOGIC=y
CONFIG_SPL_STACK_R_ADDR=0x82000000
+CONFIG_DEFAULT_DEVICE_TREE="logicpd-torpedo-37xx-devkit"
CONFIG_SYS_EXTRA_OPTIONS="NAND"
CONFIG_SYS_CONSOLE_INFO_QUIET=y
CONFIG_VERSION_VARIABLE=y
@@ -36,6 +37,11 @@ CONFIG_CMD_FS_GENERIC=y
CONFIG_CMD_UBI=y
CONFIG_ISO_PARTITION=y
CONFIG_EFI_PARTITION=y
+CONFIG_OF_CONTROL=y
+# CONFIG_BLK is not set
+CONFIG_DM_I2C=y
+CONFIG_DM_MMC=y
+# CONFIG_DM_MMC_OPS is not set
CONFIG_MMC_OMAP_HS=y
CONFIG_MMC_OMAP36XX_PINS=y
CONFIG_SYS_NS16550=y
@@ -46,4 +52,3 @@ CONFIG_USB_GADGET_DOWNLOAD=y
CONFIG_G_DNL_MANUFACTURER="TI"
CONFIG_G_DNL_VENDOR_NUM=0x0451
CONFIG_G_DNL_PRODUCT_NUM=0xd022
-CONFIG_OF_LIBFDT=y
diff --git a/configs/omap3_logic_somlv_defconfig b/configs/omap3_logic_somlv_defconfig
new file mode 100644
index 0000000..2b1eeba
--- /dev/null
+++ b/configs/omap3_logic_somlv_defconfig
@@ -0,0 +1,54 @@
+CONFIG_ARM=y
+CONFIG_OMAP34XX=y
+CONFIG_SYS_MALLOC_F_LEN=0x2000
+CONFIG_TARGET_OMAP3_LOGIC=y
+CONFIG_SPL_STACK_R_ADDR=0x82000000
+CONFIG_DEFAULT_DEVICE_TREE="logicpd-som-lv-37xx-devkit"
+CONFIG_SYS_EXTRA_OPTIONS="NAND"
+CONFIG_SYS_CONSOLE_INFO_QUIET=y
+CONFIG_VERSION_VARIABLE=y
+CONFIG_SPL=y
+CONFIG_SPL_SYS_MALLOC_SIMPLE=y
+CONFIG_SPL_STACK_R=y
+CONFIG_SPL_MTD_SUPPORT=y
+CONFIG_SPL_OS_BOOT=y
+CONFIG_HUSH_PARSER=y
+CONFIG_SYS_PROMPT="OMAP Logic # "
+CONFIG_CMD_BOOTZ=y
+# CONFIG_CMD_IMI is not set
+# CONFIG_CMD_IMLS is not set
+CONFIG_CMD_ASKENV=y
+# CONFIG_CMD_FLASH is not set
+CONFIG_CMD_MMC=y
+CONFIG_CMD_PART=y
+CONFIG_CMD_SPI=y
+CONFIG_CMD_I2C=y
+# CONFIG_CMD_FPGA is not set
+CONFIG_CMD_GPIO=y
+CONFIG_CMD_DHCP=y
+CONFIG_CMD_MII=y
+CONFIG_CMD_PING=y
+CONFIG_CMD_CACHE=y
+CONFIG_CMD_EXT2=y
+CONFIG_CMD_EXT4=y
+CONFIG_CMD_EXT4_WRITE=y
+CONFIG_CMD_FAT=y
+CONFIG_CMD_FS_GENERIC=y
+CONFIG_CMD_UBI=y
+CONFIG_ISO_PARTITION=y
+CONFIG_EFI_PARTITION=y
+CONFIG_OF_CONTROL=y
+# CONFIG_BLK is not set
+CONFIG_DM_I2C=y
+CONFIG_DM_MMC=y
+# CONFIG_DM_MMC_OPS is not set
+CONFIG_MMC_OMAP_HS=y
+CONFIG_MMC_OMAP36XX_PINS=y
+CONFIG_SYS_NS16550=y
+CONFIG_USB=y
+CONFIG_USB_MUSB_GADGET=y
+CONFIG_USB_GADGET=y
+CONFIG_USB_GADGET_DOWNLOAD=y
+CONFIG_G_DNL_MANUFACTURER="TI"
+CONFIG_G_DNL_VENDOR_NUM=0x0451
+CONFIG_G_DNL_PRODUCT_NUM=0xd022
diff --git a/include/configs/omap3_logic.h b/include/configs/omap3_logic.h
index 706175c..dde52e7 100644
--- a/include/configs/omap3_logic.h
+++ b/include/configs/omap3_logic.h
@@ -17,6 +17,20 @@
#include <configs/ti_omap3_common.h>
+#ifdef CONFIG_SPL_BUILD
+/*
+ * Disable MMC DM for SPL build and can be re-enabled after adding
+ * DM support in SPL
+ */
+#undef CONFIG_DM_MMC
+#undef OMAP_HSMMC_USE_GPIO
+
+/* select serial console configuration for SPL */
+#undef CONFIG_CONS_INDEX
+#define CONFIG_CONS_INDEX 1
+#define CONFIG_SYS_NS16550_COM1 OMAP34XX_UART1
+#endif
+
/*
* We are only ever GP parts and will utilize all of the "downloaded image"
* area in SRAM which starts at 0x40200000 and ends at 0x4020FFFF (64KB) in
@@ -34,16 +48,10 @@
/* Hardware drivers */
/* GPIO banks */
-#define CONFIG_OMAP3_GPIO_6 /* GPIO160..191 is in GPIO bank 6 */
+#define CONFIG_OMAP3_GPIO_4 /* GPIO 96..128 is in GPIO bank 4 */
#define CONFIG_USB_OMAP3
-/* select serial console configuration */
-#undef CONFIG_CONS_INDEX
-#define CONFIG_CONS_INDEX 1
-#define CONFIG_SYS_NS16550_COM1 OMAP34XX_UART1
-#define CONFIG_SERIAL1 1 /* UART1 on OMAP Logic boards */
-
/* commands to include */
#define CONFIG_CMD_NAND
#define CONFIG_CMD_MTDPARTS
@@ -52,8 +60,6 @@
/* I2C */
#define CONFIG_SYS_I2C_OMAP34XX
#define CONFIG_SYS_I2C_EEPROM_ADDR 0x50 /* EEPROM AT24C64 */
-#define EXPANSION_EEPROM_I2C_BUS 2 /* I2C Bus for AT24C64 */
-#define CONFIG_OMAP3_LOGIC_USE_NEW_PRODUCT_ID
/* USB */
#define CONFIG_USB_MUSB_OMAP2PLUS
@@ -138,6 +144,7 @@
"fi; " \
"else run defaultboot; fi\0" \
"defaultboot=run mmcramboot\0" \
+ "fdtimage=" CONFIG_DEFAULT_DEVICE_TREE ".dtb\0" \
"consoledevice=ttyO0\0" \
"setconsole=setenv console ${consoledevice},${baudrate}n8\0" \
"dump_bootargs=echo 'Bootargs: '; echo $bootargs\0" \
--
2.7.4
2
3

[U-Boot] [PATCH 6/7] OMAP3: Add SMSC9221 device tree for omap devices connected on GPMC.
by Adam Ford 12 Apr '17
by Adam Ford 12 Apr '17
12 Apr '17
Some OMAP3 devices support an SMSC ethernet PHY connected to the GPMC bus.
This copies this device tree from Linux 4.9.y stable
Signed-off-by: Adam Ford <aford173(a)gmail.com>
Reviewed-by: Lokesh Vutla <lokeshvutla(a)ti.com>
diff --git a/arch/arm/dts/omap-gpmc-smsc9221.dtsi b/arch/arm/dts/omap-gpmc-smsc9221.dtsi
new file mode 100644
index 0000000..73e272f
--- /dev/null
+++ b/arch/arm/dts/omap-gpmc-smsc9221.dtsi
@@ -0,0 +1,58 @@
+/*
+ * Common file for GPMC connected smsc9221 on omaps
+ *
+ * Compared to smsc911x, smsc9221 (and others like smsc9217
+ * or smsc 9218) has faster timings, leading to higher
+ * bandwidth.
+ *
+ * Note that the board specifc DTS file needs to specify
+ * ranges, pinctrl, reg, interrupt parent and interrupts.
+ */
+
+/ {
+ vddvario: regulator-vddvario {
+ compatible = "regulator-fixed";
+ regulator-name = "vddvario";
+ regulator-always-on;
+ };
+
+ vdd33a: regulator-vdd33a {
+ compatible = "regulator-fixed";
+ regulator-name = "vdd33a";
+ regulator-always-on;
+ };
+};
+
+&gpmc {
+ ethernet@gpmc {
+ compatible = "smsc,lan9221","smsc,lan9115";
+ bank-width = <2>;
+
+ gpmc,mux-add-data;
+ gpmc,cs-on-ns = <0>;
+ gpmc,cs-rd-off-ns = <42>;
+ gpmc,cs-wr-off-ns = <36>;
+ gpmc,adv-on-ns = <6>;
+ gpmc,adv-rd-off-ns = <12>;
+ gpmc,adv-wr-off-ns = <12>;
+ gpmc,oe-on-ns = <0>;
+ gpmc,oe-off-ns = <42>;
+ gpmc,we-on-ns = <0>;
+ gpmc,we-off-ns = <36>;
+ gpmc,rd-cycle-ns = <60>;
+ gpmc,wr-cycle-ns = <54>;
+ gpmc,access-ns = <36>;
+ gpmc,page-burst-access-ns = <0>;
+ gpmc,bus-turnaround-ns = <0>;
+ gpmc,cycle2cycle-delay-ns = <0>;
+ gpmc,wr-data-mux-bus-ns = <18>;
+ gpmc,wr-access-ns = <42>;
+ gpmc,cycle2cycle-samecsen;
+ gpmc,cycle2cycle-diffcsen;
+
+ vddvario-supply = <&vddvario>;
+ vdd33a-supply = <&vdd33a>;
+ reg-io-width = <4>;
+ smsc,save-mac-address;
+ };
+};
--
2.7.4
2
1

[U-Boot] [PATCH 5/7] omap3: Copy twl4030 device tree from Linux 4.9.y stable
by Adam Ford 12 Apr '17
by Adam Ford 12 Apr '17
12 Apr '17
Many OMAP3 boards use a TWL4030 PMIC. This brings in the related
device tree information for common TWL4030 and TWL4030 with OMAP3.
Signed-off-by: Adam Ford <aford173(a)gmail.com>
Reviewed-by: Lokesh Vutla <lokeshvutla(a)ti.com>
diff --git a/arch/arm/dts/twl4030.dtsi b/arch/arm/dts/twl4030.dtsi
new file mode 100644
index 0000000..6cb0a01
--- /dev/null
+++ b/arch/arm/dts/twl4030.dtsi
@@ -0,0 +1,161 @@
+/*
+ * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/*
+ * Integrated Power Management Chip
+ */
+&twl {
+ compatible = "ti,twl4030";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+
+ rtc {
+ compatible = "ti,twl4030-rtc";
+ interrupts = <11>;
+ };
+
+ charger: bci {
+ compatible = "ti,twl4030-bci";
+ interrupts = <9>, <2>;
+ bci3v1-supply = <&vusb3v1>;
+ };
+
+ watchdog {
+ compatible = "ti,twl4030-wdt";
+ };
+
+ vaux1: regulator-vaux1 {
+ compatible = "ti,twl4030-vaux1";
+ };
+
+ vaux2: regulator-vaux2 {
+ compatible = "ti,twl4030-vaux2";
+ };
+
+ vaux3: regulator-vaux3 {
+ compatible = "ti,twl4030-vaux3";
+ };
+
+ vaux4: regulator-vaux4 {
+ compatible = "ti,twl4030-vaux4";
+ };
+
+ vcc: regulator-vdd1 {
+ compatible = "ti,twl4030-vdd1";
+ regulator-min-microvolt = <600000>;
+ regulator-max-microvolt = <1450000>;
+ };
+
+ vdac: regulator-vdac {
+ compatible = "ti,twl4030-vdac";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ vio: regulator-vio {
+ compatible = "ti,twl4030-vio";
+ };
+
+ vintana1: regulator-vintana1 {
+ compatible = "ti,twl4030-vintana1";
+ };
+
+ vintana2: regulator-vintana2 {
+ compatible = "ti,twl4030-vintana2";
+ };
+
+ vintdig: regulator-vintdig {
+ compatible = "ti,twl4030-vintdig";
+ };
+
+ vmmc1: regulator-vmmc1 {
+ compatible = "ti,twl4030-vmmc1";
+ regulator-min-microvolt = <1850000>;
+ regulator-max-microvolt = <3150000>;
+ };
+
+ vmmc2: regulator-vmmc2 {
+ compatible = "ti,twl4030-vmmc2";
+ regulator-min-microvolt = <1850000>;
+ regulator-max-microvolt = <3150000>;
+ };
+
+ vusb1v5: regulator-vusb1v5 {
+ compatible = "ti,twl4030-vusb1v5";
+ };
+
+ vusb1v8: regulator-vusb1v8 {
+ compatible = "ti,twl4030-vusb1v8";
+ };
+
+ vusb3v1: regulator-vusb3v1 {
+ compatible = "ti,twl4030-vusb3v1";
+ };
+
+ vpll1: regulator-vpll1 {
+ compatible = "ti,twl4030-vpll1";
+ };
+
+ vpll2: regulator-vpll2 {
+ compatible = "ti,twl4030-vpll2";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ vsim: regulator-vsim {
+ compatible = "ti,twl4030-vsim";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3000000>;
+ };
+
+ twl_gpio: gpio {
+ compatible = "ti,twl4030-gpio";
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
+
+ usb2_phy: twl4030-usb {
+ compatible = "ti,twl4030-usb";
+ interrupts = <10>, <4>;
+ usb1v5-supply = <&vusb1v5>;
+ usb1v8-supply = <&vusb1v8>;
+ usb3v1-supply = <&vusb3v1>;
+ usb_mode = <1>;
+ #phy-cells = <0>;
+ };
+
+ twl_pwm: pwm {
+ compatible = "ti,twl4030-pwm";
+ #pwm-cells = <2>;
+ };
+
+ twl_pwmled: pwmled {
+ compatible = "ti,twl4030-pwmled";
+ #pwm-cells = <2>;
+ };
+
+ twl_pwrbutton: pwrbutton {
+ compatible = "ti,twl4030-pwrbutton";
+ interrupts = <8>;
+ };
+
+ twl_keypad: keypad {
+ compatible = "ti,twl4030-keypad";
+ interrupts = <1>;
+ keypad,num-rows = <8>;
+ keypad,num-columns = <8>;
+ };
+
+ twl_madc: madc {
+ compatible = "ti,twl4030-madc";
+ interrupts = <3>;
+ #io-channel-cells = <1>;
+ };
+};
diff --git a/arch/arm/dts/twl4030_omap3.dtsi b/arch/arm/dts/twl4030_omap3.dtsi
new file mode 100644
index 0000000..f9aaa53
--- /dev/null
+++ b/arch/arm/dts/twl4030_omap3.dtsi
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2013 Linaro, Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+&twl {
+ pinctrl-names = "default";
+ pinctrl-0 = <&twl4030_pins &twl4030_vpins>;
+};
+
+&omap3_pmx_core {
+ /*
+ * On most OMAP3 platforms, the twl4030 IRQ line is connected
+ * to the SYS_NIRQ line on OMAP. Therefore, configure the
+ * defaults for the SYS_NIRQ pin here.
+ */
+ twl4030_pins: pinmux_twl4030_pins {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x21e0, PIN_INPUT_PULLUP | PIN_OFF_WAKEUPENABLE | MUX_MODE0) /* sys_nirq.sys_nirq */
+ >;
+ };
+};
+
+/*
+ * If your board is not using the I2C4 pins with twl4030, then don't include
+ * this file. For proper idle mode signaling with sys_clkreq and sys_off_mode
+ * pins we need to configure I2C4, or else use the legacy sys_nvmode1 and
+ * sys_nvmode2 signaling.
+ */
+&omap3_pmx_wkup {
+ twl4030_vpins: pinmux_twl4030_vpins {
+ pinctrl-single,pins = <
+ OMAP3_WKUP_IOPAD(0x2a00, PIN_INPUT | MUX_MODE0) /* i2c4_scl.i2c4_scl */
+ OMAP3_WKUP_IOPAD(0x2a02, PIN_INPUT | MUX_MODE0) /* i2c4_sda.i2c4_sda */
+ OMAP3_WKUP_IOPAD(0x2a06, PIN_OUTPUT | MUX_MODE0) /* sys_clkreq.sys_clkreq */
+ OMAP3_WKUP_IOPAD(0x2a18, PIN_OUTPUT | MUX_MODE0) /* sys_off_mode.sys_off_mode */
+ >;
+ };
+};
--
2.7.4
2
1

[U-Boot] [PATCH 4/7] ARM: OMAP: I2C: Support New read, write and probe functions for OMAP3
by Adam Ford 12 Apr '17
by Adam Ford 12 Apr '17
12 Apr '17
New i2c_read, i2c_write and i2c_probe functions, tested on OMAP4
(4430/60/70), OMAP5 (5430) and AM335X (3359) were added in 960187ffa125(
"ARM: OMAP: I2C: New read, write and probe functions") but not tested
on OMAP3. This patch will allow the updated drivers using device tree and
DM_I2C to operate on OMAP3.
Signed-off-by: Adam Ford <aford173(a)gmail.com>
Reviewed-by: Lokesh Vutla <lokeshvutla(a)ti.com>
diff --git a/drivers/i2c/omap24xx_i2c.c b/drivers/i2c/omap24xx_i2c.c
index 26996e9..a23737a 100644
--- a/drivers/i2c/omap24xx_i2c.c
+++ b/drivers/i2c/omap24xx_i2c.c
@@ -910,6 +910,7 @@ static const struct dm_i2c_ops omap_i2c_ops = {
};
static const struct udevice_id omap_i2c_ids[] = {
+ { .compatible = "ti,omap3-i2c" },
{ .compatible = "ti,omap4-i2c" },
{ }
};
--
2.7.4
2
1