* Add U-Boot patches for NVMe boot support Add NVMe to boot order. Fix NVMe support on 64-bit Raspberry Pi devices. This is useful for Raspberry Pi Compute Module 4 IO Board where a native NVMe can be plugged in. * Enable NVMe support for Raspberry Pi 4 Our machine configuration rpi4 and rpi4_64 work on the Compute Module IO Board. In this configuration a NVMe SSD can be used. Therefor, enable support for NVMe in the Raspberry Pi 4 configurations. Note: Regular Raspberry Pi devices will not notice a difference as the "nvme scan" command will return very quickly and not find a NVMe on the PCIe bus. * Use built-in NVMe support in Kernel for NVMe boot support
264 lines
9.0 KiB
Diff
264 lines
9.0 KiB
Diff
From 7e71ddff9abedfda11fa6c8cc1ba2b5729af9a95 Mon Sep 17 00:00:00 2001
|
|
Message-Id: <7e71ddff9abedfda11fa6c8cc1ba2b5729af9a95.1632816160.git.stefan@agner.ch>
|
|
In-Reply-To: <cb3001355d465fa4a2f80cd186700a7bd27ca354.1632816160.git.stefan@agner.ch>
|
|
References: <cb3001355d465fa4a2f80cd186700a7bd27ca354.1632816160.git.stefan@agner.ch>
|
|
From: Stefan Agner <stefan@agner.ch>
|
|
Date: Thu, 23 Sep 2021 23:58:35 +0200
|
|
Subject: [PATCH 6/8] nvme: Use pointer for CPU addressed buffers
|
|
|
|
Pass buffers which use CPU addressing as void pointers. This aligns with
|
|
DMA APIs which use void pointers as argument. It will avoid unnecessary
|
|
type casts when adding support bus address translations.
|
|
|
|
Signed-off-by: Stefan Agner <stefan@agner.ch>
|
|
---
|
|
drivers/nvme/nvme.c | 50 ++++++++++++++++++++--------------------
|
|
drivers/nvme/nvme_show.c | 4 ++--
|
|
include/nvme.h | 12 +++++-----
|
|
3 files changed, 33 insertions(+), 33 deletions(-)
|
|
|
|
diff --git a/drivers/nvme/nvme.c b/drivers/nvme/nvme.c
|
|
index 677e66b1bb..4c4dc7cc4d 100644
|
|
--- a/drivers/nvme/nvme.c
|
|
+++ b/drivers/nvme/nvme.c
|
|
@@ -74,11 +74,11 @@ static int nvme_wait_ready(struct nvme_dev *dev, bool enabled)
|
|
}
|
|
|
|
static int nvme_setup_prps(struct nvme_dev *dev, u64 *prp2,
|
|
- int total_len, u64 dma_addr)
|
|
+ int total_len, void *buffer)
|
|
{
|
|
const u32 page_size = dev->page_size;
|
|
const u32 prps_per_page = (page_size >> 3) - 1;
|
|
- int offset = dma_addr & (page_size - 1);
|
|
+ int offset = (uintptr_t)buffer & (page_size - 1);
|
|
u64 *prp_pool;
|
|
int length = total_len;
|
|
int i, nprps;
|
|
@@ -92,10 +92,10 @@ static int nvme_setup_prps(struct nvme_dev *dev, u64 *prp2,
|
|
}
|
|
|
|
if (length)
|
|
- dma_addr += (page_size - offset);
|
|
+ buffer += (page_size - offset);
|
|
|
|
if (length <= page_size) {
|
|
- *prp2 = dma_addr;
|
|
+ *prp2 = (u64)buffer;
|
|
return 0;
|
|
}
|
|
|
|
@@ -125,11 +125,11 @@ static int nvme_setup_prps(struct nvme_dev *dev, u64 *prp2,
|
|
i = 0;
|
|
prp_pool += page_size;
|
|
}
|
|
- *(prp_pool + i++) = cpu_to_le64(dma_addr);
|
|
- dma_addr += page_size;
|
|
+ *(prp_pool + i++) = cpu_to_le64((u64)buffer);
|
|
+ buffer += page_size;
|
|
nprps--;
|
|
}
|
|
- *prp2 = (ulong)dev->prp_pool;
|
|
+ *prp2 = (u64)dev->prp_pool;
|
|
|
|
flush_dcache_range((ulong)dev->prp_pool, (ulong)dev->prp_pool +
|
|
dev->prp_entry_num * sizeof(u64));
|
|
@@ -450,42 +450,42 @@ static int nvme_alloc_sq(struct nvme_dev *dev, u16 qid,
|
|
}
|
|
|
|
int nvme_identify(struct nvme_dev *dev, unsigned nsid,
|
|
- unsigned cns, dma_addr_t dma_addr)
|
|
+ unsigned int cns, void *buffer)
|
|
{
|
|
struct nvme_command c;
|
|
u32 page_size = dev->page_size;
|
|
- int offset = dma_addr & (page_size - 1);
|
|
+ int offset = (uintptr_t)buffer & (page_size - 1);
|
|
int length = sizeof(struct nvme_id_ctrl);
|
|
int ret;
|
|
|
|
memset(&c, 0, sizeof(c));
|
|
c.identify.opcode = nvme_admin_identify;
|
|
c.identify.nsid = cpu_to_le32(nsid);
|
|
- c.identify.prp1 = cpu_to_le64(dma_addr);
|
|
+ c.identify.prp1 = cpu_to_le64((u64)buffer);
|
|
|
|
length -= (page_size - offset);
|
|
if (length <= 0) {
|
|
c.identify.prp2 = 0;
|
|
} else {
|
|
- dma_addr += (page_size - offset);
|
|
- c.identify.prp2 = cpu_to_le64(dma_addr);
|
|
+ buffer += (page_size - offset);
|
|
+ c.identify.prp2 = cpu_to_le64((u64)buffer);
|
|
}
|
|
|
|
c.identify.cns = cpu_to_le32(cns);
|
|
|
|
- invalidate_dcache_range(dma_addr,
|
|
- dma_addr + sizeof(struct nvme_id_ctrl));
|
|
+ invalidate_dcache_range((uintptr_t)buffer,
|
|
+ (uintptr_t)buffer + sizeof(struct nvme_id_ctrl));
|
|
|
|
ret = nvme_submit_admin_cmd(dev, &c, NULL);
|
|
if (!ret)
|
|
- invalidate_dcache_range(dma_addr,
|
|
- dma_addr + sizeof(struct nvme_id_ctrl));
|
|
+ invalidate_dcache_range((uintptr_t)buffer,
|
|
+ (uintptr_t)buffer + sizeof(struct nvme_id_ctrl));
|
|
|
|
return ret;
|
|
}
|
|
|
|
int nvme_get_features(struct nvme_dev *dev, unsigned fid, unsigned nsid,
|
|
- dma_addr_t dma_addr, u32 *result)
|
|
+ void *buffer, u32 *result)
|
|
{
|
|
struct nvme_command c;
|
|
int ret;
|
|
@@ -493,7 +493,7 @@ int nvme_get_features(struct nvme_dev *dev, unsigned fid, unsigned nsid,
|
|
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.prp1 = cpu_to_le64((u64)buffer);
|
|
c.features.fid = cpu_to_le32(fid);
|
|
|
|
ret = nvme_submit_admin_cmd(dev, &c, result);
|
|
@@ -513,13 +513,13 @@ int nvme_get_features(struct nvme_dev *dev, unsigned fid, unsigned nsid,
|
|
}
|
|
|
|
int nvme_set_features(struct nvme_dev *dev, unsigned fid, unsigned dword11,
|
|
- dma_addr_t dma_addr, u32 *result)
|
|
+ void *buffer, 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.prp1 = cpu_to_le64((u64)buffer);
|
|
c.features.fid = cpu_to_le32(fid);
|
|
c.features.dword11 = cpu_to_le32(dword11);
|
|
|
|
@@ -570,7 +570,7 @@ static int nvme_set_queue_count(struct nvme_dev *dev, int count)
|
|
u32 q_count = (count - 1) | ((count - 1) << 16);
|
|
|
|
status = nvme_set_features(dev, NVME_FEAT_NUM_QUEUES,
|
|
- q_count, 0, &result);
|
|
+ q_count, NULL, &result);
|
|
|
|
if (status < 0)
|
|
return status;
|
|
@@ -622,7 +622,7 @@ static int nvme_get_info_from_identify(struct nvme_dev *dev)
|
|
if (!ctrl)
|
|
return -ENOMEM;
|
|
|
|
- ret = nvme_identify(dev, 0, 1, (dma_addr_t)(long)ctrl);
|
|
+ ret = nvme_identify(dev, 0, 1, ctrl);
|
|
if (ret) {
|
|
free(ctrl);
|
|
return -EIO;
|
|
@@ -708,7 +708,7 @@ static int nvme_blk_probe(struct udevice *udev)
|
|
ns->dev = ndev;
|
|
/* extract the namespace id from the block device name */
|
|
ns->ns_id = trailing_strtol(udev->name);
|
|
- if (nvme_identify(ndev, ns->ns_id, 0, (dma_addr_t)(long)id)) {
|
|
+ if (nvme_identify(ndev, ns->ns_id, 0, id)) {
|
|
free(id);
|
|
return -EIO;
|
|
}
|
|
@@ -770,7 +770,7 @@ static ulong nvme_blk_rw(struct udevice *udev, lbaint_t blknr,
|
|
}
|
|
|
|
if (nvme_setup_prps(dev, &prp2,
|
|
- lbas << ns->lba_shift, (ulong)buffer))
|
|
+ lbas << ns->lba_shift, buffer))
|
|
return -EIO;
|
|
c.rw.slba = cpu_to_le64(slba);
|
|
slba += lbas;
|
|
@@ -889,7 +889,7 @@ static int nvme_probe(struct udevice *udev)
|
|
char name[20];
|
|
|
|
memset(id, 0, sizeof(*id));
|
|
- if (nvme_identify(ndev, i, 0, (dma_addr_t)(long)id)) {
|
|
+ if (nvme_identify(ndev, i, 0, id)) {
|
|
ret = -EIO;
|
|
goto free_id;
|
|
}
|
|
diff --git a/drivers/nvme/nvme_show.c b/drivers/nvme/nvme_show.c
|
|
index 15e459da1a..c30adfada5 100644
|
|
--- a/drivers/nvme/nvme_show.c
|
|
+++ b/drivers/nvme/nvme_show.c
|
|
@@ -111,14 +111,14 @@ int nvme_print_info(struct udevice *udev)
|
|
ALLOC_CACHE_ALIGN_BUFFER(char, buf_ctrl, sizeof(struct nvme_id_ctrl));
|
|
struct nvme_id_ctrl *ctrl = (struct nvme_id_ctrl *)buf_ctrl;
|
|
|
|
- if (nvme_identify(dev, 0, 1, (dma_addr_t)(long)ctrl))
|
|
+ if (nvme_identify(dev, 0, 1, ctrl))
|
|
return -EIO;
|
|
|
|
print_optional_admin_cmd(le16_to_cpu(ctrl->oacs), ns->devnum);
|
|
print_optional_nvm_cmd(le16_to_cpu(ctrl->oncs), ns->devnum);
|
|
print_format_nvme_attributes(ctrl->fna, ns->devnum);
|
|
|
|
- if (nvme_identify(dev, ns->ns_id, 0, (dma_addr_t)(long)id))
|
|
+ if (nvme_identify(dev, ns->ns_id, 0, id))
|
|
return -EIO;
|
|
|
|
print_formats(id, ns);
|
|
diff --git a/include/nvme.h b/include/nvme.h
|
|
index 2cdf8ce320..8ff823cd81 100644
|
|
--- a/include/nvme.h
|
|
+++ b/include/nvme.h
|
|
@@ -18,12 +18,12 @@ struct nvme_dev;
|
|
* @dev: NVMe controller device
|
|
* @nsid: 0 for controller, namespace id for namespace to identify
|
|
* @cns: 1 for controller, 0 for namespace
|
|
- * @dma_addr: dma buffer address to store the identify result
|
|
+ * @buffer: dma buffer address to store the identify result
|
|
* @return: 0 on success, -ETIMEDOUT on command execution timeout,
|
|
* -EIO on command execution fails
|
|
*/
|
|
int nvme_identify(struct nvme_dev *dev, unsigned nsid,
|
|
- unsigned cns, dma_addr_t dma_addr);
|
|
+ unsigned int cns, void *buffer);
|
|
|
|
/**
|
|
* nvme_get_features - retrieve the attributes of the feature specified
|
|
@@ -33,13 +33,13 @@ int nvme_identify(struct nvme_dev *dev, unsigned nsid,
|
|
* @dev: NVMe controller device
|
|
* @fid: feature id to provide data
|
|
* @nsid: namespace id the command applies to
|
|
- * @dma_addr: data structure used as part of the specified feature
|
|
+ * @buffer: data structure used as part of the specified feature
|
|
* @result: command-specific result in the completion queue entry
|
|
* @return: 0 on success, -ETIMEDOUT on command execution timeout,
|
|
* -EIO on command execution fails
|
|
*/
|
|
int nvme_get_features(struct nvme_dev *dev, unsigned fid, unsigned nsid,
|
|
- dma_addr_t dma_addr, u32 *result);
|
|
+ void *buffer, u32 *result);
|
|
|
|
/**
|
|
* nvme_set_features - specify the attributes of the feature indicated
|
|
@@ -49,13 +49,13 @@ int nvme_get_features(struct nvme_dev *dev, unsigned fid, unsigned nsid,
|
|
* @dev: NVMe controller device
|
|
* @fid: feature id to provide data
|
|
* @dword11: command-specific input parameter
|
|
- * @dma_addr: data structure used as part of the specified feature
|
|
+ * @buffer: data structure used as part of the specified feature
|
|
* @result: command-specific result in the completion queue entry
|
|
* @return: 0 on success, -ETIMEDOUT on command execution timeout,
|
|
* -EIO on command execution fails
|
|
*/
|
|
int nvme_set_features(struct nvme_dev *dev, unsigned fid, unsigned dword11,
|
|
- dma_addr_t dma_addr, u32 *result);
|
|
+ void *buffer, u32 *result);
|
|
|
|
/**
|
|
* nvme_scan_namespace - scan all namespaces attached to NVMe controllers
|
|
--
|
|
2.33.0
|
|
|