scsi: ufs: qcom: Expose the reset controller for PHY

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>
This commit is contained in:
Evan Green 2019-03-21 10:17:58 -07:00 committed by Kishon Vijay Abraham I
parent 70b894deb7
commit 12fd5f250d
3 changed files with 57 additions and 0 deletions

View File

@ -99,6 +99,7 @@ config SCSI_UFS_DWC_TC_PLATFORM
config SCSI_UFS_QCOM config SCSI_UFS_QCOM
tristate "QCOM specific hooks to UFS controller platform driver" tristate "QCOM specific hooks to UFS controller platform driver"
depends on SCSI_UFSHCD_PLATFORM && ARCH_QCOM depends on SCSI_UFSHCD_PLATFORM && ARCH_QCOM
select RESET_CONTROLLER
help help
This selects the QCOM specific additions to UFSHCD platform driver. This selects the QCOM specific additions to UFSHCD platform driver.
UFS host on QCOM needs some vendor specific configuration before UFS host on QCOM needs some vendor specific configuration before

View File

@ -16,6 +16,7 @@
#include <linux/of.h> #include <linux/of.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/phy/phy.h> #include <linux/phy/phy.h>
#include <linux/reset-controller.h>
#include "ufshcd.h" #include "ufshcd.h"
#include "ufshcd-pltfrm.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, static int ufs_qcom_set_dme_vs_core_clk_ctrl_clear_div(struct ufs_hba *hba,
u32 clk_cycles); 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, static void ufs_qcom_dump_regs_wrapper(struct ufs_hba *hba, int offset, int len,
const char *prefix, void *priv) 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 #define ANDROID_BOOT_DEV_MAX 30
static char android_boot_dev[ANDROID_BOOT_DEV_MAX]; 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; host->hba = hba;
ufshcd_set_variant(hba, host); 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 * voting/devoting device ref_clk source is time consuming hence
* skip devoting it during aggressive clock gating. This clock * skip devoting it during aggressive clock gating. This clock

View File

@ -14,6 +14,8 @@
#ifndef UFS_QCOM_H_ #ifndef UFS_QCOM_H_
#define UFS_QCOM_H_ #define UFS_QCOM_H_
#include <linux/reset-controller.h>
#define MAX_UFS_QCOM_HOSTS 1 #define MAX_UFS_QCOM_HOSTS 1
#define MAX_U32 (~(u32)0) #define MAX_U32 (~(u32)0)
#define MPHY_TX_FSM_STATE 0x41 #define MPHY_TX_FSM_STATE 0x41
@ -237,6 +239,8 @@ struct ufs_qcom_host {
/* Bitmask for enabling debug prints */ /* Bitmask for enabling debug prints */
u32 dbg_print_en; u32 dbg_print_en;
struct ufs_qcom_testbus testbus; struct ufs_qcom_testbus testbus;
struct reset_controller_dev rcdev;
}; };
static inline u32 static inline u32