Commit 12fd5f25 authored by Evan Green's avatar Evan Green Committed by Kishon Vijay Abraham I

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: default avatarEvan Green <evgreen@chromium.org>
Reviewed-by: default avatarStephen Boyd <swboyd@chromium.org>
Signed-off-by: default avatarKishon Vijay Abraham I <kishon@ti.com>
parent 70b894de
...@@ -99,6 +99,7 @@ config SCSI_UFS_DWC_TC_PLATFORM ...@@ -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
......
...@@ -16,6 +16,7 @@ ...@@ -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); ...@@ -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, ...@@ -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) ...@@ -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
......
...@@ -14,6 +14,8 @@ ...@@ -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 { ...@@ -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
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment