]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
scsi: ufs: qcom: Expose the reset controller for PHY
authorEvan Green <evgreen@chromium.org>
Thu, 21 Mar 2019 17:17:58 +0000 (10:17 -0700)
committerKishon Vijay Abraham I <kishon@ti.com>
Wed, 17 Apr 2019 08:42:56 +0000 (14:12 +0530)
Expose a reset controller that the phy will later use to control its
own PHY reset in the UFS controller. This will enable the combining
of PHY init functionality into a single function.

Signed-off-by: Evan Green <evgreen@chromium.org>
Reviewed-by: Stephen Boyd <swboyd@chromium.org>
Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
drivers/scsi/ufs/Kconfig
drivers/scsi/ufs/ufs-qcom.c
drivers/scsi/ufs/ufs-qcom.h

index 6db37cf306b05f14827a6d1974af2844d022ec06..179bda37454423125db2e571436a239e6d865860 100644 (file)
@@ -99,6 +99,7 @@ config SCSI_UFS_DWC_TC_PLATFORM
 config SCSI_UFS_QCOM
        tristate "QCOM specific hooks to UFS controller platform driver"
        depends on SCSI_UFSHCD_PLATFORM && ARCH_QCOM
 config SCSI_UFS_QCOM
        tristate "QCOM specific hooks to UFS controller platform driver"
        depends on SCSI_UFSHCD_PLATFORM && ARCH_QCOM
+       select RESET_CONTROLLER
        help
          This selects the QCOM specific additions to UFSHCD platform driver.
          UFS host on QCOM needs some vendor specific configuration before
        help
          This selects the QCOM specific additions to UFSHCD platform driver.
          UFS host on QCOM needs some vendor specific configuration before
index 3aeadb14aae1eeee158d2d20857588a89d962b5b..ab05ef5cfdcd724169f1a7b7378c943813b3698e 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/of.h>
 #include <linux/platform_device.h>
 #include <linux/phy/phy.h>
 #include <linux/of.h>
 #include <linux/platform_device.h>
 #include <linux/phy/phy.h>
+#include <linux/reset-controller.h>
 
 #include "ufshcd.h"
 #include "ufshcd-pltfrm.h"
 
 #include "ufshcd.h"
 #include "ufshcd-pltfrm.h"
@@ -49,6 +50,11 @@ static void ufs_qcom_get_default_testbus_cfg(struct ufs_qcom_host *host);
 static int ufs_qcom_set_dme_vs_core_clk_ctrl_clear_div(struct ufs_hba *hba,
                                                       u32 clk_cycles);
 
 static int ufs_qcom_set_dme_vs_core_clk_ctrl_clear_div(struct ufs_hba *hba,
                                                       u32 clk_cycles);
 
+static struct ufs_qcom_host *rcdev_to_ufs_host(struct reset_controller_dev *rcd)
+{
+       return container_of(rcd, struct ufs_qcom_host, rcdev);
+}
+
 static void ufs_qcom_dump_regs_wrapper(struct ufs_hba *hba, int offset, int len,
                                       const char *prefix, void *priv)
 {
 static void ufs_qcom_dump_regs_wrapper(struct ufs_hba *hba, int offset, int len,
                                       const char *prefix, void *priv)
 {
@@ -1147,6 +1153,41 @@ static int ufs_qcom_setup_clocks(struct ufs_hba *hba, bool on,
        return err;
 }
 
        return err;
 }
 
+static int
+ufs_qcom_reset_assert(struct reset_controller_dev *rcdev, unsigned long id)
+{
+       struct ufs_qcom_host *host = rcdev_to_ufs_host(rcdev);
+
+       /* Currently this code only knows about a single reset. */
+       WARN_ON(id);
+       ufs_qcom_assert_reset(host->hba);
+       /* provide 1ms delay to let the reset pulse propagate. */
+       usleep_range(1000, 1100);
+       return 0;
+}
+
+static int
+ufs_qcom_reset_deassert(struct reset_controller_dev *rcdev, unsigned long id)
+{
+       struct ufs_qcom_host *host = rcdev_to_ufs_host(rcdev);
+
+       /* Currently this code only knows about a single reset. */
+       WARN_ON(id);
+       ufs_qcom_deassert_reset(host->hba);
+
+       /*
+        * after reset deassertion, phy will need all ref clocks,
+        * voltage, current to settle down before starting serdes.
+        */
+       usleep_range(1000, 1100);
+       return 0;
+}
+
+static const struct reset_control_ops ufs_qcom_reset_ops = {
+       .assert = ufs_qcom_reset_assert,
+       .deassert = ufs_qcom_reset_deassert,
+};
+
 #define        ANDROID_BOOT_DEV_MAX    30
 static char android_boot_dev[ANDROID_BOOT_DEV_MAX];
 
 #define        ANDROID_BOOT_DEV_MAX    30
 static char android_boot_dev[ANDROID_BOOT_DEV_MAX];
 
@@ -1191,6 +1232,17 @@ static int ufs_qcom_init(struct ufs_hba *hba)
        host->hba = hba;
        ufshcd_set_variant(hba, host);
 
        host->hba = hba;
        ufshcd_set_variant(hba, host);
 
+       /* Fire up the reset controller. Failure here is non-fatal. */
+       host->rcdev.of_node = dev->of_node;
+       host->rcdev.ops = &ufs_qcom_reset_ops;
+       host->rcdev.owner = dev->driver->owner;
+       host->rcdev.nr_resets = 1;
+       err = devm_reset_controller_register(dev, &host->rcdev);
+       if (err) {
+               dev_warn(dev, "Failed to register reset controller\n");
+               err = 0;
+       }
+
        /*
         * voting/devoting device ref_clk source is time consuming hence
         * skip devoting it during aggressive clock gating. This clock
        /*
         * voting/devoting device ref_clk source is time consuming hence
         * skip devoting it during aggressive clock gating. This clock
index c114826316eb0165ec13a2ff7a4d935226577245..68a8801857529efe8b76536f4eb498c31e544ac8 100644 (file)
@@ -14,6 +14,8 @@
 #ifndef UFS_QCOM_H_
 #define UFS_QCOM_H_
 
 #ifndef UFS_QCOM_H_
 #define UFS_QCOM_H_
 
+#include <linux/reset-controller.h>
+
 #define MAX_UFS_QCOM_HOSTS     1
 #define MAX_U32                 (~(u32)0)
 #define MPHY_TX_FSM_STATE       0x41
 #define MAX_UFS_QCOM_HOSTS     1
 #define MAX_U32                 (~(u32)0)
 #define MPHY_TX_FSM_STATE       0x41
@@ -237,6 +239,8 @@ struct ufs_qcom_host {
        /* Bitmask for enabling debug prints */
        u32 dbg_print_en;
        struct ufs_qcom_testbus testbus;
        /* Bitmask for enabling debug prints */
        u32 dbg_print_en;
        struct ufs_qcom_testbus testbus;
+
+       struct reset_controller_dev rcdev;
 };
 
 static inline u32
 };
 
 static inline u32