forked from Minki/linux
[SCSI] ufs: configure the attribute for power mode
UIC attributes can be set with using DME_SET command for power mode change. For configuration the link capability attributes are used, which is updated after successful link startup. Signed-off-by: Seungwon Jeon <tgih.jun@samsung.com> Reviewed-by: Subhash Jadavani <subhashj@codeaurora.org> Signed-off-by: Santosh Y <santoshsy@gmail.com> Signed-off-by: James Bottomley <JBottomley@Parallels.com>
This commit is contained in:
parent
53b3d9c3fd
commit
d3e89bac71
@ -1531,6 +1531,70 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* ufshcd_config_max_pwr_mode - Set & Change power mode with
|
||||
* maximum capability attribute information.
|
||||
* @hba: per adapter instance
|
||||
*
|
||||
* Returns 0 on success, non-zero value on failure
|
||||
*/
|
||||
static int ufshcd_config_max_pwr_mode(struct ufs_hba *hba)
|
||||
{
|
||||
enum {RX = 0, TX = 1};
|
||||
u32 lanes[] = {1, 1};
|
||||
u32 gear[] = {1, 1};
|
||||
u8 pwr[] = {FASTAUTO_MODE, FASTAUTO_MODE};
|
||||
int ret;
|
||||
|
||||
/* Get the connected lane count */
|
||||
ufshcd_dme_get(hba, UIC_ARG_MIB(PA_CONNECTEDRXDATALANES), &lanes[RX]);
|
||||
ufshcd_dme_get(hba, UIC_ARG_MIB(PA_CONNECTEDTXDATALANES), &lanes[TX]);
|
||||
|
||||
/*
|
||||
* First, get the maximum gears of HS speed.
|
||||
* If a zero value, it means there is no HSGEAR capability.
|
||||
* Then, get the maximum gears of PWM speed.
|
||||
*/
|
||||
ufshcd_dme_get(hba, UIC_ARG_MIB(PA_MAXRXHSGEAR), &gear[RX]);
|
||||
if (!gear[RX]) {
|
||||
ufshcd_dme_get(hba, UIC_ARG_MIB(PA_MAXRXPWMGEAR), &gear[RX]);
|
||||
pwr[RX] = SLOWAUTO_MODE;
|
||||
}
|
||||
|
||||
ufshcd_dme_peer_get(hba, UIC_ARG_MIB(PA_MAXRXHSGEAR), &gear[TX]);
|
||||
if (!gear[TX]) {
|
||||
ufshcd_dme_peer_get(hba, UIC_ARG_MIB(PA_MAXRXPWMGEAR),
|
||||
&gear[TX]);
|
||||
pwr[TX] = SLOWAUTO_MODE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Configure attributes for power mode change with below.
|
||||
* - PA_RXGEAR, PA_ACTIVERXDATALANES, PA_RXTERMINATION,
|
||||
* - PA_TXGEAR, PA_ACTIVETXDATALANES, PA_TXTERMINATION,
|
||||
* - PA_HSSERIES
|
||||
*/
|
||||
ufshcd_dme_set(hba, UIC_ARG_MIB(PA_RXGEAR), gear[RX]);
|
||||
ufshcd_dme_set(hba, UIC_ARG_MIB(PA_ACTIVERXDATALANES), lanes[RX]);
|
||||
if (pwr[RX] == FASTAUTO_MODE)
|
||||
ufshcd_dme_set(hba, UIC_ARG_MIB(PA_RXTERMINATION), TRUE);
|
||||
|
||||
ufshcd_dme_set(hba, UIC_ARG_MIB(PA_TXGEAR), gear[TX]);
|
||||
ufshcd_dme_set(hba, UIC_ARG_MIB(PA_ACTIVETXDATALANES), lanes[TX]);
|
||||
if (pwr[TX] == FASTAUTO_MODE)
|
||||
ufshcd_dme_set(hba, UIC_ARG_MIB(PA_TXTERMINATION), TRUE);
|
||||
|
||||
if (pwr[RX] == FASTAUTO_MODE || pwr[TX] == FASTAUTO_MODE)
|
||||
ufshcd_dme_set(hba, UIC_ARG_MIB(PA_HSSERIES), PA_HS_MODE_B);
|
||||
|
||||
ret = ufshcd_uic_change_pwr_mode(hba, pwr[RX] << 4 | pwr[TX]);
|
||||
if (ret)
|
||||
dev_err(hba->dev,
|
||||
"pwr_mode: power mode change failed %d\n", ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* ufshcd_complete_dev_init() - checks device readiness
|
||||
* hba: per-adapter instance
|
||||
@ -2662,6 +2726,8 @@ static void ufshcd_async_scan(void *data, async_cookie_t cookie)
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
ufshcd_config_max_pwr_mode(hba);
|
||||
|
||||
ret = ufshcd_verify_dev_init(hba);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
@ -72,6 +72,21 @@
|
||||
#define PA_STALLNOCONFIGTIME 0x15A3
|
||||
#define PA_SAVECONFIGTIME 0x15A4
|
||||
|
||||
/* PA power modes */
|
||||
enum {
|
||||
FAST_MODE = 1,
|
||||
SLOW_MODE = 2,
|
||||
FASTAUTO_MODE = 4,
|
||||
SLOWAUTO_MODE = 5,
|
||||
UNCHANGED = 7,
|
||||
};
|
||||
|
||||
/* PA TX/RX Frequency Series */
|
||||
enum {
|
||||
PA_HS_MODE_A = 1,
|
||||
PA_HS_MODE_B = 2,
|
||||
};
|
||||
|
||||
/*
|
||||
* Data Link Layer Attributes
|
||||
*/
|
||||
@ -127,4 +142,10 @@
|
||||
#define T_TC0TXMAXSDUSIZE 0x4060
|
||||
#define T_TC1TXMAXSDUSIZE 0x4061
|
||||
|
||||
/* Boolean attribute values */
|
||||
enum {
|
||||
FALSE = 0,
|
||||
TRUE,
|
||||
};
|
||||
|
||||
#endif /* _UNIPRO_H_ */
|
||||
|
Loading…
Reference in New Issue
Block a user