scsi: ufs: Update L4 attributes on manual hibern8 exit in Cadence UFS.
Backup L4 attributes duirng manual hibern8 entry and restore the L4 attributes on manual hibern8 exit as per JESD220C. Link: https://lore.kernel.org/r/1575606303-10917-1-git-send-email-sheebab@cadence.com Reviewed-by: Alim Akhtar <alim.akhtar@samsung.com> Tested-by: Vignesh Raghavendra <vigneshr@ti.com> Signed-off-by: Sheeba B <sheebab@cadence.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
This commit is contained in:
parent
fc0a9de2f4
commit
e89fbc7feb
|
@ -19,6 +19,85 @@
|
||||||
|
|
||||||
#define CDNS_UFS_REG_HCLKDIV 0xFC
|
#define CDNS_UFS_REG_HCLKDIV 0xFC
|
||||||
#define CDNS_UFS_REG_PHY_XCFGD1 0x113C
|
#define CDNS_UFS_REG_PHY_XCFGD1 0x113C
|
||||||
|
#define CDNS_UFS_MAX_L4_ATTRS 12
|
||||||
|
|
||||||
|
struct cdns_ufs_host {
|
||||||
|
/**
|
||||||
|
* cdns_ufs_dme_attr_val - for storing L4 attributes
|
||||||
|
*/
|
||||||
|
u32 cdns_ufs_dme_attr_val[CDNS_UFS_MAX_L4_ATTRS];
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* cdns_ufs_get_l4_attr - get L4 attributes on local side
|
||||||
|
* @hba: per adapter instance
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
static void cdns_ufs_get_l4_attr(struct ufs_hba *hba)
|
||||||
|
{
|
||||||
|
struct cdns_ufs_host *host = ufshcd_get_variant(hba);
|
||||||
|
|
||||||
|
ufshcd_dme_get(hba, UIC_ARG_MIB(T_PEERDEVICEID),
|
||||||
|
&host->cdns_ufs_dme_attr_val[0]);
|
||||||
|
ufshcd_dme_get(hba, UIC_ARG_MIB(T_PEERCPORTID),
|
||||||
|
&host->cdns_ufs_dme_attr_val[1]);
|
||||||
|
ufshcd_dme_get(hba, UIC_ARG_MIB(T_TRAFFICCLASS),
|
||||||
|
&host->cdns_ufs_dme_attr_val[2]);
|
||||||
|
ufshcd_dme_get(hba, UIC_ARG_MIB(T_PROTOCOLID),
|
||||||
|
&host->cdns_ufs_dme_attr_val[3]);
|
||||||
|
ufshcd_dme_get(hba, UIC_ARG_MIB(T_CPORTFLAGS),
|
||||||
|
&host->cdns_ufs_dme_attr_val[4]);
|
||||||
|
ufshcd_dme_get(hba, UIC_ARG_MIB(T_TXTOKENVALUE),
|
||||||
|
&host->cdns_ufs_dme_attr_val[5]);
|
||||||
|
ufshcd_dme_get(hba, UIC_ARG_MIB(T_RXTOKENVALUE),
|
||||||
|
&host->cdns_ufs_dme_attr_val[6]);
|
||||||
|
ufshcd_dme_get(hba, UIC_ARG_MIB(T_LOCALBUFFERSPACE),
|
||||||
|
&host->cdns_ufs_dme_attr_val[7]);
|
||||||
|
ufshcd_dme_get(hba, UIC_ARG_MIB(T_PEERBUFFERSPACE),
|
||||||
|
&host->cdns_ufs_dme_attr_val[8]);
|
||||||
|
ufshcd_dme_get(hba, UIC_ARG_MIB(T_CREDITSTOSEND),
|
||||||
|
&host->cdns_ufs_dme_attr_val[9]);
|
||||||
|
ufshcd_dme_get(hba, UIC_ARG_MIB(T_CPORTMODE),
|
||||||
|
&host->cdns_ufs_dme_attr_val[10]);
|
||||||
|
ufshcd_dme_get(hba, UIC_ARG_MIB(T_CONNECTIONSTATE),
|
||||||
|
&host->cdns_ufs_dme_attr_val[11]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* cdns_ufs_set_l4_attr - set L4 attributes on local side
|
||||||
|
* @hba: per adapter instance
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
static void cdns_ufs_set_l4_attr(struct ufs_hba *hba)
|
||||||
|
{
|
||||||
|
struct cdns_ufs_host *host = ufshcd_get_variant(hba);
|
||||||
|
|
||||||
|
ufshcd_dme_set(hba, UIC_ARG_MIB(T_CONNECTIONSTATE), 0);
|
||||||
|
ufshcd_dme_set(hba, UIC_ARG_MIB(T_PEERDEVICEID),
|
||||||
|
host->cdns_ufs_dme_attr_val[0]);
|
||||||
|
ufshcd_dme_set(hba, UIC_ARG_MIB(T_PEERCPORTID),
|
||||||
|
host->cdns_ufs_dme_attr_val[1]);
|
||||||
|
ufshcd_dme_set(hba, UIC_ARG_MIB(T_TRAFFICCLASS),
|
||||||
|
host->cdns_ufs_dme_attr_val[2]);
|
||||||
|
ufshcd_dme_set(hba, UIC_ARG_MIB(T_PROTOCOLID),
|
||||||
|
host->cdns_ufs_dme_attr_val[3]);
|
||||||
|
ufshcd_dme_set(hba, UIC_ARG_MIB(T_CPORTFLAGS),
|
||||||
|
host->cdns_ufs_dme_attr_val[4]);
|
||||||
|
ufshcd_dme_set(hba, UIC_ARG_MIB(T_TXTOKENVALUE),
|
||||||
|
host->cdns_ufs_dme_attr_val[5]);
|
||||||
|
ufshcd_dme_set(hba, UIC_ARG_MIB(T_RXTOKENVALUE),
|
||||||
|
host->cdns_ufs_dme_attr_val[6]);
|
||||||
|
ufshcd_dme_set(hba, UIC_ARG_MIB(T_LOCALBUFFERSPACE),
|
||||||
|
host->cdns_ufs_dme_attr_val[7]);
|
||||||
|
ufshcd_dme_set(hba, UIC_ARG_MIB(T_PEERBUFFERSPACE),
|
||||||
|
host->cdns_ufs_dme_attr_val[8]);
|
||||||
|
ufshcd_dme_set(hba, UIC_ARG_MIB(T_CREDITSTOSEND),
|
||||||
|
host->cdns_ufs_dme_attr_val[9]);
|
||||||
|
ufshcd_dme_set(hba, UIC_ARG_MIB(T_CPORTMODE),
|
||||||
|
host->cdns_ufs_dme_attr_val[10]);
|
||||||
|
ufshcd_dme_set(hba, UIC_ARG_MIB(T_CONNECTIONSTATE),
|
||||||
|
host->cdns_ufs_dme_attr_val[11]);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets HCLKDIV register value based on the core_clk
|
* Sets HCLKDIV register value based on the core_clk
|
||||||
|
@ -77,6 +156,22 @@ static int cdns_ufs_hce_enable_notify(struct ufs_hba *hba,
|
||||||
return cdns_ufs_set_hclkdiv(hba);
|
return cdns_ufs_set_hclkdiv(hba);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called around hibern8 enter/exit.
|
||||||
|
* @hba: host controller instance
|
||||||
|
* @cmd: UIC Command
|
||||||
|
* @status: notify stage (pre, post change)
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
static void cdns_ufs_hibern8_notify(struct ufs_hba *hba, enum uic_cmd_dme cmd,
|
||||||
|
enum ufs_notify_change_status status)
|
||||||
|
{
|
||||||
|
if (status == PRE_CHANGE && cmd == UIC_CMD_DME_HIBER_ENTER)
|
||||||
|
cdns_ufs_get_l4_attr(hba);
|
||||||
|
if (status == POST_CHANGE && cmd == UIC_CMD_DME_HIBER_EXIT)
|
||||||
|
cdns_ufs_set_l4_attr(hba);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called before and after Link startup is carried out.
|
* Called before and after Link startup is carried out.
|
||||||
* @hba: host controller instance
|
* @hba: host controller instance
|
||||||
|
@ -117,6 +212,14 @@ static int cdns_ufs_link_startup_notify(struct ufs_hba *hba,
|
||||||
static int cdns_ufs_init(struct ufs_hba *hba)
|
static int cdns_ufs_init(struct ufs_hba *hba)
|
||||||
{
|
{
|
||||||
int status = 0;
|
int status = 0;
|
||||||
|
struct cdns_ufs_host *host;
|
||||||
|
struct device *dev = hba->dev;
|
||||||
|
|
||||||
|
host = devm_kzalloc(dev, sizeof(*host), GFP_KERNEL);
|
||||||
|
|
||||||
|
if (!host)
|
||||||
|
return -ENOMEM;
|
||||||
|
ufshcd_set_variant(hba, host);
|
||||||
|
|
||||||
if (hba->vops && hba->vops->phy_initialization)
|
if (hba->vops && hba->vops->phy_initialization)
|
||||||
status = hba->vops->phy_initialization(hba);
|
status = hba->vops->phy_initialization(hba);
|
||||||
|
@ -144,8 +247,10 @@ static int cdns_ufs_m31_16nm_phy_initialization(struct ufs_hba *hba)
|
||||||
|
|
||||||
static const struct ufs_hba_variant_ops cdns_ufs_pltfm_hba_vops = {
|
static const struct ufs_hba_variant_ops cdns_ufs_pltfm_hba_vops = {
|
||||||
.name = "cdns-ufs-pltfm",
|
.name = "cdns-ufs-pltfm",
|
||||||
|
.init = cdns_ufs_init,
|
||||||
.hce_enable_notify = cdns_ufs_hce_enable_notify,
|
.hce_enable_notify = cdns_ufs_hce_enable_notify,
|
||||||
.link_startup_notify = cdns_ufs_link_startup_notify,
|
.link_startup_notify = cdns_ufs_link_startup_notify,
|
||||||
|
.hibern8_notify = cdns_ufs_hibern8_notify,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct ufs_hba_variant_ops cdns_ufs_m31_16nm_pltfm_hba_vops = {
|
static const struct ufs_hba_variant_ops cdns_ufs_m31_16nm_pltfm_hba_vops = {
|
||||||
|
@ -154,6 +259,7 @@ static const struct ufs_hba_variant_ops cdns_ufs_m31_16nm_pltfm_hba_vops = {
|
||||||
.hce_enable_notify = cdns_ufs_hce_enable_notify,
|
.hce_enable_notify = cdns_ufs_hce_enable_notify,
|
||||||
.link_startup_notify = cdns_ufs_link_startup_notify,
|
.link_startup_notify = cdns_ufs_link_startup_notify,
|
||||||
.phy_initialization = cdns_ufs_m31_16nm_phy_initialization,
|
.phy_initialization = cdns_ufs_m31_16nm_phy_initialization,
|
||||||
|
.hibern8_notify = cdns_ufs_hibern8_notify,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct of_device_id cdns_ufs_of_match[] = {
|
static const struct of_device_id cdns_ufs_of_match[] = {
|
||||||
|
|
Loading…
Reference in New Issue