From b2d01681ab2d7dd1735fefaacf0cbcb7d4e4f32a Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Wed, 11 Oct 2023 21:15:44 +0800 Subject: [PATCH 1/9] ufs: Correct the UFS terminlogy UFS stands for Universal Flash Storage, not Subsytem. Signed-off-by: Bin Meng Reviewed-by: Simon Glass Reviewed-by: Neha Malcom Francis --- cmd/Kconfig | 2 +- drivers/ufs/ufs-uclass.c | 2 +- drivers/ufs/ufs.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/cmd/Kconfig b/cmd/Kconfig index 6470b138d2..a59c67e333 100644 --- a/cmd/Kconfig +++ b/cmd/Kconfig @@ -1536,7 +1536,7 @@ config CMD_TSI148 Turndra tsi148 device. See the command help for full details. config CMD_UFS - bool "Enable UFS - Universal Flash Subsystem commands" + bool "Enable UFS - Universal Flash Storage commands" depends on UFS help "This provides commands to initialise and configure universal flash diff --git a/drivers/ufs/ufs-uclass.c b/drivers/ufs/ufs-uclass.c index ceea30c4a9..ffae811d46 100644 --- a/drivers/ufs/ufs-uclass.c +++ b/drivers/ufs/ufs-uclass.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 /** - * ufs-uclass.c - Universal Flash Subsystem (UFS) Uclass driver + * ufs-uclass.c - Universal Flash Storage (UFS) Uclass driver * * Copyright (C) 2019 Texas Instruments Incorporated - http://www.ti.com */ diff --git a/drivers/ufs/ufs.c b/drivers/ufs/ufs.c index 7c48d57f99..f534d6e29f 100644 --- a/drivers/ufs/ufs.c +++ b/drivers/ufs/ufs.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0+ /** - * ufs.c - Universal Flash Subsystem (UFS) driver + * ufs.c - Universal Flash Storage (UFS) driver * * Taken from Linux Kernel v5.2 (drivers/scsi/ufs/ufshcd.c) and ported * to u-boot. From 1b3dab2d296c4ae8ccdd85986c26a77036c81d85 Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Wed, 11 Oct 2023 21:15:45 +0800 Subject: [PATCH 2/9] ufs: Add a line feed to the end of some dev_xxx() messages Add a line feed to improve readability of some dev_xxx() messages. Signed-off-by: Bin Meng Reviewed-by: Neha Malcom Francis Reviewed-by: Simon Glass --- drivers/ufs/ufs.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/ufs/ufs.c b/drivers/ufs/ufs.c index f534d6e29f..96801866d3 100644 --- a/drivers/ufs/ufs.c +++ b/drivers/ufs/ufs.c @@ -320,7 +320,7 @@ static int ufshcd_disable_tx_lcc(struct ufs_hba *hba, bool peer) UIC_ARG_MPHY_TX_GEN_SEL_INDEX(i)), 0); if (err) { - dev_err(hba->dev, "%s: TX LCC Disable failed, peer = %d, lane = %d, err = %d", + dev_err(hba->dev, "%s: TX LCC Disable failed, peer = %d, lane = %d, err = %d\n", __func__, peer, i, err); break; } @@ -441,7 +441,7 @@ static int ufshcd_make_hba_operational(struct ufs_hba *hba) ufshcd_enable_run_stop_reg(hba); } else { dev_err(hba->dev, - "Host controller not ready to process requests"); + "Host controller not ready to process requests\n"); err = -EIO; goto out; } @@ -930,7 +930,7 @@ static int ufshcd_copy_query_response(struct ufs_hba *hba) memcpy(hba->dev_cmd.query.descriptor, descp, resp_len); } else { dev_warn(hba->dev, - "%s: Response size is bigger than buffer", + "%s: Response size is bigger than buffer\n", __func__); return -EINVAL; } @@ -1179,11 +1179,11 @@ static int ufshcd_read_desc_length(struct ufs_hba *hba, enum desc_idn desc_id, &header_len); if (ret) { - dev_err(hba->dev, "%s: Failed to get descriptor header id %d", + dev_err(hba->dev, "%s: Failed to get descriptor header id %d\n", __func__, desc_id); return ret; } else if (desc_id != header[QUERY_DESC_DESC_TYPE_OFFSET]) { - dev_warn(hba->dev, "%s: descriptor header id %d and desc_id %d mismatch", + dev_warn(hba->dev, "%s: descriptor header id %d and desc_id %d mismatch\n", __func__, header[QUERY_DESC_DESC_TYPE_OFFSET], desc_id); ret = -EINVAL; @@ -1302,7 +1302,7 @@ int ufshcd_read_desc_param(struct ufs_hba *hba, enum desc_idn desc_id, /* Sanity checks */ if (ret || !buff_len) { - dev_err(hba->dev, "%s: Failed to get full descriptor length", + dev_err(hba->dev, "%s: Failed to get full descriptor length\n", __func__); return ret; } @@ -1323,14 +1323,14 @@ int ufshcd_read_desc_param(struct ufs_hba *hba, enum desc_idn desc_id, &buff_len); if (ret) { - dev_err(hba->dev, "%s: Failed reading descriptor. desc_id %d, desc_index %d, param_offset %d, ret %d", + dev_err(hba->dev, "%s: Failed reading descriptor. desc_id %d, desc_index %d, param_offset %d, ret %d\n", __func__, desc_id, desc_index, param_offset, ret); goto out; } /* Sanity check */ if (desc_buf[QUERY_DESC_DESC_TYPE_OFFSET] != desc_id) { - dev_err(hba->dev, "%s: invalid desc_id %d in descriptor header", + dev_err(hba->dev, "%s: invalid desc_id %d in descriptor header\n", __func__, desc_buf[QUERY_DESC_DESC_TYPE_OFFSET]); ret = -EINVAL; goto out; From ff039a8704e9c1e3d9cae535726686df78ef749e Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Wed, 11 Oct 2023 21:15:46 +0800 Subject: [PATCH 3/9] cmd: kconfig: Make ufs prompt look similar to other commands At present the 'ufs' command prompt does not look similar like other commands. Update it. Signed-off-by: Bin Meng Reviewed-by: Simon Glass Reviewed-by: Neha Malcom Francis --- cmd/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/Kconfig b/cmd/Kconfig index a59c67e333..0b4e76c262 100644 --- a/cmd/Kconfig +++ b/cmd/Kconfig @@ -1536,7 +1536,7 @@ config CMD_TSI148 Turndra tsi148 device. See the command help for full details. config CMD_UFS - bool "Enable UFS - Universal Flash Storage commands" + bool "ufs - Universal Flash Storage commands" depends on UFS help "This provides commands to initialise and configure universal flash From ba537e9b27acf0c4e6f9c474fe708f3997129936 Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Wed, 11 Oct 2023 21:15:47 +0800 Subject: [PATCH 4/9] cmd: ufs: Correct the help text Remove the additional space and use "sub-system" for consistency with other commands like "scsi" and "usb". Signed-off-by: Bin Meng Reviewed-by: Simon Glass Reviewed-by: Neha Malcom Francis --- cmd/ufs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/ufs.c b/cmd/ufs.c index 143e946370..2c8d88df18 100644 --- a/cmd/ufs.c +++ b/cmd/ufs.c @@ -32,6 +32,6 @@ static int do_ufs(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) } U_BOOT_CMD(ufs, 3, 1, do_ufs, - "UFS sub system", + "UFS sub-system", "init [dev] - init UFS subsystem\n" ); From 07a64f0a347a4befb01dbdf912f8451f30f71abc Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Wed, 11 Oct 2023 21:15:48 +0800 Subject: [PATCH 5/9] pci_ids: Add Red Hat vendor and device IDs Red Hat, Inc. donates a part of its device ID range [1] to QEMU, to be used for virtual devices. This commit adds several typical devices that are useful in U-Boot. [1] https://www.qemu.org/docs/master/specs/pci-ids.html Signed-off-by: Bin Meng Reviewed-by: Neha Malcom Francis Reviewed-by: Simon Glass --- include/pci_ids.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/include/pci_ids.h b/include/pci_ids.h index 88b0a64045..b63bf45168 100644 --- a/include/pci_ids.h +++ b/include/pci_ids.h @@ -1363,6 +1363,13 @@ #define PCI_DEVICE_ID_XILINX_HAMMERFALL_DSP 0x3fc5 #define PCI_DEVICE_ID_XILINX_HAMMERFALL_DSP_MADI 0x3fc6 +/* Per https://www.qemu.org/docs/master/specs/pci-ids.html */ +#define PCI_VENDOR_ID_REDHAT 0x1b36 +#define PCI_DEVICE_ID_REDHAT_SDHCI 0x0007 +#define PCI_DEVICE_ID_REDHAT_XHCI 0x000d +#define PCI_DEVICE_ID_REDHAT_NVME 0x0010 +#define PCI_DEVICE_ID_REDHAT_UFS 0x0013 + #define PCI_VENDOR_ID_INIT 0x1101 #define PCI_VENDOR_ID_CREATIVE 0x1102 /* duplicate: ECTIVA */ From e5c19ce47c7063553b26443560179307416e26f9 Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Wed, 11 Oct 2023 21:15:49 +0800 Subject: [PATCH 6/9] ufs: Allow mmio registers on the PCI bus Check if the UFS controller is on the PCI bus, and get its register base address accordingly. Signed-off-by: Bin Meng Reviewed-by: Simon Glass Reviewed-by: Neha Malcom Francis --- drivers/ufs/ufs.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/drivers/ufs/ufs.c b/drivers/ufs/ufs.c index 96801866d3..fb2a607ef1 100644 --- a/drivers/ufs/ufs.c +++ b/drivers/ufs/ufs.c @@ -1914,6 +1914,7 @@ int ufshcd_probe(struct udevice *ufs_dev, struct ufs_hba_ops *hba_ops) struct ufs_hba *hba = dev_get_uclass_priv(ufs_dev); struct scsi_plat *scsi_plat; struct udevice *scsi_dev; + void __iomem *mmio_base; int err; device_find_first_child(ufs_dev, &scsi_dev); @@ -1927,7 +1928,14 @@ int ufshcd_probe(struct udevice *ufs_dev, struct ufs_hba_ops *hba_ops) hba->dev = ufs_dev; hba->ops = hba_ops; - hba->mmio_base = dev_read_addr_ptr(ufs_dev); + + if (device_is_on_pci_bus(ufs_dev)) { + mmio_base = dm_pci_map_bar(ufs_dev, PCI_BASE_ADDRESS_0, 0, 0, + PCI_REGION_TYPE, PCI_REGION_MEM); + } else { + mmio_base = dev_read_addr_ptr(ufs_dev); + } + hba->mmio_base = mmio_base; /* Set descriptor lengths to specification defaults */ ufshcd_def_desc_sizes(hba); From 2ec7d657c03dd583b4638bff6352ac3b88742c09 Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Wed, 11 Oct 2023 21:15:50 +0800 Subject: [PATCH 7/9] ufs: Add a PCI based UFS controller driver This adds a simple PCI based UFS controller driver with a QEMU emulated UFS controller on the PCI bus. Requiring QEMU v8.2+. Signed-off-by: Bin Meng Reviewed-by: Neha Malcom Francis Reviewed-by: Simon Glass --- drivers/ufs/Kconfig | 11 +++++++++++ drivers/ufs/Makefile | 1 + drivers/ufs/ufs-pci.c | 45 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 57 insertions(+) create mode 100644 drivers/ufs/ufs-pci.c diff --git a/drivers/ufs/Kconfig b/drivers/ufs/Kconfig index 0e0cc58e3d..42797ce052 100644 --- a/drivers/ufs/Kconfig +++ b/drivers/ufs/Kconfig @@ -15,6 +15,17 @@ config CADENCE_UFS This selects the platform driver for the Cadence UFS host controller present on present TI's J721e devices. +config UFS_PCI + bool "PCI bus based UFS Controller support" + depends on PCI && UFS + help + This selects the PCI UFS Host Controller Interface. Select this if + you have UFS Host Controller with PCI Interface. + + If you have a controller with this interface, say Y here. + + If unsure, say N. + config TI_J721E_UFS bool "Glue Layer driver for UFS on TI J721E devices" help diff --git a/drivers/ufs/Makefile b/drivers/ufs/Makefile index 4f3344fd4e..13f1e689ef 100644 --- a/drivers/ufs/Makefile +++ b/drivers/ufs/Makefile @@ -6,4 +6,5 @@ obj-$(CONFIG_UFS) += ufs.o ufs-uclass.o obj-$(CONFIG_CADENCE_UFS) += cdns-platform.o obj-$(CONFIG_TI_J721E_UFS) += ti-j721e-ufs.o +obj-$(CONFIG_UFS_PCI) += ufs-pci.o obj-$(CONFIG_UFS_RENESAS) += ufs-renesas.o diff --git a/drivers/ufs/ufs-pci.c b/drivers/ufs/ufs-pci.c new file mode 100644 index 0000000000..ad41358727 --- /dev/null +++ b/drivers/ufs/ufs-pci.c @@ -0,0 +1,45 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2023 tinylab.org + * Author: Bin Meng + */ + +#include +#include +#include +#include +#include +#include +#include "ufs.h" + +static int ufs_pci_bind(struct udevice *dev) +{ + struct udevice *scsi_dev; + + return ufs_scsi_bind(dev, &scsi_dev); +} + +static int ufs_pci_probe(struct udevice *dev) +{ + int err; + + err = ufshcd_probe(dev, NULL); + if (err) + dev_err(dev, "%s failed (ret=%d)\n", __func__, err); + + return err; +} + +U_BOOT_DRIVER(ufs_pci) = { + .name = "ufs_pci", + .id = UCLASS_UFS, + .bind = ufs_pci_bind, + .probe = ufs_pci_probe, +}; + +static struct pci_device_id ufs_supported[] = { + { PCI_DEVICE(PCI_VENDOR_ID_REDHAT, PCI_DEVICE_ID_REDHAT_UFS) }, + {}, +}; + +U_BOOT_PCI_DEVICE(ufs_pci, ufs_supported); From 5b2d25a2e3c303515f6ce3b0ea7e984e1e6312da Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Wed, 11 Oct 2023 21:15:51 +0800 Subject: [PATCH 8/9] ufs: Handle UFS 3.1 controllers Extend the version check to handle UFS 3.1 controllers as well. Tested on QEMU emulated UFS 3.1 controller. Signed-off-by: Bin Meng Reviewed-by: Neha Malcom Francis Reviewed-by: Simon Glass --- drivers/ufs/ufs.c | 3 ++- drivers/ufs/ufs.h | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/ufs/ufs.c b/drivers/ufs/ufs.c index fb2a607ef1..6287ce91a3 100644 --- a/drivers/ufs/ufs.c +++ b/drivers/ufs/ufs.c @@ -1953,7 +1953,8 @@ int ufshcd_probe(struct udevice *ufs_dev, struct ufs_hba_ops *hba_ops) hba->version != UFSHCI_VERSION_11 && hba->version != UFSHCI_VERSION_20 && hba->version != UFSHCI_VERSION_21 && - hba->version != UFSHCI_VERSION_30) + hba->version != UFSHCI_VERSION_30 && + hba->version != UFSHCI_VERSION_31) dev_err(hba->dev, "invalid UFS version 0x%x\n", hba->version); diff --git a/drivers/ufs/ufs.h b/drivers/ufs/ufs.h index 9daaf03d22..816a5ce0ca 100644 --- a/drivers/ufs/ufs.h +++ b/drivers/ufs/ufs.h @@ -782,6 +782,7 @@ enum { UFSHCI_VERSION_20 = 0x00000200, /* 2.0 */ UFSHCI_VERSION_21 = 0x00000210, /* 2.1 */ UFSHCI_VERSION_30 = 0x00000300, /* 3.0 */ + UFSHCI_VERSION_31 = 0x00000310, /* 3.1 */ }; /* Interrupt disable masks */ From 3555c92583c2c778a7b252bc6951be49fc21d22c Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Wed, 11 Oct 2023 21:15:52 +0800 Subject: [PATCH 9/9] qemu: riscv: Enable UFS support This enables UFS support for QEMU RISC-V 'virt' machine. Signed-off-by: Bin Meng Reviewed-by: Neha Malcom Francis Reviewed-by: Simon Glass --- board/emulation/qemu-riscv/Kconfig | 2 ++ doc/board/emulation/qemu-riscv.rst | 8 +++++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/board/emulation/qemu-riscv/Kconfig b/board/emulation/qemu-riscv/Kconfig index d56b4b5bc1..f3ee1f6e90 100644 --- a/board/emulation/qemu-riscv/Kconfig +++ b/board/emulation/qemu-riscv/Kconfig @@ -82,5 +82,7 @@ config BOARD_SPECIFIC_OPTIONS # dummy imply USB_XHCI_PCI imply USB_KEYBOARD imply CMD_USB + imply UFS + imply UFS_PCI endif diff --git a/doc/board/emulation/qemu-riscv.rst b/doc/board/emulation/qemu-riscv.rst index 61137bcbf1..8a5eb1eda5 100644 --- a/doc/board/emulation/qemu-riscv.rst +++ b/doc/board/emulation/qemu-riscv.rst @@ -131,7 +131,13 @@ An attached disk can be emulated in RISC-V virt machine by adding:: -drive if=none,file=riscv64.img,format=raw,id=mydisk \ -device ide-hd,drive=mydisk,bus=ahci.0 -You will have to run 'scsi scan' to use it. +or alternatively attach an emulated UFS:: + + -device ufs,id=ufs0 \ + -drive if=none,file=test.img,format=raw,id=lun0 \ + -device ufs-lu,drive=lun0,bus=ufs0 + +You will have to run 'scsi scan' to use them. A video console can be emulated in RISC-V virt machine by removing "-nographic" and adding::