]> git.dujemihanovic.xyz Git - u-boot.git/commitdiff
ufs: Add missing memory barriers
authorBhupesh Sharma <bhupesh.linux@gmail.com>
Mon, 30 Sep 2024 12:44:32 +0000 (14:44 +0200)
committerNeil Armstrong <neil.armstrong@linaro.org>
Mon, 14 Oct 2024 06:55:28 +0000 (08:55 +0200)
Add missing wmb() and mb() barriers in the u-boot UFS core
framework driver to allow registers updates to happen before
follow-up read operations.

This makes the barrier placement similar to the Linux UFS driver,
synced from the Linux v6.9 release.

Starting from the v6.10 release, the barriers were replaced with a register
read-back in [1], this will ported to u-boot in a second time.

[1] https://lore.kernel.org/all/20240329-ufs-reset-ensure-effect-before-delay-v5-0-181252004586@redhat.com/

Signed-off-by: Bhupesh Sharma <bhupesh.sharma@linaro.org>
Tested-by: Venkatesh Yadav Abbarapu <venkatesh.abbarapu@amd.com>
Tested-by: Julius Lehmann <lehmanju@devpi.de>
Link: https://lore.kernel.org/r/20240930-topic-ufs-enhancements-v3-10-58234f84ab89@linaro.org
Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org>
drivers/ufs/ufs.c

index 565a6af1404897e1c4ec4474da8372e74b29b11c..5d4e5424358c8e384736537825e9599489d4928d 100644 (file)
@@ -432,6 +432,12 @@ static int ufshcd_make_hba_operational(struct ufs_hba *hba)
        ufshcd_writel(hba, upper_32_bits((dma_addr_t)hba->utmrdl),
                      REG_UTP_TASK_REQ_LIST_BASE_H);
 
+       /*
+        * Make sure base address and interrupt setup are updated before
+        * enabling the run/stop registers below.
+        */
+       wmb();
+
        /*
         * UCRDY, UTMRLDY and UTRLRDY bits must be 1
         */
@@ -861,6 +867,9 @@ static int ufshcd_send_command(struct ufs_hba *hba, unsigned int task_tag)
 
        ufshcd_writel(hba, 1 << task_tag, REG_UTP_TRANSFER_REQ_DOOR_BELL);
 
+       /* Make sure doorbell reg is updated before reading interrupt status */
+       wmb();
+
        start = get_timer(0);
        do {
                intr_status = ufshcd_readl(hba, REG_INTERRUPT_STATUS);
@@ -1994,6 +2003,8 @@ int ufshcd_probe(struct udevice *ufs_dev, struct ufs_hba_ops *hba_ops)
                      REG_INTERRUPT_STATUS);
        ufshcd_writel(hba, 0, REG_INTERRUPT_ENABLE);
 
+       mb();
+
        err = ufshcd_hba_enable(hba);
        if (err) {
                dev_err(hba->dev, "Host controller enable failed\n");