aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSeungwon Jeon <tgih.jun@samsung.com>2013-08-31 12:10:24 -0400
committerJames Bottomley <JBottomley@Parallels.com>2013-09-06 19:08:37 -0400
commitd3e89bac7155341d3cfe58e76842a2a9729e6e41 (patch)
treed9b33ca91f15e2afd21c7017f856091536599d44
parent53b3d9c3fdda94d14392dd221c67e24700b1fed6 (diff)
[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>
-rw-r--r--drivers/scsi/ufs/ufshcd.c66
-rw-r--r--drivers/scsi/ufs/unipro.h21
2 files changed, 87 insertions, 0 deletions
diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index 1788d9cc571b..04884d663e4e 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -1532,6 +1532,70 @@ out:
1532} 1532}
1533 1533
1534/** 1534/**
1535 * ufshcd_config_max_pwr_mode - Set & Change power mode with
1536 * maximum capability attribute information.
1537 * @hba: per adapter instance
1538 *
1539 * Returns 0 on success, non-zero value on failure
1540 */
1541static int ufshcd_config_max_pwr_mode(struct ufs_hba *hba)
1542{
1543 enum {RX = 0, TX = 1};
1544 u32 lanes[] = {1, 1};
1545 u32 gear[] = {1, 1};
1546 u8 pwr[] = {FASTAUTO_MODE, FASTAUTO_MODE};
1547 int ret;
1548
1549 /* Get the connected lane count */
1550 ufshcd_dme_get(hba, UIC_ARG_MIB(PA_CONNECTEDRXDATALANES), &lanes[RX]);
1551 ufshcd_dme_get(hba, UIC_ARG_MIB(PA_CONNECTEDTXDATALANES), &lanes[TX]);
1552
1553 /*
1554 * First, get the maximum gears of HS speed.
1555 * If a zero value, it means there is no HSGEAR capability.
1556 * Then, get the maximum gears of PWM speed.
1557 */
1558 ufshcd_dme_get(hba, UIC_ARG_MIB(PA_MAXRXHSGEAR), &gear[RX]);
1559 if (!gear[RX]) {
1560 ufshcd_dme_get(hba, UIC_ARG_MIB(PA_MAXRXPWMGEAR), &gear[RX]);
1561 pwr[RX] = SLOWAUTO_MODE;
1562 }
1563
1564 ufshcd_dme_peer_get(hba, UIC_ARG_MIB(PA_MAXRXHSGEAR), &gear[TX]);
1565 if (!gear[TX]) {
1566 ufshcd_dme_peer_get(hba, UIC_ARG_MIB(PA_MAXRXPWMGEAR),
1567 &gear[TX]);
1568 pwr[TX] = SLOWAUTO_MODE;
1569 }
1570
1571 /*
1572 * Configure attributes for power mode change with below.
1573 * - PA_RXGEAR, PA_ACTIVERXDATALANES, PA_RXTERMINATION,
1574 * - PA_TXGEAR, PA_ACTIVETXDATALANES, PA_TXTERMINATION,
1575 * - PA_HSSERIES
1576 */
1577 ufshcd_dme_set(hba, UIC_ARG_MIB(PA_RXGEAR), gear[RX]);
1578 ufshcd_dme_set(hba, UIC_ARG_MIB(PA_ACTIVERXDATALANES), lanes[RX]);
1579 if (pwr[RX] == FASTAUTO_MODE)
1580 ufshcd_dme_set(hba, UIC_ARG_MIB(PA_RXTERMINATION), TRUE);
1581
1582 ufshcd_dme_set(hba, UIC_ARG_MIB(PA_TXGEAR), gear[TX]);
1583 ufshcd_dme_set(hba, UIC_ARG_MIB(PA_ACTIVETXDATALANES), lanes[TX]);
1584 if (pwr[TX] == FASTAUTO_MODE)
1585 ufshcd_dme_set(hba, UIC_ARG_MIB(PA_TXTERMINATION), TRUE);
1586
1587 if (pwr[RX] == FASTAUTO_MODE || pwr[TX] == FASTAUTO_MODE)
1588 ufshcd_dme_set(hba, UIC_ARG_MIB(PA_HSSERIES), PA_HS_MODE_B);
1589
1590 ret = ufshcd_uic_change_pwr_mode(hba, pwr[RX] << 4 | pwr[TX]);
1591 if (ret)
1592 dev_err(hba->dev,
1593 "pwr_mode: power mode change failed %d\n", ret);
1594
1595 return ret;
1596}
1597
1598/**
1535 * ufshcd_complete_dev_init() - checks device readiness 1599 * ufshcd_complete_dev_init() - checks device readiness
1536 * hba: per-adapter instance 1600 * hba: per-adapter instance
1537 * 1601 *
@@ -2662,6 +2726,8 @@ static void ufshcd_async_scan(void *data, async_cookie_t cookie)
2662 if (ret) 2726 if (ret)
2663 goto out; 2727 goto out;
2664 2728
2729 ufshcd_config_max_pwr_mode(hba);
2730
2665 ret = ufshcd_verify_dev_init(hba); 2731 ret = ufshcd_verify_dev_init(hba);
2666 if (ret) 2732 if (ret)
2667 goto out; 2733 goto out;
diff --git a/drivers/scsi/ufs/unipro.h b/drivers/scsi/ufs/unipro.h
index 3a710eb3ec20..0bb8041c047a 100644
--- a/drivers/scsi/ufs/unipro.h
+++ b/drivers/scsi/ufs/unipro.h
@@ -72,6 +72,21 @@
72#define PA_STALLNOCONFIGTIME 0x15A3 72#define PA_STALLNOCONFIGTIME 0x15A3
73#define PA_SAVECONFIGTIME 0x15A4 73#define PA_SAVECONFIGTIME 0x15A4
74 74
75/* PA power modes */
76enum {
77 FAST_MODE = 1,
78 SLOW_MODE = 2,
79 FASTAUTO_MODE = 4,
80 SLOWAUTO_MODE = 5,
81 UNCHANGED = 7,
82};
83
84/* PA TX/RX Frequency Series */
85enum {
86 PA_HS_MODE_A = 1,
87 PA_HS_MODE_B = 2,
88};
89
75/* 90/*
76 * Data Link Layer Attributes 91 * Data Link Layer Attributes
77 */ 92 */
@@ -127,4 +142,10 @@
127#define T_TC0TXMAXSDUSIZE 0x4060 142#define T_TC0TXMAXSDUSIZE 0x4060
128#define T_TC1TXMAXSDUSIZE 0x4061 143#define T_TC1TXMAXSDUSIZE 0x4061
129 144
145/* Boolean attribute values */
146enum {
147 FALSE = 0,
148 TRUE,
149};
150
130#endif /* _UNIPRO_H_ */ 151#endif /* _UNIPRO_H_ */