summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorTom Rini <[email protected]>2026-03-13 09:01:53 -0600
committerTom Rini <[email protected]>2026-03-13 10:52:03 -0600
commitdba21bf0b6ececa4bbc15ac93b3cdf4b09286ed7 (patch)
treedd57833421f4b24cdbee47249405df46d7a49e96 /drivers
parent2f52473884723751316388af30a95419905b1cd3 (diff)
parent67d8731d4aad25be00e27eeef3602c519619405e (diff)
Merge tag 'u-boot-ufs-20260313' of https://source.denx.de/u-boot/custodians/u-boot-ufs into next
- ufs_hba_ops callbacks cleanup - Rockchip UFS reset support - UFS support in SPL
Diffstat (limited to 'drivers')
-rw-r--r--drivers/Makefile1
-rw-r--r--drivers/scsi/Makefile3
-rw-r--r--drivers/ufs/Kconfig4
-rw-r--r--drivers/ufs/ufs-rockchip.c31
-rw-r--r--drivers/ufs/ufs-rockchip.h1
-rw-r--r--drivers/ufs/ufs-uclass.c36
-rw-r--r--drivers/ufs/ufs.h10
7 files changed, 69 insertions, 17 deletions
diff --git a/drivers/Makefile b/drivers/Makefile
index de993ae42ac..43d0ba33281 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -73,6 +73,7 @@ obj-$(CONFIG_SPL_USB_HOST) += usb/host/
obj-$(CONFIG_SPL_SATA) += ata/ scsi/
obj-$(CONFIG_SPL_LEGACY_BLOCK) += block/
obj-$(CONFIG_SPL_THERMAL) += thermal/
+obj-$(CONFIG_SPL_UFS_SUPPORT) += scsi/ ufs/
endif
endif
diff --git a/drivers/scsi/Makefile b/drivers/scsi/Makefile
index b76de1b22a8..c9af60d5d03 100644
--- a/drivers/scsi/Makefile
+++ b/drivers/scsi/Makefile
@@ -16,4 +16,7 @@ ifdef CONFIG_XPL_BUILD
ifdef CONFIG_SPL_SATA
obj-$(CONFIG_SCSI) += scsi.o scsi-uclass.o
endif
+ifdef CONFIG_SPL_UFS_SUPPORT
+obj-$(CONFIG_SCSI) += scsi.o scsi-uclass.o
+endif
endif
diff --git a/drivers/ufs/Kconfig b/drivers/ufs/Kconfig
index 6c75bb2a079..49472933de3 100644
--- a/drivers/ufs/Kconfig
+++ b/drivers/ufs/Kconfig
@@ -76,6 +76,10 @@ config UFS_RENESAS_GEN5
config UFS_ROCKCHIP
bool "Rockchip specific hooks to UFS controller platform driver"
depends on UFS
+ depends on DM_GPIO
+ depends on RESET_ROCKCHIP
+ depends on SPL_DM_GPIO || !SPL_UFS_SUPPORT
+ depends on SPL_RESET_ROCKCHIP || !SPL_UFS_SUPPORT
help
This selects the Rockchip specific additions to UFSHCD platform driver.
diff --git a/drivers/ufs/ufs-rockchip.c b/drivers/ufs/ufs-rockchip.c
index 643a6ffb9bc..a13236c7f76 100644
--- a/drivers/ufs/ufs-rockchip.c
+++ b/drivers/ufs/ufs-rockchip.c
@@ -5,6 +5,7 @@
* Copyright (C) 2025 Rockchip Electronics Co.Ltd.
*/
+#include <asm/gpio.h>
#include <asm/io.h>
#include <clk.h>
#include <dm.h>
@@ -29,12 +30,9 @@ static int ufs_rockchip_hce_enable_notify(struct ufs_hba *hba,
ufshcd_dme_reset(hba);
ufshcd_dme_enable(hba);
- if (hba->ops->phy_initialization) {
- err = hba->ops->phy_initialization(hba);
- if (err)
- dev_err(hba->dev,
- "Phy init failed (%d)\n", err);
- }
+ err = ufshcd_ops_phy_initialization(hba);
+ if (err)
+ dev_err(hba->dev, "Phy init failed (%d)\n", err);
return err;
}
@@ -152,11 +150,31 @@ static int ufs_rockchip_common_init(struct ufs_hba *hba)
return err;
}
+ err = gpio_request_by_name(dev, "reset-gpios", 0, &host->device_reset,
+ GPIOD_IS_OUT | GPIOD_ACTIVE_LOW);
+ if (err) {
+ dev_err(dev, "Cannot get reset GPIO\n");
+ return err;
+ }
+
host->hba = hba;
return 0;
}
+static int ufs_rockchip_device_reset(struct ufs_hba *hba)
+{
+ struct ufs_rockchip_host *host = dev_get_priv(hba->dev);
+
+ dm_gpio_set_value(&host->device_reset, true);
+ udelay(20);
+
+ dm_gpio_set_value(&host->device_reset, false);
+ udelay(20);
+
+ return 0;
+}
+
static int ufs_rockchip_rk3576_init(struct ufs_hba *hba)
{
int ret = 0;
@@ -174,6 +192,7 @@ static struct ufs_hba_ops ufs_hba_rk3576_vops = {
.init = ufs_rockchip_rk3576_init,
.phy_initialization = ufs_rockchip_rk3576_phy_init,
.hce_enable_notify = ufs_rockchip_hce_enable_notify,
+ .device_reset = ufs_rockchip_device_reset,
};
static const struct udevice_id ufs_rockchip_of_match[] = {
diff --git a/drivers/ufs/ufs-rockchip.h b/drivers/ufs/ufs-rockchip.h
index 3dcb80f5702..50c2539da78 100644
--- a/drivers/ufs/ufs-rockchip.h
+++ b/drivers/ufs/ufs-rockchip.h
@@ -72,6 +72,7 @@ struct ufs_rockchip_host {
void __iomem *ufs_sys_ctrl;
void __iomem *mphy_base;
struct reset_ctl_bulk rsts;
+ struct gpio_desc device_reset;
struct clk ref_out_clk;
uint64_t caps;
uint32_t phy_config_mode;
diff --git a/drivers/ufs/ufs-uclass.c b/drivers/ufs/ufs-uclass.c
index 7a80a9d5664..bb997aace8f 100644
--- a/drivers/ufs/ufs-uclass.c
+++ b/drivers/ufs/ufs-uclass.c
@@ -127,11 +127,6 @@ static void ufshcd_print_pwr_info(struct ufs_hba *hba)
hba->pwr_info.hs_rate);
}
-static void ufshcd_device_reset(struct ufs_hba *hba)
-{
- ufshcd_vops_device_reset(hba);
-}
-
/**
* ufshcd_ready_for_uic_cmd - Check if controller is ready
* to accept UIC commands
@@ -512,7 +507,9 @@ static int ufshcd_link_startup(struct ufs_hba *hba)
int retries = DME_LINKSTARTUP_RETRIES;
do {
- ufshcd_ops_link_startup_notify(hba, PRE_CHANGE);
+ ret = ufshcd_ops_link_startup_notify(hba, PRE_CHANGE);
+ if (ret)
+ goto out;
ret = ufshcd_dme_link_startup(hba);
@@ -598,12 +595,18 @@ static inline void ufshcd_hba_start(struct ufs_hba *hba)
static int ufshcd_hba_enable(struct ufs_hba *hba)
{
int retry;
+ int ret;
if (!ufshcd_is_hba_active(hba))
/* change controller state to "reset state" */
ufshcd_hba_stop(hba);
- ufshcd_ops_hce_enable_notify(hba, PRE_CHANGE);
+ ret = ufshcd_ops_hce_enable_notify(hba, PRE_CHANGE);
+ if (ret) {
+ dev_err(hba->dev, "Controller enable notify PRE_CHANGE failed: %i\n",
+ ret);
+ return ret;
+ }
/* start controller initialization sequence */
ufshcd_hba_start(hba);
@@ -635,7 +638,12 @@ static int ufshcd_hba_enable(struct ufs_hba *hba)
/* enable UIC related interrupts */
ufshcd_enable_intr(hba, UFSHCD_UIC_MASK);
- ufshcd_ops_hce_enable_notify(hba, POST_CHANGE);
+ ret = ufshcd_ops_hce_enable_notify(hba, POST_CHANGE);
+ if (ret) {
+ dev_err(hba->dev, "Controller enable notify POST_CHANGE failed: %i\n",
+ ret);
+ return ret;
+ }
return 0;
}
@@ -2184,7 +2192,11 @@ int ufshcd_probe(struct udevice *ufs_dev, struct ufs_hba_ops *hba_ops)
/* Set descriptor lengths to specification defaults */
ufshcd_def_desc_sizes(hba);
- ufshcd_ops_init(hba);
+ err = ufshcd_ops_init(hba);
+ if (err) {
+ dev_err(hba->dev, "Host controller init failed: %i\n", err);
+ return err;
+ }
/* Read capabilities registers */
hba->capabilities = ufshcd_readl(hba, REG_CONTROLLER_CAPABILITIES);
@@ -2228,7 +2240,11 @@ int ufshcd_probe(struct udevice *ufs_dev, struct ufs_hba_ops *hba_ops)
mb(); /* flush previous writes */
/* Reset the attached device */
- ufshcd_device_reset(hba);
+ err = ufshcd_vops_device_reset(hba);
+ if (err) {
+ dev_err(hba->dev, "Failed to reset attached device: %i\n", err);
+ return err;
+ }
err = ufshcd_hba_enable(hba);
if (err) {
diff --git a/drivers/ufs/ufs.h b/drivers/ufs/ufs.h
index bc839a43704..0f6c93fbce7 100644
--- a/drivers/ufs/ufs.h
+++ b/drivers/ufs/ufs.h
@@ -509,7 +509,7 @@ struct ufs_query {
};
/**
- * struct ufs_dev_cmd - all assosiated fields with device management commands
+ * struct ufs_dev_cmd - all associated fields with device management commands
* @type: device management command type - Query, NOP OUT
* @tag_wq: wait queue until free command slot is available
*/
@@ -756,6 +756,14 @@ static inline int ufshcd_ops_link_startup_notify(struct ufs_hba *hba,
return 0;
}
+static inline int ufshcd_ops_phy_initialization(struct ufs_hba *hba)
+{
+ if (hba->ops && hba->ops->phy_initialization)
+ return hba->ops->phy_initialization(hba);
+
+ return 0;
+}
+
static inline int ufshcd_vops_device_reset(struct ufs_hba *hba)
{
if (hba->ops && hba->ops->device_reset)