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
+       select RESET_CONTROLLER
        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/reset-controller.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 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)
 {
@@ -1147,6 +1153,41 @@ static int ufs_qcom_setup_clocks(struct ufs_hba *hba, bool on,
        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];
 
@@ -1191,6 +1232,17 @@ static int ufs_qcom_init(struct ufs_hba *hba)
        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
index c114826316eb0165ec13a2ff7a4d935226577245..68a8801857529efe8b76536f4eb498c31e544ac8 100644 (file)
@@ -14,6 +14,8 @@
 #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
@@ -237,6 +239,8 @@ struct ufs_qcom_host {
        /* Bitmask for enabling debug prints */
        u32 dbg_print_en;
        struct ufs_qcom_testbus testbus;
+
+       struct reset_controller_dev rcdev;
 };
 
 static inline u32