diff options
| author | Seungwon Jeon <tgih.jun@samsung.com> | 2013-08-31 12:10:24 -0400 |
|---|---|---|
| committer | James Bottomley <JBottomley@Parallels.com> | 2013-09-06 19:08:37 -0400 |
| commit | d3e89bac7155341d3cfe58e76842a2a9729e6e41 (patch) | |
| tree | d9b33ca91f15e2afd21c7017f856091536599d44 | |
| parent | 53b3d9c3fdda94d14392dd221c67e24700b1fed6 (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.c | 66 | ||||
| -rw-r--r-- | drivers/scsi/ufs/unipro.h | 21 |
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 | */ | ||
| 1541 | static 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 */ | ||
| 76 | enum { | ||
| 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 */ | ||
| 85 | enum { | ||
| 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 */ | ||
| 146 | enum { | ||
| 147 | FALSE = 0, | ||
| 148 | TRUE, | ||
| 149 | }; | ||
| 150 | |||
| 130 | #endif /* _UNIPRO_H_ */ | 151 | #endif /* _UNIPRO_H_ */ |
